/*
 * sizetip.c - resize tips for PuTTY(tel) terminal window.
 */

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

#include "putty.h"

static ATOM tip_class = 0;

static HFONT tip_font;
static COLORREF tip_bg;
static COLORREF tip_text;

static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
                                       WPARAM wParam, LPARAM lParam)
{

    switch (nMsg) {
      case WM_ERASEBKGND:
        return true;

      case WM_PAINT:
        {
            HBRUSH hbr;
            HGDIOBJ holdbr;
            RECT cr;
            int wtlen;
            LPTSTR wt;
            HDC hdc;

            PAINTSTRUCT ps;
            hdc = BeginPaint(hWnd, &ps);

            SelectObject(hdc, tip_font);
            SelectObject(hdc, GetStockObject(BLACK_PEN));

            hbr = CreateSolidBrush(tip_bg);
            holdbr = SelectObject(hdc, hbr);

            GetClientRect(hWnd, &cr);
            Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);

            wtlen = GetWindowTextLength(hWnd);
            wt = (LPTSTR) snewn(wtlen + 1, TCHAR);
            GetWindowText(hWnd, wt, wtlen + 1);

            SetTextColor(hdc, tip_text);
            SetBkColor(hdc, tip_bg);

            TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);

            sfree(wt);

            SelectObject(hdc, holdbr);
            DeleteObject(hbr);

            EndPaint(hWnd, &ps);
        }
        return 0;

      case WM_NCHITTEST:
        return HTTRANSPARENT;

      case WM_DESTROY:
        DeleteObject(tip_font);
        tip_font = NULL;
        break;

      case WM_SETTEXT:
        {
            LPCTSTR str = (LPCTSTR) lParam;
            SIZE sz;
            HDC hdc = CreateCompatibleDC(NULL);

            SelectObject(hdc, tip_font);
            GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);

            SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
                         SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
            InvalidateRect(hWnd, NULL, false);

            DeleteDC(hdc);
        }
        break;
    }

    return DefWindowProc(hWnd, nMsg, wParam, lParam);
}

static HWND tip_wnd = NULL;
static bool tip_enabled = false;

void UpdateSizeTip(HWND src, int cx, int cy)
{
    TCHAR str[32];

    if (!tip_enabled)
        return;

    if (!tip_wnd) {
        NONCLIENTMETRICS nci;

        /* First make sure the window class is registered */

        if (!tip_class) {
            WNDCLASS wc;
            wc.style = CS_HREDRAW | CS_VREDRAW;
            wc.lpfnWndProc = SizeTipWndProc;
            wc.cbClsExtra = 0;
            wc.cbWndExtra = 0;
            wc.hInstance = hinst;
            wc.hIcon = NULL;
            wc.hCursor = NULL;
            wc.hbrBackground = NULL;
            wc.lpszMenuName = NULL;
            wc.lpszClassName = "SizeTipClass";

            tip_class = RegisterClass(&wc);
        }
#if 0
        /* Default values based on Windows Standard color scheme */

        tip_font = GetStockObject(SYSTEM_FONT);
        tip_bg = RGB(255, 255, 225);
        tip_text = RGB(0, 0, 0);
#endif

        /* Prepare other GDI objects and drawing info */

        tip_bg = GetSysColor(COLOR_INFOBK);
        tip_text = GetSysColor(COLOR_INFOTEXT);

        memset(&nci, 0, sizeof(NONCLIENTMETRICS));
        nci.cbSize = sizeof(NONCLIENTMETRICS);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
                             sizeof(NONCLIENTMETRICS), &nci, 0);
        tip_font = CreateFontIndirect(&nci.lfStatusFont);
    }

    /* Generate the tip text */

    sprintf(str, "%dx%d", cx, cy);

    if (!tip_wnd) {
        HDC hdc;
        SIZE sz;
        RECT wr;
        int ix, iy;

        /* calculate the tip's size */

        hdc = CreateCompatibleDC(NULL);
        GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
        DeleteDC(hdc);

        GetWindowRect(src, &wr);

        ix = wr.left;
        if (ix < 16)
            ix = 16;

        iy = wr.top - sz.cy;
        if (iy < 16)
            iy = 16;

        /* Create the tip window */

        tip_wnd =
            CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
                           MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix,
                           iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL);

        ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);

    } else {

        /* Tip already exists, just set the text */

        SetWindowText(tip_wnd, str);
    }
}

void EnableSizeTip(bool bEnable)
{
    if (tip_wnd && !bEnable) {
        DestroyWindow(tip_wnd);
        tip_wnd = NULL;
    }

    tip_enabled = bEnable;
}
