/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <stdio.h>
#include "windows.h"
#include "main.h"
#include "license.h"
#include "language.h"
#include "winclock.h"
#include "commdlg.h"

CLOCK_GLOBALS Globals;

/***********************************************************************
 *
 *           CLOCK_MenuCommand
 *
 *  All handling of main menu events
 */

int CLOCK_MenuCommand (WPARAM wParam)
{
CHAR szApp[MAX_STRING_LEN];
CHAR szAppRelease[MAX_STRING_LEN];
   switch (wParam) {
	/* switch to analog */
     case 0x100: {
         Globals.bAnalog = TRUE;
         LANGUAGE_UpdateMenuCheckmarks();
	 SendMessage(Globals.hMainWnd, WM_PAINT, 0, 0);
	 break;
       }
	/* switch to digital */
     case 0x101: {
         Globals.bAnalog = FALSE;
         LANGUAGE_UpdateMenuCheckmarks();
	 SendMessage(Globals.hMainWnd, WM_PAINT, 0, 0);
	 break;
       }
	/* change font */
     case 0x103: {
         MAIN_FileChooseFont();
         break;
       }
	/* hide title bar */
     case 0x105: {
         Globals.bWithoutTitle = !Globals.bWithoutTitle;
         LANGUAGE_UpdateWindowCaption();
         LANGUAGE_UpdateMenuCheckmarks();
         break;
       }
	/* always on top */
     case 0x10D: {
         Globals.bAlwaysOnTop = !Globals.bAlwaysOnTop;
         LANGUAGE_UpdateMenuCheckmarks();
         break;
       }
	/* show or hide seconds */
     case 0x107: {
         Globals.bSeconds = !Globals.bSeconds;
         LANGUAGE_UpdateMenuCheckmarks();
         SendMessage(Globals.hMainWnd, WM_PAINT, 0, 0);
         break;
       }
	/* show or hide date */
     case 0x108: {
         Globals.bDate = !Globals.bDate;
         LANGUAGE_UpdateMenuCheckmarks();
         LANGUAGE_UpdateWindowCaption();
         break;
       }
	/* show license */
     case 0x109: {
         WineLicense(Globals.hMainWnd);
         break;
       }
	/* show warranties */
     case 0x10A: {
         WineWarranty(Globals.hMainWnd);
         break;
       }
	/* show "about" box */
     case 0x10B: {
         LoadString(Globals.hInstance, 0x10C, szApp, sizeof(szApp));
         lstrcpy(szAppRelease,szApp);
         lstrcat(szAppRelease,"\n" PACKAGE_STRING);
         ShellAbout(Globals.hMainWnd, szApp, szAppRelease, 0);
         break;
       }
     /* Handle languages */
/*     default:
         LANGUAGE_DefaultHandle(wParam);
*/
   }
   return 0;
}

VOID MAIN_FileChooseFont(VOID) {

  CHOOSEFONT font;
  LOGFONT	 lf;

        font.lStructSize     = sizeof(font);
        font.hwndOwner       = Globals.hMainWnd;
        font.hDC             = NULL;
        font.lpLogFont       = &lf;
        font.iPointSize      = 0;
        font.Flags           = 0;
        font.rgbColors       = 0;
        font.lCustData       = 0;
        font.lpfnHook        = 0;
        font.lpTemplateName  = 0;
        font.hInstance       = Globals.hInstance;
/*        font.lpszStyle       = LF_FACESIZE; */
        font.nFontType       = 0;
        font.nSizeMin        = 0;
        font.nSizeMax        = 144;

        if (ChooseFont(&font)) {
            /* do nothing yet */
        }

}

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

LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC context;

    switch (msg) {

        case WM_CREATE: {
            printf("WM_CREATE\n");
   	    break;
        }

        case WM_RBUTTONUP: {
	    printf("WM_RBUTTONUP\n");
            Globals.bWithoutTitle = !Globals.bWithoutTitle;
            LANGUAGE_UpdateMenuCheckmarks();
            LANGUAGE_UpdateWindowCaption();
            UpdateWindow (Globals.hMainWnd);
            break;
        }

	case WM_PAINT: {
            printf("WM_PAINT\n");
            context = BeginPaint(hWnd, &ps);
	    if(Globals.bAnalog) {
	        DrawFace(context);
	        Idle(context);
	    }
	       else
            {
               /* do nothing */
            }
            EndPaint(hWnd, &ps);
            break;
        }

        case WM_SIZE: {
            printf("WM_SIZE\n");
	    Globals.MaxX = LOWORD(lParam);
	    Globals.MaxY = HIWORD(lParam);
            OldHour.DontRedraw   = TRUE;
            OldMinute.DontRedraw = TRUE;
            OldSecond.DontRedraw = TRUE;
	    break;
        }

        case WM_COMMAND: {
            CLOCK_MenuCommand(wParam);
            break;
        }

        case WM_DESTROY: {
            printf("WM_DESTROY\n");
            PostQuitMessage (0);
            break;
        }

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



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

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

    char szClassName[] = "CLClass";  /* To make sure className >= 0x10000 */
    char szWinName[]   = "Clock";

    /* Setup Globals */
    Globals.bAnalog	    = TRUE;
    Globals.bSeconds        = TRUE;
    Globals.lpszIniFile     = "clock.ini";
    Globals.lpszIcoFile     = "clock.ico";

    Globals.hInstance       = hInstance;
    Globals.hMainIcon       = ExtractIcon(Globals.hInstance,
                                          Globals.lpszIcoFile, 0);

    if (!Globals.hMainIcon) Globals.hMainIcon =
                                  LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));

    if (!prev){
	class.style         = CS_HREDRAW | CS_VREDRAW;
	class.lpfnWndProc   = CLOCK_WndProc;
	class.cbClsExtra    = 0;
	class.cbWndExtra    = 0;
	class.hInstance     = Globals.hInstance;
	class.hIcon         = LoadIcon (0, IDI_APPLICATION);
	class.hCursor       = LoadCursor (0, IDC_ARROW);
	class.hbrBackground = GetStockObject (GRAY_BRUSH);
	class.lpszMenuName  = 0;
	class.lpszClassName = szClassName;
    }

    if (!RegisterClass (&class)) return FALSE;

    Globals.hMainWnd = CreateWindow (szClassName, szWinName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, Globals.MaxX, Globals.MaxY, 0,
        LoadMenu(Globals.hInstance, STRING_MENU_Xx), Globals.hInstance, 0);

    LANGUAGE_LoadMenus();
    SetMenu(Globals.hMainWnd, Globals.hMainMenu);

    LANGUAGE_UpdateMenuCheckmarks();

    ShowWindow (Globals.hMainWnd, show);
    UpdateWindow (Globals.hMainWnd);

    while (TRUE) {
        Sleep(1);
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
                if (msg.message == WM_QUIT) return msg.wParam;
	        TranslateMessage(&msg);
	        DispatchMessage(&msg);
	        Idle(NULL);
        }
          else Idle(NULL);
    }

    /* We will never reach the following statement !   */
    return 0;
}

