/*
 *  ReactOS Task Manager
 *
 *  graph.c
 *
 *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
 *  Copyright (C) 2008  Vladimir Pankratov
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>
#include <commctrl.h>
#include <winnt.h>

#include "wine/unicode.h"
#include "taskmgr.h"
#include "perfdata.h"

#define BRIGHT_GREEN	RGB(0, 255, 0)
#define DARK_GREEN	RGB(0, 130, 0)
#define RED		RGB(255, 0, 0)


WNDPROC             OldGraphWndProc;

static void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
{
    RECT            rcClient;
    RECT            rcBarLeft;
    RECT            rcBarRight;
    WCHAR            Text[256];
    ULONG            CpuUsage;
    ULONG            CpuKernelUsage;
    int                nBars;
    int                nBarsUsed; 
/* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
    int                nBarsUsedKernel; 
/* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
    int                nBarsFree; 
/* Top bars that are "unused", i.e. are dark green, representing free cpu time */
    int                i;

    static const WCHAR    wszFormatI[] = {'%','d','%','%',0};
    static const WCHAR    wszFormatII[] = {' ',' ','%','d','%','%',0};
    static const WCHAR    wszFormatIII[] = {' ','%','d','%','%',0};
    
    /*
     * Get the client area rectangle
     */
    GetClientRect(hWnd, &rcClient);
    
    /*
     * Fill it with blackness
     */
    FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
    
    /*
     * Get the CPU usage
     */
    CpuUsage = PerfDataGetProcessorUsage();
    CpuKernelUsage = PerfDataGetProcessorSystemUsage();

    /*
     * Check and see how many digits it will take
     * so we get the indentation right every time.
     */
    if (CpuUsage == 100)
    {
        sprintfW(Text, wszFormatI, (int)CpuUsage);
    }
    else if (CpuUsage < 10)
    {
        sprintfW(Text, wszFormatII, (int)CpuUsage);
    }
    else
    {
        sprintfW(Text, wszFormatIII, (int)CpuUsage);
    }
    
    /*
     * Draw the font text onto the graph
     * The bottom 20 pixels are reserved for the text
     */
    Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5);

    /*
     * Now we have to draw the graph
     * So first find out how many bars we can fit
     */
    nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
    nBarsUsed = (nBars * CpuUsage) / 100;
    if ((CpuUsage) && (nBarsUsed == 0))
    {
        nBarsUsed = 1;
    }
    nBarsFree = nBars - nBarsUsed;
    if (TaskManagerSettings.ShowKernelTimes)
    {
        nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
        nBarsUsed -= (nBarsUsedKernel / 2);
    }
    else
    {
        nBarsUsedKernel = 0;
    }

    /*
     * Now draw the bar graph
     */
    rcBarLeft.left =  ((rcClient.right - rcClient.left) - 33) / 2;
    rcBarLeft.right =  rcBarLeft.left + 16;
    rcBarRight.left = rcBarLeft.left + 17;
    rcBarRight.right = rcBarLeft.right + 17;
    rcBarLeft.top = rcBarRight.top = 5;
    rcBarLeft.bottom = rcBarRight.bottom = 7;

    if (nBarsUsed < 0)     nBarsUsed = 0;
    if (nBarsUsed > nBars) nBarsUsed = nBars;

    if (nBarsFree < 0)     nBarsFree = 0;
    if (nBarsFree > nBars) nBarsFree = nBars;

    if (nBarsUsedKernel < 0)     nBarsUsedKernel = 0;
    if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;

    /*
     * Draw the "free" bars
     */
    for (i=0; i<nBarsFree; i++)
    {
        FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
        FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
        
        rcBarLeft.top += 3;
        rcBarLeft.bottom += 3;
        
        rcBarRight.top += 3;
        rcBarRight.bottom += 3;
    }
    
    /*
     * Draw the "used" bars
     */
    for (i=0; i<nBarsUsed; i++)
    {
        if (nBarsUsed > 5000) nBarsUsed = 5000;

        FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
        FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
        
        rcBarLeft.top += 3;
        rcBarLeft.bottom += 3;
        
        rcBarRight.top += 3;
        rcBarRight.bottom += 3;
    }
    
    /*
     * Draw the "used" kernel bars
     */
    rcBarLeft.bottom--;
    rcBarRight.bottom--;
    if (nBarsUsedKernel && nBarsUsedKernel % 2)
    {
        rcBarLeft.top -= 2;
        rcBarLeft.bottom -= 2;
        
        rcBarRight.top -= 2;
        rcBarRight.bottom -= 2;

        FillSolidRect(hDC, &rcBarLeft, RED);
        FillSolidRect(hDC, &rcBarRight, RED);
        
        rcBarLeft.top += 2;
        rcBarLeft.bottom += 2;
        
        rcBarRight.top += 2;
        rcBarRight.bottom += 2;

        nBarsUsedKernel--;
    }
    for (i=0; i<nBarsUsedKernel; i++)
    {
        if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;

        FillSolidRect(hDC, &rcBarLeft, RED);
        FillSolidRect(hDC, &rcBarRight, RED);
        
        rcBarLeft.top++;
        rcBarLeft.bottom++;
        
        rcBarRight.top++;
        rcBarRight.bottom++;

        if (i % 2)
        {
            rcBarLeft.top++;
            rcBarLeft.bottom++;
            
            rcBarRight.top++;
            rcBarRight.bottom++;
        }
    }
}

static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
{
    RECT            rcClient;
    RECT            rcBarLeft;
    RECT            rcBarRight;
    WCHAR            Text[256];
    ULONGLONG        CommitChargeTotal;
    ULONGLONG        CommitChargeLimit;
    int                nBars;
    int                nBarsUsed = 0; 
/* Bottom bars that are "used", i.e. are bright green, representing used memory */
    int                nBarsFree; 
/* Top bars that are "unused", i.e. are dark green, representing free memory */
    int                i;

    static const WCHAR    wszFormat[] = {'%','d','K',0};
    
    /*
     * Get the client area rectangle
     */
    GetClientRect(hWnd, &rcClient);
    
    /*
     * Fill it with blackness
     */
    FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
    
    /*
     * Get the memory usage
     */
    CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
    CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();

    sprintfW(Text, wszFormat, (int)CommitChargeTotal);
    
    /*
     * Draw the font text onto the graph
     * The bottom 20 pixels are reserved for the text
     */
    Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (strlenW(Text) * 8)) / 2, rcClient.bottom - 11 - 5);

    /*
     * Now we have to draw the graph
     * So first find out how many bars we can fit
     */
    nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
    if (CommitChargeLimit)
        nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
    nBarsFree = nBars - nBarsUsed;

    if (nBarsUsed < 0)     nBarsUsed = 0;
    if (nBarsUsed > nBars) nBarsUsed = nBars;

    if (nBarsFree < 0)     nBarsFree = 0;
    if (nBarsFree > nBars) nBarsFree = nBars;

    /*
     * Now draw the bar graph
     */
    rcBarLeft.left =  ((rcClient.right - rcClient.left) - 33) / 2;
    rcBarLeft.right =  rcBarLeft.left + 16;
    rcBarRight.left = rcBarLeft.left + 17;
    rcBarRight.right = rcBarLeft.right + 17;
    rcBarLeft.top = rcBarRight.top = 5;
    rcBarLeft.bottom = rcBarRight.bottom = 7;
    
    /*
     * Draw the "free" bars
     */
    for (i=0; i<nBarsFree; i++)
    {
        FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
        FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
        
        rcBarLeft.top += 3;
        rcBarLeft.bottom += 3;
        
        rcBarRight.top += 3;
        rcBarRight.bottom += 3;
    }
    
    /*
     * Draw the "used" bars
     */
    for (i=0; i<nBarsUsed; i++)
    {
        FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
        FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
        
        rcBarLeft.top += 3;
        rcBarLeft.bottom += 3;
        
        rcBarRight.top += 3;
        rcBarRight.bottom += 3;
    }
}

static void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
{
    RECT            rcClient;
    int                i;
    static int        offset = 0;
    
    if (offset++ >= 10)
        offset = 0;
    
    /*
     * Get the client area rectangle
     */
    GetClientRect(hWnd, &rcClient);
    
    /*
     * Fill it with blackness
     */
    FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));

    /*
     * Draw the graph background
     *
     * Draw the horizontal bars
     */
    for (i=0; i<rcClient.bottom; i++)
    {
        if ((i % 11) == 0)
        {
            /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN);  */
        }
    }
    /*
     * Draw the vertical bars
     */
    for (i=11; i<rcClient.right + offset; i++)
    {
        if ((i % 11) == 0)
        {
            /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN);  */
        }
    }

    /*
     * Draw the memory usage
     */
    for (i=rcClient.right; i>=0; i--)
    {
    }
}

INT_PTR CALLBACK
Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC                hdc;
    PAINTSTRUCT        ps;
    LONG            WindowId;
    
    switch (message)
    {
    case WM_ERASEBKGND:
        return TRUE;

    /*
     * Filter out mouse  & keyboard messages
     */
    /* case WM_APPCOMMAND: */
    case WM_CAPTURECHANGED:
    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_MOUSEACTIVATE:
    case WM_MOUSEHOVER:
    case WM_MOUSELEAVE:
    case WM_MOUSEMOVE:
    /* case WM_MOUSEWHEEL: */
    case WM_NCHITTEST:
    case WM_NCLBUTTONDBLCLK:
    case WM_NCLBUTTONDOWN:
    case WM_NCLBUTTONUP:
    case WM_NCMBUTTONDBLCLK:
    case WM_NCMBUTTONDOWN:
    case WM_NCMBUTTONUP:
    /* case WM_NCMOUSEHOVER: */
    /* case WM_NCMOUSELEAVE: */
    case WM_NCMOUSEMOVE:
    case WM_NCRBUTTONDBLCLK:
    case WM_NCRBUTTONDOWN:
    case WM_NCRBUTTONUP:
    /* case WM_NCXBUTTONDBLCLK: */
    /* case WM_NCXBUTTONDOWN: */
    /* case WM_NCXBUTTONUP: */
    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    /* case WM_XBUTTONDBLCLK: */
    /* case WM_XBUTTONDOWN: */
    /* case WM_XBUTTONUP: */
    case WM_ACTIVATE:
    case WM_CHAR:
    case WM_DEADCHAR:
    case WM_GETHOTKEY:
    case WM_HOTKEY:
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_KILLFOCUS:
    case WM_SETFOCUS:
    case WM_SETHOTKEY:
    case WM_SYSCHAR:
    case WM_SYSDEADCHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
            
    case WM_NCCALCSIZE:
        return 0;

    case WM_PAINT:
        
        hdc = BeginPaint(hWnd, &ps);

        WindowId = GetWindowLongPtrW(hWnd, GWLP_ID);

        switch (WindowId)
        {
        case IDC_CPU_USAGE_GRAPH:
            Graph_DrawCpuUsageGraph(hdc, hWnd);
            break;
        case IDC_MEM_USAGE_GRAPH:
            Graph_DrawMemUsageGraph(hdc, hWnd);
            break;
        case IDC_MEM_USAGE_HISTORY_GRAPH:
            Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
            break;
        }
        
        EndPaint(hWnd, &ps);
        
        return 0;
        
    }

    /*
     * We pass on all non-handled messages
     */
    return CallWindowProcW(OldGraphWndProc, hWnd, message, wParam, lParam);
}
