/*
 * 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 "shellapi.h"

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

#define INITIAL_WINDOW_SIZE 200
#define TIMER_ID 1

CLOCK_GLOBALS Globals;

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 | CF_NOVERTFONTS;
    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 "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;
}
