/* 
 *  Clock (winclock.c)
 *
 *  Copyright 1998 by Marcel Baur <mbaur@g26.ethz.ch>
 *
 *  This file is based on  rolex.c  by Jim Peterson.
 *
 *  I just managed to move the relevant parts into the Clock application
 *  and made it look like the original Windows one. You can find the original
 *  rolex.c in the wine /libtest directory.
 *
 *  Original file header:
 *  >
 *  > 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 "winclock.h"
#include "windows.h"
#include "main.h"
#include "winnls.h"

COLORREF FaceColor = RGB(192,192,192);
COLORREF HandColor = RGB(0,0,0);
COLORREF EtchColor = RGB(0,0,0);

float Pi=3.1415926;

int nLastSecond = 60;

HandData OldSecond,OldHour,OldMinute;

int MiddleX(void) {
  int X, diff;

  X    = (Globals.MaxX/2);  
  diff = (Globals.MaxX-Globals.MaxY);
  if (diff>0) { X = (X-(diff/2)); }
  return X;
}

int MiddleY(void) {
  int Y, diff;
  
  Y    = (Globals.MaxY/2);
  diff = (Globals.MaxX-Globals.MaxY);
  if (diff<0) { Y = Y+(diff/2); }
  return Y;
}

void DrawFace(HDC dc)
{
  int MidX, MidY, t, DiffX, DiffY;
  
  MidX = MiddleX();
  MidY = MiddleY();
  DiffX = (Globals.MaxX-MidX*2)/2;
  DiffY = (Globals.MaxY-MidY*2)/2;

  SelectObject(dc,CreateSolidBrush(FaceColor));
  SelectObject(dc,CreatePen(PS_SOLID,1,EtchColor));
  Ellipse(dc,DiffX,DiffY,2*MidX+DiffX,2*MidY+DiffY);

  for(t=0; t<12; t++)
  {
    MoveToEx(dc,(MidX+DiffX)+sin(t*Pi/6)*0.9*MidX,(MidY+DiffY)-cos(t*Pi/6)*0.9*MidY,NULL);
    LineTo(dc,(MidY+DiffX)+sin(t*Pi/6)*0.8*MidX,(MidY+DiffY)-cos(t*Pi/6)*0.8*MidY);
  }
  if(Globals.MaxX>64 && Globals.MaxY>64)
    for(t=0; t<60; t++)
      SetPixel(dc,(MidX+DiffX)+sin(t*Pi/30)*0.9*MidX,(MidY+DiffY)-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)
{
  if (OldHour.DontRedraw) return;
  MoveToEx(dc, OldHour.StartX, OldHour.StartY, NULL);
  LineTo(dc, OldHour.EndX, OldHour.EndY);
}

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

void DrawSecondHand(HDC dc)
{
    if (OldSecond.DontRedraw) return;
    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 (Globals.bAnalog && rv)DrawHourHand(dc);
  OldHour.StartX = Sx; OldHour.EndX = Ex;
  OldHour.StartY = Sy; OldHour.EndY = Ey;
  OldHour.DontRedraw=FALSE;
  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 (Globals.bAnalog && rv)DrawMinuteHand(dc);
  OldMinute.StartX = Sx; OldMinute.EndX = Ex;
  OldMinute.StartY = Sy; OldMinute.EndY = Ey;
  OldMinute.DontRedraw=FALSE;
  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;
  
  if (Globals.bSeconds) {
    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 (Globals.bAnalog && rv) DrawSecondHand(dc);
    OldSecond.StartX = Sx; OldSecond.EndX = Ex;
    OldSecond.StartY = Sy; OldSecond.EndY = Ey;
    OldSecond.DontRedraw=FALSE;
  }
  
  return rv;
}

void DigitalClock(HDC dc) {

  CHAR szTime[MAX_STRING_LEN];
  LPSTR time = szTime;
  static short xChar, yChar;
  TEXTMETRIC tm;
  
  SYSTEMTIME st;
  LPSYSTEMTIME lpst = &st;
  
  GetLocalTime(&st);
  GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, time, 
                MAX_STRING_LEN);
                
  SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
  xChar = tm.tmAveCharWidth;
  yChar = tm.tmHeight;
  
  xChar = 100;
  yChar = 100;
  TextOut (dc, xChar, yChar, szTime, strlen (szTime)); 
  DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
              
}



void AnalogClock(HDC dc) {

  SYSTEMTIME st;
  WORD H, M, S, F;
  int MidX, MidY, DiffX, DiffY;
  BOOL Redraw;

  GetLocalTime(&st);

  S = st.wSecond;
  if (nLastSecond==S) { exit; }
  nLastSecond = S;
  H = st.wHour;
  M = st.wMinute;
  F = st.wMilliseconds / 10;
  F = F + S*100;
  M = M*1000+F/6;
  H = H*1000+M/60;
  MidX = MiddleX();
  MidY = MiddleY();
  DiffX = (Globals.MaxX-MidX*2)/2;
  DiffY = (Globals.MaxY-MidY*2)/2;

  SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
  Redraw = FALSE;
  if(UpdateHourHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE;
  if(UpdateMinuteHand(dc,MidX+DiffX,MidY+DiffY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE;
  if(UpdateSecondHand(dc,MidX+DiffX,MidY+DiffY,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))); 
  
}

void Idle(HDC idc)
{
  HDC context;

  if(idc)
        context=idc;
  else
        context=GetDC(Globals.hMainWnd);

  if (!context) return;

  if (Globals.bAnalog)
  {
    AnalogClock(context);
  }
  else 
  {
    DigitalClock(context);
  }
  if(!idc) ReleaseDC(Globals.hMainWnd, context);
}
