/*********************************************************************
 *                                                                   *
 *  rolex.c: Windows clock application for WINE (by Jim Peterson)    *
 *                                                                   *
 *  This is a translation of a Turbo Pascal OWL application I made   *
 *  once, so it's a little flaky (tons of globals, functions that    *
 *  could have been in-lined, etc.).  The source code should easily  *
 *  compile with a standard Win32 C compiler.                        *
 *                                                                   *
 *  To try it out, type 'make rolex'.                                *
 *                                                                   *
 *********************************************************************/

#include <math.h>
#include <string.h>
#include "windows.h"

char AppName[] = "Rolex";
char WindowName[] = "Rolex";
int WindowWidth = 100;
int WindowHeight = 121;
COLORREF FaceColor = RGB(192,192,192);
COLORREF HandColor = RGB(0,0,0);
COLORREF EtchColor = RGB(0,0,0);

float Pi=3.1415926;

typedef struct
{
  int StartX,StartY,EndX,EndY;
} HandData;

int MaxX,MaxY;
HandData OldSecond,OldHour,OldMinute;

HWND HWindow;

void DrawFace(HDC dc)
{
  int MidX, MidY, t;

  MidX=MaxX/2;
  MidY=MaxY/2;
  SelectObject(dc,CreateSolidBrush(FaceColor));
  SelectObject(dc,CreatePen(PS_SOLID,1,EtchColor));
  Ellipse(dc,0,0,MaxX,MaxY);

  for(t=0; t<12; t++)
  {
    MoveToEx(dc,MidX+sin(t*Pi/6)*0.9*MidX,MidY-cos(t*Pi/6)*0.9*MidY,NULL);
    LineTo(dc,MidX+sin(t*Pi/6)*0.8*MidX,MidY-cos(t*Pi/6)*0.8*MidY);
  }
  if(MaxX>64 && MaxY>64)
    for(t=0; t<60; t++)
      SetPixel(dc,MidX+sin(t*Pi/30)*0.9*MidX,MidY-cos(t*Pi/30)*0.9*MidY
	       ,EtchColor);
  DeleteObject(SelectObject(dc,GetStockObject(NULL_BRUSH)));
  DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
  memset(&OldSecond,0,sizeof(OldSecond));
  memset(&OldMinute,0,sizeof(OldMinute));
  memset(&OldHour,0,sizeof(OldHour));
}

void DrawHourHand(HDC dc)
{
  MoveToEx(dc, OldHour.StartX, OldHour.StartY, NULL);
  LineTo(dc, OldHour.EndX, OldHour.EndY);
}

void DrawMinuteHand(HDC dc)
{
  MoveToEx(dc, OldMinute.StartX, OldMinute.StartY, NULL);
  LineTo(dc, OldMinute.EndX, OldMinute.EndY);
}

void DrawSecondHand(HDC dc)
{
  MoveToEx(dc, OldSecond.StartX, OldSecond.StartY, NULL);
  LineTo(dc, OldSecond.EndX, OldSecond.EndY);
}

BOOL UpdateHourHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
{
  int Sx, Sy, Ex, Ey;
  BOOL rv;

  rv = FALSE;
  Sx = MidX; Sy = MidY;
  Ex = MidX+sin(Pos*Pi/6000)*XExt;
  Ey = MidY-cos(Pos*Pi/6000)*YExt;
  rv = ( Sx!=OldHour.StartX || Ex!=OldHour.EndX || 
	 Sy!=OldHour.StartY || Ey!=OldHour.EndY );
  if(rv)DrawHourHand(dc);
  OldHour.StartX = Sx; OldHour.EndX = Ex;
  OldHour.StartY = Sy; OldHour.EndY = Ey;
  return rv;
}

BOOL UpdateMinuteHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
{
  int Sx, Sy, Ex, Ey;
  BOOL rv;

  rv = FALSE;
  Sx = MidX; Sy = MidY;
  Ex = MidX+sin(Pos*Pi/30000)*XExt;
  Ey = MidY-cos(Pos*Pi/30000)*YExt;
  rv = ( Sx!=OldMinute.StartX || Ex!=OldMinute.EndX ||
	 Sy!=OldMinute.StartY || Ey!=OldMinute.EndY );
  if(rv)DrawMinuteHand(dc);
  OldMinute.StartX = Sx; OldMinute.EndX = Ex;
  OldMinute.StartY = Sy; OldMinute.EndY = Ey;
  return rv;
}

BOOL UpdateSecondHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
{
  int Sx, Sy, Ex, Ey;
  BOOL rv;

  rv = FALSE;
  Sx = MidX; Sy = MidY;
  Ex = MidX+sin(Pos*Pi/3000)*XExt;
  Ey = MidY-cos(Pos*Pi/3000)*YExt;
  rv = ( Sx!=OldSecond.StartX || Ex!=OldSecond.EndX ||
	 Sy!=OldSecond.StartY || Ey!=OldSecond.EndY );
  if(rv)DrawSecondHand(dc);
  OldSecond.StartX = Sx; OldSecond.EndX = Ex;
  OldSecond.StartY = Sy; OldSecond.EndY = Ey;
  return rv;
}

void Idle(HDC idc)
{
  SYSTEMTIME st;
  WORD H, M, S, F;
  int MidX, MidY;
  HDC dc;
  BOOL Redraw;

  if(idc)
    dc=idc;
  else
    dc=GetDC(HWindow);
  if(!dc)return;

  GetLocalTime(&st);
  H = st.wHour;
  M = st.wMinute;
  S = st.wSecond;
  F = st.wMilliseconds / 10;
  F = F + S*100;
  M = M*1000+F/6;
  H = H*1000+M/60;
  MidX = MaxX/2;
  MidY = MaxY/2;
  SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
  Redraw = FALSE;
  if(UpdateHourHand(dc,MidX,MidY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE;
  if(UpdateMinuteHand(dc,MidX,MidY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE;
  if(UpdateSecondHand(dc,MidX,MidY,MidX*0.79,MidY*0.79,F)) Redraw = TRUE;
  DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor)));
  if(Redraw)
  {
    DrawSecondHand(dc);
    DrawMinuteHand(dc);
    DrawHourHand(dc);
  }
  DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
  if(!idc) ReleaseDC(HWindow,dc);
}

LRESULT ProcessAppMsg(HWND wnd,UINT msg,WPARAM w,LPARAM l)
{
  PAINTSTRUCT PaintInfo;
  HDC dc;

  switch(msg)
  {
  case WM_PAINT:
    if(GetUpdateRect(wnd,NULL,FALSE))
    {
      dc=BeginPaint(wnd,&PaintInfo);
      DrawFace(dc);
      Idle(dc);
      EndPaint(wnd,&PaintInfo);
    }
    break;

  case WM_SIZE:
    MaxX = LOWORD(l);
    MaxY = HIWORD(l);
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (wnd, msg, w, l);
  }
  return 0l;
}

WPARAM MessageLoop()
{
  MSG msg;

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

int PASCAL WinMain (HANDLE inst, HANDLE prev, LPSTR cmdline, int show)
{
  WNDCLASS class;
  if(!prev)
  {
    class.style = CS_HREDRAW | CS_VREDRAW;
    class.lpfnWndProc = ProcessAppMsg;
    class.cbClsExtra = 0;
    class.cbWndExtra = 0;
    class.hInstance  = inst;
    class.hIcon      = 0; /* Draw my own icon */
    class.hCursor    = LoadCursor (0, IDC_ARROW);
    class.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    class.lpszMenuName = 0;
    class.lpszClassName = AppName;
  }
  if (!RegisterClass (&class)) return -1;

  HWindow=CreateWindowEx(WS_EX_TOPMOST,AppName,WindowName,WS_OVERLAPPEDWINDOW,
			 CW_USEDEFAULT,CW_USEDEFAULT,WindowWidth,WindowHeight,
			 0,0,inst,0);
  memset(&OldSecond,0,sizeof(OldSecond));
  memset(&OldMinute,0,sizeof(OldMinute));
  memset(&OldHour,0,sizeof(OldHour));
  MaxX = WindowWidth;
  MaxY = WindowHeight;

  ShowWindow (HWindow, show);
  UpdateWindow (HWindow);

  return MessageLoop();
}
