/*static char *SCCSID = "@(#)wndproc.c  6.11 92/03/10";*/

/*=========================================================================\
 *									   *
 *	 FILE:wndproc.c							   *
 *									   *
 *	 DESCRIPTION:	 Window procedure for clock client window	   *
 *									   *
 *									   *
 *									   *
 *	Copyright 1989, 1990, 1992 IBM Corp.				   *
 *									   *
 *	DISCLAIMER OF WARRANTIES.  The following [enclosed] code is	   *
 *	sample code created by IBM Corporation. This sample code is not	   *
 *	part of any standard or IBM product and is provided to you solely  *
 *	for  the purpose of assisting you in the development of your	   *
 *	applications.  The code is provided "AS IS", without		   *
 *	warranty of any kind.  IBM shall not be liable for any damages	   *
 *	arising out of your use of the sample code, even if they have been *
 *	advised of the possibility of	such damages.			   *
 *									   *
 *-------------------------------------------------------------------------*
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *--------------------------------------------------------------
 *
 *  This source file contains the following functions:
 *
 *
 *
 *
 *
\*==============================================================*/

/*--------------------------------------------------------------*\
 *  Include files, macros, defined constants, and externs
\*--------------------------------------------------------------*/

#define INCL_DEV
#define INCL_WININPUT
#define INCL_WINFRAMEMGR
#define INCL_WINTRACKRECT
#define INCL_WINMENUS
#define INCL_WINSYS
#define INCL_WINTIMER
#define INCL_WINMESSAGEMGR
#define INCL_WINSHELLDATA
#define INCL_WINWINDOWMGR
#define INCL_WINHELP
#define INCL_GPICONTROL
#define INCL_GPIPRIMITIVES
#define INCL_GPILOGCOLORTABLE
#define INCL_GPIBITMAPS
#define INCL_GPITRANSFORMS
#define INCL_DOSSEMAPHORES
#define INCL_DOSDATETIME


#include <os2.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "clock.h"
#include "res.h"
#include "clkdata.h"
#include "help.h"

/*--------------------------------------------------------------*\
 *  Global variables and definitions for this file
\*--------------------------------------------------------------*/

/* Fields marked (RT) are filled in at run-time */

#define RESOURCEFLAG	0xFFFF0000

CHAR szHelpTitle [MAXTITLELENGTH + 1];


/*d-------------------------------------------------------------*\
 *  Entry point declarations
\*-------------------------------------------------------------k*/

MRESULT EXPENTRY ClkTicksDlgProc (HWND hWnd,ULONG usMessage,
				  MPARAM mp1, MPARAM mp2);
MRESULT EXPENTRY ClkColorsDlgProc(HWND hWnd,ULONG usMessage,
				  MPARAM mp1, MPARAM mp2);
MRESULT EXPENTRY TimeDlgProc(HWND hWnd,ULONG usMessage,
			     MPARAM mp1, MPARAM mp2);
MRESULT EXPENTRY AlarmDlgProc (HWND hWnd,ULONG usMessage,
			       MPARAM mp1, MPARAM mp2);
VOID FAR SaveApplication (HWND hWnd);

VOID ClkPaint (HWND);
VOID ClkCreate (HWND);
VOID ClkDestroy (HWND);
VOID ClkMinmax (HWND, PSWP);
VOID ClkSize (HWND);
VOID ClkTimer (HWND);
VOID ClkCommand (HWND, MPARAM,MPARAM );
VOID GetArrangedDate (CHAR []);
VOID ClkDrawDate (HPS, USHORT);

VOID ClkHideFrameControls (HWND);
VOID ClkShowFrameControls (HWND);
VOID DrawDigitalTime (HWND);
VOID GetCountryDependent (VOID);
VOID SetDispMode (VOID);
VOID SetRGBColors (VOID);
VOID ShadeLight	  (PLONG );
BYTE LightRGBByte (BYTE);
BYTE ShadeRGBByte (BYTE);
VOID InitMenu(MPARAM mp1, MPARAM mp2);
VOID EnableMenuItem(HWND hwndMenu, SHORT idItem, BOOL fEnable);
/****************************************************************\
 *  Routine Name:ClkWndProc()
 *--------------------------------------------------------------
 *
 *  Name:
 *
 *  Purpose:
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns: MRESULT()
 *
 *
\****************************************************************/

MRESULT EXPENTRY ClkWndProc (HWND hwnd, ULONG usMsg, MPARAM mp1, MPARAM mp2)
{
    switch (usMsg) {

    case WM_CREATE:
	ClkCreate (hwnd);
	return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));

    case WM_DESTROY:
	ClkDestroy (hwnd);
	return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));

    case WM_TIMER:
	ClkTimer (hwnd);
	if ( (BOOL) hDateTime)
	    WinSendMsg (hDateTime, WM_TIMER, mp1, mp2);
	break;

    case WM_PAINT:
	ClkPaint (hwnd);
	break;

    case WM_MINMAXFRAME:
	ClkMinmax (hwnd, (PSWP)mp1);
	break;

    case WM_SIZE:
	ClkSize (hwnd);
	return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));

    case WM_COMMAND:
	ClkCommand (hwnd, mp1,mp2);
	break;

    case WM_BUTTON1DOWN:
	return WinSendMsg (hwndFrame, WM_TRACKFRAME,
			   MPFROMSHORT((USHORT)mp2 | TF_MOVE), MPVOID);

    case WM_BUTTON1DBLCLK:
	if (cp.fControlsHidden)
	    ClkShowFrameControls (hwndFrame);
	else
	    ClkHideFrameControls (hwndFrame);
	break;

    case WM_TRANSLATEACCEL:
	return WinSendMsg(hwndFrame, usMsg, mp1, mp2);
	break;

    case WM_SAVEAPPLICATION:
	/***********************************************************\
	*  Task Manager option to Save Desktop sends this message.
	*  Save window state (MIN/RESTORE) and position in OS2.INI
	\***********************************************************/
	SaveApplication (hwndFrame);
	break;

     case WM_INITMENU:
	 InitMenu(mp1, mp2);
	 break;

    case HM_QUERY_KEYS_HELP:
	return (MRESULT)PANEL_HELPKEYS;	  /* return id of key help panel */
	break;

    default:
	/* let default window procedure handle it. */
	return (WinDefWindowProc (hwnd, usMsg, mp1, mp2));
    }

    return (MRFROMLONG(0));
}



/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkCreate()
 *
 *  Purpose:Intialize a newly created client window
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *	    1 - if sucessful execution completed
 *	    0 - if error
\****************************************************************/
VOID ClkCreate ( HWND hwnd )
{
    LONG cxScreen , cyScreen;  /* screen dimensions */
    LONG xLeft , yBottom ;	/* frame window location */
    ULONG cbBuf;
    LONG cyHeight;
    LONG cxWidth;

    hwndClient = hwnd;

    WinLoadString(hab, NULLHANDLE, IDS_TITLE,  0, (PSZ)szTitle	 );
    WinLoadString(hab, NULLHANDLE, IDS_HELPTITLE, 256, (PSZ)szHelpTitle);
    GetCountryDependent();
    /* we are called before the global hwndFrame is valid */
    hwndFrame = WinQueryWindow ( hwnd , QW_PARENT) ;
    hwndTitleBar = WinWindowFromID ( hwndFrame , FID_TITLEBAR ) ;
    hwndSysMenu = WinWindowFromID ( hwndFrame , FID_SYSMENU ) ;
    hwndMinMax = WinWindowFromID ( hwndFrame , FID_MINMAX ) ;

    /* load our menus */
    hwndMenu = WinLoadMenu (hwndFrame, NULLHANDLE, IDR_MAIN);
    /* determine screen dimensions */
    /* open a device context and create a presentation space */

    hdc = WinOpenWindowDC (hwnd);
    hps = GpiCreatePS (hab, hdc, &sizl, PU_ARBITRARY | GPIT_MICRO |
	    GPIA_ASSOC);

    /*
     * Create our off-screen 'buffer'.
     */
    hdcBuffer = DevOpenDC ( (HAB)0L, OD_MEMORY, "*", 0L, NULL, hdc);
    hpsBuffer = GpiCreatePS (hab, hdcBuffer, &sizl, PU_ARBITRARY |
			       GPIT_MICRO | GPIA_ASSOC);

    GpiCreateLogColorTable (hpsBuffer, 0, LCOLF_RGB, 0, 0, (PLONG)NULL);

    /* get the device resolutions so we can make the face appear circular */
    DevQueryCaps (hdc, (LONG)CAPS_VERTICAL_RESOLUTION,(LONG) 1L, &cyRes);
    DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &cxRes);
    DevQueryCaps (hdc, CAPS_COLOR_PLANES, 1L, &cColorPlanes);
    DevQueryCaps (hdc, CAPS_COLOR_BITCOUNT, 1L, &cColorBitcount);

    cxScreen = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);
    cyScreen = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);

    /*
     * Calculate an initial window position and size.
     */
    xLeft = cxScreen / 8;
    yBottom = cyScreen / 2;
    cxWidth = cxScreen / 3;
    cyHeight = cyScreen / 2;
    WinSetWindowPos (hwndFrame, NULLHANDLE, xLeft, yBottom,
		       cxWidth, cyHeight,
		       SWP_SIZE | SWP_MOVE | SWP_ACTIVATE);

    cbBuf = sizeof(cp);
    if (!PrfQueryProfileData(hab, SZ_APPNAME, SZ_KEYNAME, &cp, &cbBuf))
    {
	cp.usMajorTickPref = CLKTM_ALWAYS;
	cp.usMinorTickPref = CLKTM_NOTICONIC;
	cp.clrBackground = 0x00008080;
	cp.clrFace = 0x00008080;
	cp.clrHourHand = RGB_RED;
	cp.clrMinuteHand = RGB_RED;
	cp.fControlsHidden = FALSE;
	cp.usDispMode = DM_TIME | DM_ANALOG | DM_SECONDHAND;
	cp.alarm.uchHour = 0;
	cp.alarm.uchMinutes = 0;
	cp.alarm.usMode = 0;
	SetRGBColors();
	/* position the window and make it visible */
	WinSetWindowPos( hwndFrame , NULLHANDLE ,
			   xLeft , yBottom ,
			   cxWidth , cyHeight ,
			   SWP_SIZE | SWP_MOVE | SWP_ACTIVATE);
	WinQueryWindowPos(hwndFrame, &cp.swp);
    }
    else
    { /*Protect against garbage swp*/

	cp.swp.hwnd = hwndFrame;
	cp.swp.hwndInsertBehind = HWND_TOP;

	cp.swp.fl = (cp.swp.fl & (SWP_MINIMIZE | SWP_MAXIMIZE)) | SWP_SIZE | SWP_MOVE | SWP_ACTIVATE;
	SetRGBColors();
	WinSetMultWindowPos(hab, &cp.swp, 1);
    }

    if (cp.fControlsHidden)
	ClkHideFrameControls (hwndFrame);

    /*
     * Check relevant items.
     */
    WinSendMsg( hwndMenu,
		MM_SETITEMATTR,
		MPFROM2SHORT( IDM_TIME, TRUE),
		MPFROM2SHORT( MIA_CHECKED,
			      ( (cp.usDispMode & DM_TIME)?  MIA_CHECKED
				      : ~MIA_CHECKED) ) );
    WinSendMsg( hwndMenu,
		MM_SETITEMATTR,
		MPFROM2SHORT( IDM_DATE, TRUE),
		MPFROM2SHORT( MIA_DISABLED,
			      ( (!(cp.usDispMode & DM_TIME))?  MIA_DISABLED
				      : ~MIA_DISABLED) ) );
    WinSendMsg( hwndMenu,
		MM_SETITEMATTR,
		MPFROM2SHORT( IDM_DATE, TRUE),
		MPFROM2SHORT( MIA_CHECKED,
			      ( (cp.usDispMode & DM_DATE)?  MIA_CHECKED
				      : ~MIA_CHECKED) ) );
    WinSendMsg( hwndMenu,
		MM_SETITEMATTR,
		MPFROM2SHORT( IDM_TIME, TRUE),
		MPFROM2SHORT( MIA_DISABLED,
			      ( ((!(cp.usDispMode & DM_DATE) || (cp.usDispMode & DM_ANALOG)))?	MIA_DISABLED
				      : ~MIA_DISABLED) ) );
    WinSendMsg( hwndMenu,
		MM_SETITEMATTR,
		MPFROM2SHORT( (cp.usDispMode & DM_DIGITAL)
							  ?IDM_DIGITAL
							  :IDM_ANALOG,
			       TRUE),
		MPFROM2SHORT( MIA_CHECKED,
			      MIA_CHECKED));

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_SECONDHAND, TRUE),
		MPFROM2SHORT( MIA_CHECKED,
			      ( (cp.usDispMode & DM_SECONDHAND) ? MIA_CHECKED
				      : ~MIA_CHECKED)));


    /*
     * Disable these items if the digital clock is visible
     * since they won't apply.
     */
    if (cp.usDispMode & DM_DIGITAL)
    {
	WinSendMsg (hwndMenu, MM_SETITEMATTR,
		MPFROM2SHORT(IDM_SECONDHAND, TRUE),
		MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));

	WinSendMsg (hwndMenu, MM_SETITEMATTR,
		MPFROM2SHORT( IDM_TICKS, TRUE), MPFROM2SHORT( MIA_DISABLED,
		MIA_DISABLED));
    }

    /* have we been asked to start as an icon? */
    if (fStartAsIcon)
	WinSetWindowPos(hwndFrame, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);

    WinShowWindow(hwndFrame, TRUE);

    /* get the time in a format for dislaying */
    DosGetDateTime(&dt);
    dt.hours = (UCHAR )(dt.hours * (UCHAR) 5) % (UCHAR) 60 + dt.minutes / (UCHAR)12;

    /* start a timer */
    WinStartTimer (hab, hwnd, IDR_MAIN, 1000);

    WinLoadString(hab, NULLHANDLE, IDS_TITLE, 80, (PSZ)szTitle);
    GetCountryDependent();

}


/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkDestroy()
 *
 *  Purpose: Destroy clock face.
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:VOID
 *
 *
\****************************************************************/
VOID ClkDestroy (HWND hwnd)
{
    HBITMAP hbm;

    hbm = GpiSetBitmap (hpsBuffer, NULLHANDLE);

    if (hbm != NULLHANDLE)
	GpiDeleteBitmap (hbm);

    GpiDestroyPS (hpsBuffer);
    DevCloseDC (hdcBuffer);
}
/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name: ClkSize()
 *
 *  Purpose:When the window has been sized, we calculate  a page
 *	    rectangle which: (a) fills the window rectangle in either
 *	    the x or y dimension, (b) appears square, and (c) is centered
 *	    in the window rectangle
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *
 *
\****************************************************************/
VOID ClkSize (HWND hwnd)
{
    RECTL rclWindow;
    SIZEF sizef;
    LONG cxSquare, cySquare, cxEdge, cyEdge;
    LONG cyHeight;
    LONG cxWidth;
    HBITMAP hbm;
    BITMAPINFOHEADER bmp;

    /*
     * First get rid of any buffer bitmap already there.
     */
    hbm = GpiSetBitmap (hpsBuffer, NULLHANDLE);

    if (hbm != NULLHANDLE)
	GpiDeleteBitmap (hbm);

    /*
     * Get the width and height of the window rectangle.
     */
    WinQueryWindowRect (hwnd, &rclWindow);
    cxWidth = rclWindow.xRight - rclWindow.xLeft - 2;
    cyHeight = rclWindow.yTop - rclWindow.yBottom - 2;

    /*
     * Now create a bitmap the size of the window.
     */
    bmp.cbFix = sizeof(BITMAPINFOHEADER);
    bmp.cx = (SHORT)cxWidth;
    bmp.cy = (SHORT)cyHeight;
    bmp.cPlanes = (SHORT)cColorPlanes;
    bmp.cBitCount = (SHORT)cColorBitcount;
    hbm = GpiCreateBitmap(hpsBuffer, (PBITMAPINFOHEADER2)&bmp,
			  0x0000, (PBYTE)NULL, (PBITMAPINFO2)NULL);
    GpiSetBitmap (hpsBuffer, hbm);

    /*
     * Assume the size of the page rectangle is constrained in the y
     * dimension,compute the x size which would make the rectangle appear
     * square, then check the assumption and do the reverse calculation
     * if necessary.
     */
    cySquare = cyHeight - 2;
    cxSquare = ( cyHeight * cxRes ) / cyRes;

    if (cxWidth < cxSquare)
    {
	cxSquare = cxWidth - 2;
	cySquare = (cxWidth * cyRes) / cxRes;
    }

    /*
     * Fill in the page rectangle and set the page viewport.
     */
    cxEdge = (cxWidth - cxSquare ) / 2;
    cyEdge = (cyHeight - cySquare ) / 2;
    rclPage.xLeft = cxEdge;
    rclPage.xRight = cxWidth - cxEdge;
    rclPage.yBottom = cyEdge;
    rclPage.yTop = cyHeight - cyEdge;

    /*
     * Determine where to put the date. If we have room under the clock, we
     * put it there. If we have more room on the left we put it there. If we
     * have more room in the midlle, it goes there.
     */
    if (cp.usDispMode & DM_DATE)
    {
	vclrDate[SURFACE] = vclrBG[SHADE];
	vclrDate[LIGHT] = vclrBG[LIGHT];
	vclrDate[SHADE] = vclrBG[SHADE];
	vclrDate[BACKGROUND] = vclrBG[SURFACE];
	if (cyHeight > (cySquare*6/5)) { /*Goes under*/
	    vmatlfDateTrans.lM31 = (LONG)15;		/*Horizontal*/
	    vmatlfDateTrans.lM32 = -(LONG)17;	 /*vertical*/
	    vmatlfDateScale.fxM11 = MAKEFIXED(2,0x8000);
	    vmatlfDateScale.fxM22 = MAKEFIXED(2,0x8000);
	    rclPage. yTop += cyEdge;
	    rclPage. yBottom += cyEdge;
	    vusDatePos = DP_UNDER;
	}
	else
	{
	    if (cxWidth > (cxSquare * 31/10 ))
	    {
		vmatlfDateTrans.lM31 = -(LONG)53 ;	      /*Horizontal*/
		vmatlfDateTrans.lM32 = (LONG)04;    /*vertical*/
		vmatlfDateScale.fxM11 = MAKEFIXED(7,0xe000);
		vmatlfDateScale.fxM22 = MAKEFIXED(7,0xe000);
		rclPage.xRight += cxEdge;
		rclPage.xLeft += cxEdge;
		vusDatePos = DP_LEFTMIDDLE;

	    }
	    else
	    {
		if (cxWidth > (cxSquare * 2)) { /*Goes on the left*/
		    vmatlfDateTrans.lM31 = -(LONG)52 ;		  /*Horizontal*/
		    vmatlfDateTrans.lM32 = (LONG)2;    /*vertical*/
		    vmatlfDateScale.fxM11 = MAKEFIXED(3,0xd000);
		    vmatlfDateScale.fxM22 = MAKEFIXED(3,0xd000);
		    rclPage.xRight += cxEdge;
		    rclPage.xLeft += cxEdge;
		    vusDatePos = DP_LEFTDOWN  ;

		}
		else
		{   /*Goes inside*/
		    vmatlfDateTrans.lM31 = (LONG)24 ;		 /*Horizontal*/
		    vmatlfDateTrans.lM32 = (LONG)23;	/*vertical*/
		    vmatlfDateScale.fxM11 = MAKEFIXED(2,0);
		    vmatlfDateScale.fxM22 = MAKEFIXED(2,0);
		    vclrDate[SURFACE] = vclrFace[SHADE] ;
		    vclrDate[LIGHT] = vclrFace[LIGHT] ;
		    vclrDate[SHADE] = vclrFace[SHADE];
		    vclrDate[BACKGROUND] = vclrFace[SURFACE];
		    vusDatePos = DP_INSIDE;
		}
	    }
	}
    }

    f = GpiSetPageViewport (hps, &rclPage);
    f = GpiSetPageViewport (hpsBuffer, &rclPage);

    /*
     * Are we iconic?
     */
    f = WinQueryWindowPos (hwndFrame, &swp);
    fIconic = (BOOL)(swp.fl & SWP_MINIMIZE );
    fShowSecondHand = (BOOL) !(fIconic);

    GpiQueryCharBox(hpsBuffer, &sizef);
    GpiSetCharBox(hpsBuffer, &sizef);

    fBufferDirty = TRUE;
}

/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkMinMax()
 *
 *  Purpose:
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *	    VOID
 *
\****************************************************************/
VOID ClkMinmax (HWND hwnd, PSWP pswp)
{
    char achFinalDate[10];
    HWND hwndFrame;


    /*
     * We want the date as the icon text if the clock is
     * minimized and the user has selected both date and
     * time be displayed.
     */
    if ((cp.usDispMode & (DM_TIME | DM_DATE)) == (DM_TIME | DM_DATE))
    {
	hwndFrame = WinQueryWindow (hwnd, QW_PARENT);
	if (pswp->fl & SWP_MINIMIZE) {
	    GetArrangedDate (achFinalDate);
	    WinSetWindowText (hwndFrame, achFinalDate);
	} else {
	    WinSetWindowText (hwndFrame, "Clock");
	}
    }
}
/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkTimer()
 *
 *  Purpose: Handles window timer events
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *	    1 - if sucessful execution completed
 *	    0 - if error
\****************************************************************/
VOID ClkTimer (HWND hwnd)
{
    DATETIME	dtNew;
    static time_t lTimeChangeCheck = 0L;
    time_t	lTime;

    DosGetDateTime ( &dtNew ) ;

    if (cp.usDispMode & DM_ANALOG)
    {

	/* get the new time */
	DosGetDateTime (&dtNew);

	/* adjust the hour hand */
	dtNew.hours = (dtNew.hours * (UCHAR) 5 ) % (UCHAR) 60
		      + dtNew.minutes / (UCHAR)12;

	/* if we must move the hour and minute hands, redraw it all */
	if (dtNew.minutes != dt.minutes)
	{

	    ClkDrawFace(hpsBuffer);
	    ClkDrawDate(hpsBuffer, DM_REDRAW);
	    ClkDrawHand(hpsBuffer, HT_HOUR_SHADE, dtNew.hours);
	    ClkDrawHand(hpsBuffer, HT_MINUTE_SHADE, dtNew.minutes);
	    ClkDrawHand(hpsBuffer, HT_HOUR, dtNew.hours);
	    ClkDrawHand(hpsBuffer, HT_MINUTE, dtNew.minutes);

	    UpdateScreen (hps, NULL);

	    if (fShowSecondHand && (cp.usDispMode & DM_SECONDHAND))
	    {
		GpiSetMix(hps, FM_INVERT);
		ClkDrawHand(hps, HT_SECOND, dtNew.seconds);
	    }
	}

	/* otherwise just undraw the old second hand and draw the new */
	else if (fShowSecondHand  && (cp.usDispMode & DM_SECONDHAND))
	{
	    GpiSetMix(hps, FM_INVERT);
	    ClkDrawHand(hps, HT_SECOND, dt.seconds);
	    ClkDrawHand(hps, HT_SECOND, dtNew.seconds);
	}

	dt = dtNew ;
    }
    else /*Must be Digital*/
    {
	DrawDigitalTime(hwnd);
    }

    /*
     *if this is the first
     *time through init it
     */
    if(!lTimeChangeCheck)
    {
	  time(&lTimeChangeCheck);

    }

    /*
     *a quick check to see if
     *any other session
     *adjusted our time
     *if so reset the timer
     */
    else
    {
	  time(&lTime);
	  /*
	   *did the clock get changed by more than 60 seconds
	   */
	  if( lTime  > ( lTimeChangeCheck  + 60L ) ||
	      lTimeChangeCheck > ( lTime   + 60L ) )
	  {

	       AlarmSetTimer(cp.alarm.uchHour,
				   cp.alarm.uchMinutes);
	  }
	  lTimeChangeCheck = lTime;
     }

}

/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:DrawDigitalTime()
 *
 *  Purpose:
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *	    1 - if sucessful execution completed
 *	    0 - if error
\****************************************************************/

VOID DrawDigitalTime(HWND hwnd)
{
    RECTL rcl;
    RECTL rclChar;
    RECTL rclCharOld;
    RECTL rclTime;
    RECTL rclAmPm;
    RECTL rclDate;
    HPS hpsWnd;
    SIZEF sizef;
    USHORT usi;
    ULONG  ulCharWidth,ulCharModulu;
    char achTime[9];
    char achFinalDate[9];
    time_t     tTime;
    struct tm  *pLocalTime;

    WinQueryWindowRect (hwnd, &rcl);
    hpsWnd = WinGetPS (hwnd);

    memset(achTime,0,sizeof(achTime) );
    memset(achFinalDate,0,sizeof(achFinalDate) );

    GpiCreateLogColorTable (hpsWnd, LCOL_RESET, LCOLF_RGB, 0, 0,
				 (PLONG) NULL);

    /*
     *if black hands and black background
     *selected force the background to
     *blue
     */

    if( !cp.clrMinuteHand && !cp.clrBackground )
    {
	  cp.clrBackground = RGB_BLUE;
    }



    switch (cp.usDispMode & (DM_TIME | DM_DATE))
    {
    case DM_DATE:
	rclDate = rcl;
	break;

    case DM_TIME | DM_DATE:
	if (!fIconic)
	{
	    rclTime = rclDate = rcl;
	    rclTime.yBottom = rclDate.yTop = rcl.yTop / 2;
	    break;
	} /*else fall through*/

    case DM_TIME:
	rclTime = rcl;
	break;
    }

    if (cp.usDispMode & DM_TIME)
    {

	rclAmPm = rclTime;
	time(&tTime);
	pLocalTime = localtime(&tTime);
	if (bTwelveHourFormat)
	{
	   strftime(achTime, sizeof(achTime), "%I %M %S", pLocalTime);
	}
	else
	{
	   strftime(achTime, sizeof(achTime), "%H %M %S", pLocalTime);
	}

	/*insert country time separator*/
	achTime[2] = achTime[5] = szTimeSep[0];
	achTime[8] = '\000';
	/*Process 12 hours mode*/
	if (bTwelveHourFormat)
	{

	    if (fIconic)
	    {
		rclTime.yBottom = rclAmPm.yTop = rclTime.yTop / 2;
	    }
	    else
	    {
		rclTime.xRight = rcl.xRight * 8 / 11;
		rclAmPm.xLeft = rclTime.xRight;
	    }

	    strcpy(achAmPm,szAnteMeridian);

	    if (pLocalTime->tm_hour >= 12)
	    {
		strcpy(achAmPm,szPostMeridian);
	    }

	}

	GpiSetCharMode(hpsWnd, CM_MODE3);

	if (fIconic)
	{
	    sizef.cx = MAKEFIXED(LOUSHORT((rclTime.xRight - rclTime.xLeft)
		    / 3), 0);
	    sizef.cy = MAKEFIXED(LOUSHORT((rclTime.yTop - rclTime.yBottom)
		    * 1400 / 1000), 0);
	}
	else
	{
	    sizef.cx = MAKEFIXED(LOUSHORT((rclTime.xRight - rclTime.xLeft)
		    / 6), 8000);
	    sizef.cy = MAKEFIXED(LOUSHORT((rclTime.yTop - rclTime.yBottom)
		    * 1000 / 1500), 0);
	}

	GpiSetCharBox(hpsWnd, &sizef);

	if (bTwelveHourFormat)
	{

	    if( strcmp(achAmPm,achOldAmPm) )
	    {
		WinFillRect(hpsWnd, &rclAmPm, cp.clrBackground);
		WinDrawText(hpsWnd, sizeof(achAmPm) - 1, (PSZ)achAmPm,
			(PRECTL)&rclAmPm, cp.clrMinuteHand, cp.clrBackground,
			DT_CENTER | DT_VCENTER );
	    }
	}

	if (!fIconic)
	{

	    WinDrawText(hpsWnd, sizeof(achTime) - 1 , (PSZ)achTime,
		    (PRECTL)&rclTime, cp.clrMinuteHand, cp.clrBackground,
		    DT_CENTER | DT_VCENTER | DT_QUERYEXTENT);

	    ulCharWidth = (rclTime.xRight - rclTime.xLeft) / (sizeof(achTime) - 1 );
	    ulCharModulu = (rclTime.xRight - rclTime.xLeft) % (sizeof(achTime) - 1 );
	    rclCharOld.xRight = rclTime.xLeft;

	    rclChar.yTop = rclTime.yTop;
	    rclChar.yBottom = rclTime.yBottom;

	    for (usi = 0; usi < (sizeof(achTime)); usi++)
	    {
		rclChar.xLeft = rclCharOld.xRight + (ULONG)1;
		rclChar.xRight = rclChar.xLeft + ulCharWidth +
			((ulCharModulu > 0L) ? 1L : 0L);

		if (ulCharModulu)
		    ulCharModulu--;

		if (achTime[usi] == szTimeSep[0])
		{
		    rclChar.xRight -= 3;
		}
		else
		{
		    rclChar.xRight += 1;
		}

		rclCharOld = rclChar;

		if (achTime[usi] != achOldTime[usi])
		{
		    WinFillRect (hpsWnd, &rclChar, cp.clrBackground);
		    if (!((usi == 0) && (achTime[0] == '0') &&
			    (bTwelveHourFormat)))
			WinDrawText (hpsWnd, 1, (PSZ)&achTime[usi], &rclChar,
				cp.clrMinuteHand, cp.clrBackground,
				DT_CENTER | DT_VCENTER);
		}
	    }
	}
	else
	{   /*Iconic. just draw if minute changed*/

	    if (strncmp(achTime,achOldTime,5))
	    {
		WinFillRect(hpsWnd,&rclTime,cp.clrBackground);
		WinDrawText(hpsWnd, sizeof(achTime) - 4 , (PSZ)achTime,
			(PRECTL)&rclTime, cp.clrMinuteHand, cp.clrBackground,
			DT_CENTER | DT_VCENTER);
	    }
	}
    }

    if ((!(cp.usDispMode & DM_TIME)) || ((cp.usDispMode & DM_DATE) &&
	    (!fIconic)))
    {
	GetArrangedDate(achFinalDate);
	if (strncmp(achFinalDate, achOldDate,
		sizeof(achFinalDate) - fIconic ? 4 : 1))
	{

	    WinFillRect (hpsWnd, &rclDate, cp.clrBackground);
	    GpiSetCharMode (hpsWnd, CM_MODE3);

	    sizef.cx = MAKEFIXED(LOUSHORT(
			    (rclDate.xRight - rclDate.xLeft) / 5), 0);
	    sizef.cy = MAKEFIXED(LOUSHORT(
			    (rclDate.yTop - rclDate.yBottom) * 1000 / 1500), 0);

	    GpiSetCharBox(hpsWnd, &sizef);
	    WinDrawText(hpsWnd,
			(sizeof(achFinalDate) - (fIconic ? 4 : 1) ),
			(PSZ)achFinalDate,(PRECTL)&rclDate,
			(LONG)cp.clrMinuteHand,
			(LONG)cp.clrBackground,
			(ULONG )(DT_CENTER | DT_VCENTER ) );
	}
    }

    WinReleasePS(hpsWnd);

    strncpy(achOldTime,achTime,sizeof(achOldTime));
    strncpy(achOldAmPm,achAmPm,sizeof(achOldAmPm));
    strncpy(achOldDate,achFinalDate,sizeof(achOldDate));
}
/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkCommand()
 *
 *  Purpose:Handle  WM_COMMAND events.
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *	    VOID
 *
\****************************************************************/
VOID ClkCommand ( HWND hwnd , MPARAM mp1, MPARAM mp2 )
{
    DATETIME  dtNew ;

    switch ( SHORT1FROMMP ( mp1 ) )
    {

	case IDM_TICKS :
	    WinDlgBox ( HWND_DESKTOP , hwndFrame , ClkTicksDlgProc ,
			NULLHANDLE ,
			IDD_TICKS , (PVOID )NULL ) ;
	    break;

	case IDM_EXIT:
	    /*
	     *post the event semaphore
	     *for our alarm thread
	     */
	    fEndThread = TRUE;
	    DosPostEventSem(TimerResources.hTimerDev);
	    WinPostMsg(hwnd, WM_QUIT,MPVOID, MPVOID);


	    break;

	case IDM_COLORS :
	    WinDlgBox ( HWND_DESKTOP , hwndFrame ,ClkColorsDlgProc ,
			NULLHANDLE ,
			IDD_COLORS , NULL ) ;
	    SetRGBColors();
	    ClkSize(hwnd);
	    break ;

	case IDM_TOGGLECONTROLS :
	    if (cp.fControlsHidden) {
		ClkShowFrameControls( hwndFrame );
	    } else {
		ClkHideFrameControls ( hwndFrame ) ;
	    }
	    break ;

	case IDM_DATETIME:
	    if (hDateTime == NULLHANDLE)
	    {
		WinDlgBox(HWND_DESKTOP,hwndFrame,TimeDlgProc,
			  NULLHANDLE,IDD_TIME ,NULL);
		dt.minutes += 2; /*Fool the ClkTimer proc. It will now think it have
				  to redraw*/
	    } else {
		WinSetFocus (HWND_DESKTOP, hDateTime);
	    }
	    break;
	case IDM_ALARM:
	    if (hAlarmTime == (HWND)NULL)
	    {
		WinDlgBox(HWND_DESKTOP,hwndFrame,AlarmDlgProc,
			  NULLHANDLE,IDD_ALARM ,NULL);
	    }
	    else
	    {
		WinSetFocus(HWND_DESKTOP,hAlarmTime);
	    }

	    break;

	case IDM_SECONDHAND:
	    cp.usDispMode = ((cp.usDispMode & DM_SECONDHAND) ?
		    (cp.usDispMode & (~DM_SECONDHAND)) : (cp.usDispMode | DM_SECONDHAND));

	    GpiSetMix(hps, FM_INVERT);

	    /*
	     * Depending on the current mode draw or remove the second hand.
	     */
	    if (cp.usDispMode & DM_SECONDHAND) {
		DosGetDateTime(&dtNew);
		ClkDrawHand(hps, HT_SECOND, dtNew.seconds);
		dt.seconds = dtNew.seconds;
	    } else {
		ClkDrawHand(hps, HT_SECOND, dt.seconds);
	    }

	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_SECONDHAND, TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				      ( (cp.usDispMode & DM_SECONDHAND)?  MIA_CHECKED
					      : ~MIA_CHECKED) ) );
	    break;

	case IDM_TIME:
	    cp.usDispMode = ((cp.usDispMode & DM_TIME) ? (cp.usDispMode & (~DM_TIME))
						      : (cp.usDispMode | DM_TIME));

	    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_TIME, TRUE),
		    MPFROM2SHORT(MIA_CHECKED, ((cp.usDispMode & DM_TIME) ?
		    MIA_CHECKED : ~MIA_CHECKED)));

	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_DATE, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
				      ( (!(cp.usDispMode & DM_TIME)) ? MIA_DISABLED
					      : ~MIA_DISABLED) ) );
	    ClkSize(hwnd);
	    WinInvalidateRect(hwnd, NULL, TRUE);
	    break;

	case IDM_DATE:
	    cp.usDispMode = ((cp.usDispMode & DM_DATE) ? (cp.usDispMode & (~DM_DATE))
						      : (cp.usDispMode | DM_DATE));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_DATE, TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				      ( (cp.usDispMode & DM_DATE)?  MIA_CHECKED
					      : ~MIA_CHECKED) ) );
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_TIME, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
				      ( ((!(cp.usDispMode & DM_DATE)) || (cp.usDispMode & DM_ANALOG))?	MIA_DISABLED
					      : ~MIA_DISABLED) ) );
	    ClkSize(hwnd);
	    WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE);

	    break;
	case IDM_DIGITAL:
	    cp.usDispMode |=  DM_DIGITAL;
	    cp.usDispMode &=  (~DM_ANALOG);
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_DIGITAL, TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				      MIA_CHECKED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_ANALOG , TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				     ~MIA_CHECKED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_SECONDHAND, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
					MIA_DISABLED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_TICKS, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
					MIA_DISABLED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_TIME, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
				      ( ((!(cp.usDispMode & DM_DATE)) || (cp.usDispMode & DM_ANALOG))?	MIA_DISABLED
					      : ~MIA_DISABLED) ) );
	    WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE);
	    break;
	case IDM_ANALOG :
	    cp.usDispMode |=  DM_ANALOG;
	    cp.usDispMode &=  (~DM_DIGITAL);
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_ANALOG, TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				      MIA_CHECKED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_DIGITAL, TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				     ~MIA_CHECKED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_TIME, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
					MIA_DISABLED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_DATE, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
					~MIA_DISABLED));

	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_SECONDHAND, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
					~MIA_DISABLED));
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_TICKS, TRUE),
			MPFROM2SHORT( MIA_DISABLED,
					~MIA_DISABLED));

	    cp.usDispMode |= DM_TIME;
	    WinSendMsg( hwndMenu,
			MM_SETITEMATTR,
			MPFROM2SHORT( IDM_TIME, TRUE),
			MPFROM2SHORT( MIA_CHECKED,
				      MIA_CHECKED));
	    WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE);
	    break;


	case IDM_HELPHELPFORHELP:
	    HelpHelpForHelp(mp2);
	    break;

	case IDM_HELPEXTENDED:
	    HelpExtended(mp2);
	    break;

	case IDM_HELPKEYS:
	    HelpKeys(mp2);
	    break;

	case IDM_HELPINDEX:
	    HelpIndex(mp2);
	    break;

	case IDM_HELPTUTORIAL:
	    HelpTutorial(mp2);
	    break;

	case IDM_HELPABOUT:
	    HelpAbout(mp2);
	    break;

     case IDM_ALARM_EXPIRED:
	   WinMessageBox(HWND_DESKTOP,
			 hwndFrame,
			 (PSZ)"Alarm Expired",
			 (PSZ)"The Bells Are Ringing",
			 0,
			 MB_OK);
	    break;
    }
}


/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkHideFrameControls
 *
 *  Purpose:Hide the title bar and associted controls
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *
 *
\****************************************************************/
VOID ClkHideFrameControls ( HWND hwndFrame )
{

    WinSetParent ( hwndTitleBar , HWND_OBJECT , FALSE ) ;
    WinSetParent ( hwndSysMenu , HWND_OBJECT , FALSE ) ;
    WinSetParent ( hwndMinMax , HWND_OBJECT , FALSE ) ;
    WinSetParent ( hwndMenu , HWND_OBJECT , FALSE ) ;

    WinSendMsg ( hwndFrame , WM_UPDATEFRAME ,
		 MPFROMLONG( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_MENU ) ,
		 MPVOID) ;

    cp.fControlsHidden = TRUE ;
}
/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ClkShowFrameControls
 *
 *  Purpose:Show the title bar and associated contols
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *	    VOID
 *
\****************************************************************/


VOID ClkShowFrameControls ( HWND hwndFrame )
{

    WinSetParent ( hwndTitleBar , hwndFrame , FALSE ) ;
    WinSetParent ( hwndSysMenu , hwndFrame , FALSE ) ;
    WinSetParent ( hwndMinMax , hwndFrame , FALSE ) ;
    WinSetParent ( hwndMenu , hwndFrame , FALSE ) ;

    WinSendMsg ( hwndFrame , WM_UPDATEFRAME ,
		MPFROMLONG( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINMAX | FCF_MENU ) ,
		MPVOID) ;
    WinInvalidateRect ( hwndFrame , NULL , TRUE ) ;

    cp.fControlsHidden = FALSE ;
}


/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:GetArrangedDate()
 *
 *  Purpose:
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns: VOID
 *
\****************************************************************/
VOID GetArrangedDate(CHAR achFinalDate[])
{
    time_t     tTime;
    struct tm  *pLocalTime;

    time(&tTime);
    pLocalTime = localtime(&tTime);
    switch (vusDateFormat)
    {
	case 2: /*YMD*/
	    if (fIconic)
	    {
	       strftime(achFinalDate, sizeof(achFinalDate), "%m %d %y", pLocalTime);
	    }
	    else
	    {
	       strftime(achFinalDate, sizeof(achFinalDate), "%y %m %d", pLocalTime);
	    }
    /*put date separators*/
	    achFinalDate[2] = achFinalDate[5] = szDateSep[0];
	    break;

	case 1: /*DMY*/
	    strftime(achFinalDate, sizeof(achFinalDate), "%d %m %y", pLocalTime);
	    achFinalDate[2] = achFinalDate[5] = szDateSep[0];
	    break;

	default: /*MDY*/
	    strftime(achFinalDate, 9, "%m %d %y", pLocalTime);
	    achFinalDate[2] = achFinalDate[5] = szDateSep[0];
	    break;
    }
    achFinalDate[8] = '\0';
}

/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:SaveApplication()
 *
 *  Purpose:Handle the	 WM_SAVEAPPLICATION message from the desktop
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns: VOID
 *
 *
\****************************************************************/
VOID FAR SaveApplication( HWND hwnd )
{

    WinQueryWindowPos( hwnd, (PSWP)&cp.swp);
    PrfWriteProfileData(hab, SZ_APPNAME, SZ_KEYNAME, &cp, sizeof(cp));
}


/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name: SetRGBColors
 *
 *  Purpose: Set the RGB schema so that each time a user changes the
 *	     color we update it here.
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:VOID
 *
 *
\****************************************************************/
VOID SetRGBColors(VOID)
{
    vclrFace[SURFACE] = cp.clrFace;
    vclrBG[SURFACE] = cp.clrBackground;
    vclrHands[SURFACE] = cp.clrMinuteHand;
    vclrMajorTicks[SURFACE] = cp.clrHourHand;

    /*Fill color tables*/
    ShadeLight(vclrMajorTicks);

    vclrMinorTicks[SURFACE] = vclrFace[SURFACE];
    ShadeLight(vclrMinorTicks);

    ShadeLight(vclrFace);

    vclrRing[SURFACE] = vclrFace[SURFACE];
    ShadeLight(vclrRing);

    #ifdef DISABLE
    ShadeLight(vclrHands);
    #endif
    vclrHands[SHADE] = RGB_BLACK;

    ShadeLight(vclrBG);
}
/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ShadeLight()
 *
 *  Purpose: Find the shade and light color index values and
 *	     install them in the colors	  array of the element
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *
 *
\****************************************************************/
VOID ShadeLight(PLONG nplColors)
{
   typedef  union  _RGBLONG
   {
	RGB rgb;
	LONG lng;
   } RGBLONG ;
   RGBLONG  rgbSurface,rgbShade,rgbLight;

   rgbSurface.lng = rgbShade.lng = rgbLight.lng = 0L;

   #ifdef DISABLE
   rgbSurface.lng = GpiQueryRGBColor(hps,0L,);
   #endif
   rgbSurface.lng = nplColors[SURFACE];
   rgbShade.rgb.bBlue = ShadeRGBByte(rgbSurface.rgb.bBlue);
   rgbShade.rgb.bRed = ShadeRGBByte(rgbSurface.rgb.bRed);
   rgbShade.rgb.bGreen = ShadeRGBByte(rgbSurface.rgb.bGreen);
   rgbLight.rgb.bBlue = LightRGBByte(rgbSurface.rgb.bBlue);
   rgbLight.rgb.bRed = LightRGBByte(rgbSurface.rgb.bRed);
   rgbLight.rgb.bGreen = LightRGBByte(rgbSurface.rgb.bGreen);
   nplColors[SHADE] = rgbShade.lng;
   nplColors[LIGHT] = rgbLight.lng;
}


/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:ShadeRGBByte
 *
 *  Purpose:
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *
 *
\****************************************************************/

BYTE ShadeRGBByte(BYTE brgb)
{
  #define SHADER   ( (BYTE) 0x50)

  if (brgb > SHADER)
  {
     return (brgb - SHADER);
  }
  else
  {
     return (0);
  }

}
/****************************************************************\
 *
 *--------------------------------------------------------------
 *
 *  Name:LightRGBByte
 *
 *  Purpose:
 *
 *
 *
 *  Usage:
 *
 *  Method:
 *	    -
 *
 *	    -
 *	    -
 *
 *	    -
 *	    -
 *
 *  Returns:
 *
 *
\****************************************************************/
BYTE LightRGBByte(BYTE brgb)
{

  #define LIGHTER  ( (BYTE) 0x40)

  if (brgb < (0xff - LIGHTER) )
  {
     return (brgb + LIGHTER);
  }

  else return (0xff);

}



/****************************************************************\
 *  Menu item intialization routine
 *--------------------------------------------------------------
 *
 *  Name:   InitMenu(mp1, mp2)
 *
 *  Purpose: Processes the WM_INITMENU message for the main window,
 *		disabling any menus that are not active
 *
 *  Usage:  Routine is called each time a menu is dropped
 *
 *  Method: A switch statement branches control based upon
 *	    the id of the menu that is being displayed
 *
 *  Returns:
\****************************************************************/
VOID InitMenu(MPARAM mp1, MPARAM mp2)
{

    /* define a shorthand way of denoting the menu handle */
    #define hwndMenu	    HWNDFROMMP(mp2)

    switch(SHORT1FROMMP(mp1))
    {

	case IDM_HELP:
	    /*
	     * Enable or disable the Help menu depending upon whether the
	     * help manager has been enabled
	     */
	    EnableMenuItem(hwndMenu, IDM_HELPHELPFORHELP, fHelpEnabled);
	    EnableMenuItem(hwndMenu, IDM_HELPEXTENDED, fHelpEnabled);
	    EnableMenuItem(hwndMenu, IDM_HELPKEYS, fHelpEnabled);
	    EnableMenuItem(hwndMenu, IDM_HELPINDEX, fHelpEnabled);

	    /** REMEMBER: add a case for IDM_HELPTUTORIAL if you include
		the Tutorial menu item	 **/

	    break;

	default:
	    break;
    }

    #undef hwndMenu

}   /* InitMenu() */


/****************************************************************\
 *  Enables/Disables the menu item of the given menu
 *--------------------------------------------------------------
 *
 *  Name:   EnableMenuItem(hwndMenu, idItem, fEnable)
 *
 *  Purpose: Enables or disables the menu item
 *
 *  Usage:  Called whenever a menu item is to be enabled or
 *	    disabled
 *
 *  Method: Sends a MM_SETITEMATTR to the menu with the
 *	    given item id.  Sets the MIA_DISABLED attribute
 *	    flag if the item is to be disabled, clears the flag
 *	    if enabling
 *
 *  Returns:
 *
\****************************************************************/
VOID EnableMenuItem(HWND hwndMenu, SHORT idItem, BOOL fEnable)
{
    SHORT fsFlag;

    if(fEnable)
	fsFlag = 0;
    else
	fsFlag = MIA_DISABLED;

    WinSendMsg(hwndMenu,
	       MM_SETITEMATTR,
	       MPFROM2SHORT(idItem, TRUE),
	       MPFROM2SHORT(MIA_DISABLED, fsFlag));

}   /* EnableMenuItem() */


/*--------------------------------------------------------------*\
 *  End of file :wndproc.c
\*--------------------------------------------------------------*/
