/*
 * Clock
 *
 * Copyright 1998 Marcel Baur <mbaur@g26.ethz.ch>
 *
 * Clock is partially based on
 * - Program Manager by Ulrich Schmied
 * - rolex.c by Jim Peterson
 *
 *
 * 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 "windows.h"
#include "commdlg.h"

#include "main.h"
#include "winclock.h"

#define INITIAL_WINDOW_SIZE 200
#define TIMER_ID 1

CLOCK_GLOBALS Globals;

static VOID WineLicense(HWND Wnd)
{
  WCHAR cap[20], text[1024];
  LoadStringW(Globals.hInstance, IDS_LICENSE, text, sizeof(text)/sizeof(WCHAR));
  LoadStringW(Globals.hInstance, IDS_LICENSE_CAPTION, cap, sizeof(cap)/sizeof(WCHAR));
  MessageBoxW(Wnd, text, cap, MB_ICONINFORMATION | MB_OK);
}

static VOID WineWarranty(HWND Wnd)
{
  WCHAR cap[20], text[1024];
  LoadStringW(Globals.hInstance, IDS_WARRANTY, text, sizeof(text)/sizeof(WCHAR));
  LoadStringW(Globals.hInstance, IDS_WARRANTY_CAPTION, cap, sizeof(cap)/sizeof(WCHAR));
  MessageBoxW(Wnd, text, cap, MB_ICONEXCLAMATION | MB_OK);
}

static VOID CLOCK_UpdateMenuCheckmarks(VOID)
{
    HMENU hPropertiesMenu;
    hPropertiesMenu = GetSubMenu(Globals.hMainMenu, 0);
    if (!hPropertiesMenu)
	return;

    if(Globals.bAnalog) {

        /* analog clock */
        CheckMenuRadioItem(hPropertiesMenu, IDM_ANALOG, IDM_DIGITAL, IDM_ANALOG, MF_CHECKED);
        EnableMenuItem(hPropertiesMenu, IDM_FONT, MF_GRAYED);
    }
    else
    {
        /* digital clock */
        CheckMenuRadioItem(hPropertiesMenu, IDM_ANALOG, IDM_DIGITAL, IDM_DIGITAL, MF_CHECKED);
        EnableMenuItem(hPropertiesMenu, IDM_FONT, 0);
    }

    CheckMenuItem(hPropertiesMenu, IDM_NOTITLE, (Globals.bWithoutTitle ? MF_CHECKED : MF_UNCHECKED));

    CheckMenuItem(hPropertiesMenu, IDM_ONTOP, (Globals.bAlwaysOnTop ? MF_CHECKED : MF_UNCHECKED));
    CheckMenuItem(hPropertiesMenu, IDM_SECONDS, (Globals.bSeconds ? MF_CHECKED : MF_UNCHECKED));
    CheckMenuItem(hPropertiesMenu, IDM_DATE, (Globals.bDate ? MF_CHECKED : MF_UNCHECKED));
}

static VOID CLOCK_UpdateWindowCaption(VOID)
{
    WCHAR szCaption[MAX_STRING_LEN];
    int chars = 0;

    /* Set frame caption */
    if (Globals.bDate) {
	chars = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, NULL, NULL,
                               szCaption, sizeof(szCaption)/sizeof(WCHAR));
        if (chars) {
	    --chars;
	    szCaption[chars++] = ' ';
	    szCaption[chars++] = '-';
	    szCaption[chars++] = ' ';
	    szCaption[chars] = '\0';
	}
    }
    LoadStringW(0, IDS_CLOCK, szCaption + chars, MAX_STRING_LEN - chars);
    SetWindowTextW(Globals.hMainWnd, szCaption);
}

/***********************************************************************
 *
 *           CLOCK_ResetTimer
 */
static BOOL CLOCK_ResetTimer(void)
{
    UINT period; /* milliseconds */

    KillTimer(Globals.hMainWnd, TIMER_ID);

    if (Globals.bSeconds)
	if (Globals.bAnalog)
	    period = 50;
	else
	    period = 500;
    else
	period = 1000;

    if (!SetTimer (Globals.hMainWnd, TIMER_ID, period, NULL)) {
        static const WCHAR notimersW[] = {'N','o',' ','a','v','a','i','l','a','b','l','e',' ','t','i','m','e','r','s',0};
        WCHAR szApp[MAX_STRING_LEN];
        LoadStringW(Globals.hInstance, IDS_CLOCK, szApp, MAX_STRING_LEN);
        MessageBoxW(0, notimersW, szApp, MB_ICONEXCLAMATION | MB_OK);
        return FALSE;
    }
    return TRUE;
}

/***********************************************************************
 *
 *           CLOCK_ResetFont
 */
static VOID CLOCK_ResetFont(VOID)
{
    HFONT newfont;
    HDC dc = GetDC(Globals.hMainWnd);
    newfont = SizeFont(dc, Globals.MaxX, Globals.MaxY, Globals.bSeconds, &Globals.logfont);
    if (newfont) {
	DeleteObject(Globals.hFont);
	Globals.hFont = newfont;
    }
	
    ReleaseDC(Globals.hMainWnd, dc);
}


/***********************************************************************
 *
 *           CLOCK_ChooseFont
 */
static VOID CLOCK_ChooseFont(VOID)
{
    LOGFONTW lf;
    CHOOSEFONTW cf;
    memset(&cf, 0, sizeof(cf));
    lf = Globals.logfont;
    cf.lStructSize = sizeof(cf);
    cf.hwndOwner = Globals.hMainWnd;
    cf.lpLogFont = &lf;
    cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
    if (ChooseFontW(&cf)) {
	Globals.logfont = lf;
	CLOCK_ResetFont();
    }
}

/***********************************************************************
 *
 *           CLOCK_ToggleTitle
 */
static VOID CLOCK_ToggleTitle(VOID)
{
    /* Also shows/hides the menu */
    LONG style = GetWindowLongW(Globals.hMainWnd, GWL_STYLE);
    if ((Globals.bWithoutTitle = !Globals.bWithoutTitle)) {
	style = (style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP|WS_THICKFRAME;
	SetMenu(Globals.hMainWnd, 0);
    }
    else {
	style = (style & ~(WS_POPUP|WS_THICKFRAME)) | WS_OVERLAPPEDWINDOW;
        SetMenu(Globals.hMainWnd, Globals.hMainMenu);
        SetWindowRgn(Globals.hMainWnd, 0, TRUE);
    }
    SetWindowLongW(Globals.hMainWnd, GWL_STYLE, style);
    SetWindowPos(Globals.hMainWnd, 0,0,0,0,0, 
		 SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
    
    CLOCK_UpdateMenuCheckmarks();
    CLOCK_UpdateWindowCaption();
}

/***********************************************************************
 *
 *           CLOCK_ToggleOnTop
 */
static VOID CLOCK_ToggleOnTop(VOID)
{
    if ((Globals.bAlwaysOnTop = !Globals.bAlwaysOnTop)) {
	SetWindowPos(Globals.hMainWnd, HWND_TOPMOST, 0,0,0,0,
		     SWP_NOMOVE|SWP_NOSIZE);
    }
    else {
	SetWindowPos(Globals.hMainWnd, HWND_NOTOPMOST, 0,0,0,0,
		     SWP_NOMOVE|SWP_NOSIZE);
    }
    CLOCK_UpdateMenuCheckmarks();
}
/***********************************************************************
 *
 *           CLOCK_MenuCommand
 *
 *  All handling of main menu events
 */

static int CLOCK_MenuCommand (WPARAM wParam)
{
    WCHAR szApp[MAX_STRING_LEN];
    WCHAR szAppRelease[MAX_STRING_LEN];
    switch (wParam) {
        /* switch to analog */
        case IDM_ANALOG: {
            Globals.bAnalog = TRUE;
            CLOCK_UpdateMenuCheckmarks();
	    CLOCK_ResetTimer();
	    InvalidateRect(Globals.hMainWnd, NULL, FALSE);
            break;
        }
            /* switch to digital */
        case IDM_DIGITAL: {
            Globals.bAnalog = FALSE;
            CLOCK_UpdateMenuCheckmarks();
	    CLOCK_ResetTimer();
	    CLOCK_ResetFont();
	    InvalidateRect(Globals.hMainWnd, NULL, FALSE);
            break;
        }
            /* change font */
        case IDM_FONT: {
            CLOCK_ChooseFont();
            break;
        }
            /* hide title bar */
        case IDM_NOTITLE: {
	    CLOCK_ToggleTitle();
            break;
        }
            /* always on top */
        case IDM_ONTOP: {
	    CLOCK_ToggleOnTop();
            break;
        }
            /* show or hide seconds */
        case IDM_SECONDS: {
            Globals.bSeconds = !Globals.bSeconds;
            CLOCK_UpdateMenuCheckmarks();
	    CLOCK_ResetTimer();
	    if (!Globals.bAnalog)
		CLOCK_ResetFont();
	    InvalidateRect(Globals.hMainWnd, NULL, FALSE);
            break;
        }
            /* show or hide date */
        case IDM_DATE: {
            Globals.bDate = !Globals.bDate;
            CLOCK_UpdateMenuCheckmarks();
            CLOCK_UpdateWindowCaption();
            break;
        }
            /* show license */
        case IDM_LICENSE: {
            WineLicense(Globals.hMainWnd);
            break;
        }
            /* show warranties */
        case IDM_NOWARRANTY: {
            WineWarranty(Globals.hMainWnd);
            break;
        }
            /* show "about" box */
        case IDM_ABOUT: {
            LoadStringW(Globals.hInstance, IDS_CLOCK, szApp, sizeof(szApp)/sizeof(WCHAR));
            lstrcpyW(szAppRelease,szApp);
            ShellAboutW(Globals.hMainWnd, szApp, szAppRelease, 0);
            break;
        }
    }
    return 0;
}

/***********************************************************************
 *
 *           CLOCK_Paint
 */
static VOID CLOCK_Paint(HWND hWnd)
{
    PAINTSTRUCT ps;
    HDC dcMem, dc;
    HBITMAP bmMem, bmOld;

    dc = BeginPaint(hWnd, &ps);

    /* Use an offscreen dc to avoid flicker */
    dcMem = CreateCompatibleDC(dc);
    bmMem = CreateCompatibleBitmap(dc, ps.rcPaint.right - ps.rcPaint.left,
				    ps.rcPaint.bottom - ps.rcPaint.top);

    bmOld = SelectObject(dcMem, bmMem);

    SetViewportOrgEx(dcMem, -ps.rcPaint.left, -ps.rcPaint.top, NULL);
    /* Erase the background */
    FillRect(dcMem, &ps.rcPaint, GetSysColorBrush(COLOR_3DFACE));

    if(Globals.bAnalog)
	AnalogClock(dcMem, Globals.MaxX, Globals.MaxY, Globals.bSeconds, Globals.bWithoutTitle);
    else
	DigitalClock(dcMem, Globals.MaxX, Globals.MaxY, Globals.bSeconds, Globals.hFont);

    /* Blit the changes to the screen */
    BitBlt(dc, 
	   ps.rcPaint.left, ps.rcPaint.top,
	   ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,
           dcMem,
	   ps.rcPaint.left, ps.rcPaint.top,
           SRCCOPY);

    SelectObject(dcMem, bmOld);
    DeleteObject(bmMem);
    DeleteDC(dcMem);
    
    EndPaint(hWnd, &ps);
}

/***********************************************************************
 *
 *           CLOCK_WndProc
 */

static LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
	/* L button drag moves the window */
        case WM_NCHITTEST: {
	    LRESULT ret = DefWindowProcW(hWnd, msg, wParam, lParam);
	    if (ret == HTCLIENT)
		ret = HTCAPTION;
            return ret;
	}

        case WM_NCLBUTTONDBLCLK:
        case WM_LBUTTONDBLCLK: {
	    CLOCK_ToggleTitle();
            break;
        }

        case WM_PAINT: {
	    CLOCK_Paint(hWnd);
            break;

        }

        case WM_SIZE: {
            Globals.MaxX = LOWORD(lParam);
            Globals.MaxY = HIWORD(lParam);
            if (Globals.bAnalog && Globals.bWithoutTitle)
            {
                RECT rect;
                INT diameter = min( Globals.MaxX, Globals.MaxY );
                HRGN hrgn = CreateEllipticRgn( (Globals.MaxX - diameter) / 2,
                                               (Globals.MaxY - diameter) / 2,
                                               (Globals.MaxX + diameter) / 2,
                                               (Globals.MaxY + diameter) / 2 );
                GetWindowRect( hWnd, &rect );
                MapWindowPoints( 0, hWnd, (LPPOINT)&rect, 2 );
                OffsetRgn( hrgn, -rect.left, -rect.top );
                SetWindowRgn( Globals.hMainWnd, hrgn, TRUE );
            }
	    CLOCK_ResetFont();
            break;
        }

        case WM_COMMAND: {
            CLOCK_MenuCommand(wParam);
            break;
        }
            
        case WM_TIMER: {
            /* Could just invalidate what has changed,
             * but it doesn't really seem worth the effort
             */
	    InvalidateRect(Globals.hMainWnd, NULL, FALSE);
	    break;
        }

        case WM_DESTROY: {
            PostQuitMessage (0);
            break;
        }

        default:
            return DefWindowProcW(hWnd, msg, wParam, lParam);
    }
    return 0;
}


/***********************************************************************
 *
 *           WinMain
 */

int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
{
    MSG      msg;
    WNDCLASSW class;

    static const WCHAR szClassName[] = {'C','L','C','l','a','s','s',0};
    static const WCHAR szWinName[]   = {'C','l','o','c','k',0};

    /* Setup Globals */
    memset(&Globals.hFont, 0, sizeof (Globals.hFont));
    Globals.bAnalog         = TRUE;
    Globals.bSeconds        = TRUE;
    
    if (!prev){
        class.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
        class.lpfnWndProc   = CLOCK_WndProc;
        class.cbClsExtra    = 0;
        class.cbWndExtra    = 0;
        class.hInstance     = hInstance;
        class.hIcon         = LoadIconW(0, (LPCWSTR)IDI_APPLICATION);
        class.hCursor       = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
        class.hbrBackground = 0;
        class.lpszMenuName  = 0;
        class.lpszClassName = szClassName;
    }
    
    if (!RegisterClassW(&class)) return FALSE;
    
    Globals.MaxX = Globals.MaxY = INITIAL_WINDOW_SIZE;
    Globals.hMainWnd = CreateWindowW(szClassName, szWinName, WS_OVERLAPPEDWINDOW,
                                     CW_USEDEFAULT, CW_USEDEFAULT,
                                     Globals.MaxX, Globals.MaxY, 0,
                                     0, hInstance, 0);

    if (!CLOCK_ResetTimer())
        return FALSE;

    Globals.hMainMenu = LoadMenuW(0, MAKEINTRESOURCEW(MAIN_MENU));
    SetMenu(Globals.hMainWnd, Globals.hMainMenu);
    CLOCK_UpdateMenuCheckmarks();
    CLOCK_UpdateWindowCaption();
    
    ShowWindow (Globals.hMainWnd, show);
    UpdateWindow (Globals.hMainWnd);
    
    while (GetMessageW(&msg, 0, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    KillTimer(Globals.hMainWnd, TIMER_ID);
    DeleteObject(Globals.hFont);

    return 0;
}
