/*********************************************************************
 *                                                                   *
 *  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();
}
