/*
   newclock.c by bill buckels
   a clock program template
   March 1991

*/

/*

a radian is the measure of an angle with its with vertex at the
center of a circle whose intercepted arc on the circle is equal
in length to the radius of the circle...

 - allyn j. washington

*/

#include <graphics.h>
#include <bios.h>
#include <math.h>
#include <stdio.h>

#define ESCKEY     27  /* character generated by the Esc key            */
#define FUNCKEY    0   /* first character generated by function keys    */
#define UPARROW    'H' /* second character generated by up-arrow key    */
#define DOWNARROW  'P' /* second character generated by down-arrow key  */
#define LEFTARROW  'K' /* second character generated by left-arrow key  */
#define RIGHTARROW 'M' /* second character generated by right-arrow key */

struct vconfig _videostuff;
float aspect_rat;
char timestuff[2][40];
char stuffcords[2][2]={0,182,
                       0,24};

void circlepoints(x,y,baselength ,fdegrees)
int *x,*y;
int baselength;
float fdegrees;
{
     /* convert from degrees to radians */
     /* in order to use trig functions  */
     float pi=3.1415926535;
     float radians;
     float tempx= (float)baselength;
     float tempy= (float)baselength;
     int degrees= (int)fdegrees;

     switch(degrees)
     {
       case 360 :
       case 0   : *y-=(int)(aspect_rat*baselength);break;
       case 180 : *y+=(int)(aspect_rat*baselength);break;

       case 90  : *x+=baselength;break;
       case 270 : *x-=baselength;break;

     default    :

     /* positive angles - all quadrants */
     if(degrees > 0  && degrees <=45  || degrees >= 315 && degrees < 360||
        degrees > 90 && degrees <=135 || degrees >= 225 && degrees < 270)
     {
       radians = (pi*degrees)/180;
       tempx*= sin(radians);
       tempy*= cos(radians);
       *x+=(int)tempx;
       *y-=(int)(tempy*aspect_rat);
      }

    /*  negative angles - all quadrants */
     if(degrees > 45 && degrees < 90   || degrees < 315 && degrees > 270 ||
        degrees > 135 && degrees < 180 || degrees > 180 && degrees < 225)
     {
       degrees = 90-degrees;
       radians = (pi*degrees)/180;
       tempx*= cos(radians);
       tempy*= sin(radians);
       *x+=(int)tempx;
       *y-=(int)(tempy*aspect_rat);
      }
    }

}

char *hourstrings[14]={
     "Twelve",
     "One",
     "Two",
     "Three",
     "Four",
     "Five",
     "Six",
     "Seven",
     "Eight",
     "Nine",
     "Ten",
     "Eleven",
     "Twelve",
     "One"};

char *minutestrings[31]={
     "O\'clock",
     "One",
     "Two",
     "Three",
     "Four",
     "Five",
     "Six",
     "Seven",
     "Eight",
     "Nine",
     "Ten",
     "Eleven",
     "Twelve",
     "Thirteen",
     "Fourteen",
     "Quarter",
     "Sixteen",
     "Seventeen",
     "Eighteen",
     "Nineteen",
     "Twenty",
     "Twenty-One",
     "Twenty-Two",
     "Twenty-Three",
     "Twenty-Four",
     "Twenty-Five",
     "Twenty-Six",
     "Twenty-Seven",
     "Twenty-Eight",
     "Twenty-Nine",
     "Thirty"};


void dohands(hour,minute,oldhour,oldminute)
int hour, minute,oldhour,oldminute;
{
   int x1=160, y1=106, x2, y2;
   int hourbase=50, minutebase=64;
   char minister[33];

   float hourdegrees, oldhourdegrees;
   float minutedegrees, oldminutedegrees;

   minutedegrees=(float)6*minute;
   oldminutedegrees=(float)6*oldminute;

       /* update the written display first */
       pen_color(0);
       stuffcords[0][0]=x1-(strlen(timestuff[0])*4);
       move_to(stuffcords[0][0],stuffcords[0][1]);
       plots(timestuff[0]);
       stuffcords[1][0]=x1-(strlen(timestuff[1])*4);
       move_to(stuffcords[1][0],stuffcords[1][1]);
       plots(timestuff[1]);

       switch(minute)
       {
          case 0 :  sprintf(timestuff[0],"%s %s",hourstrings[hour],
                                    minutestrings[minute]);break;
          case 15:  sprintf(timestuff[0],"%s after %s",minutestrings[minute],
                                          hourstrings[hour]);break;
          case 30:  sprintf(timestuff[0],"%s %s",hourstrings[hour],
                                    minutestrings[minute]);break;
          case 45: sprintf(timestuff[0],"%s to %s",minutestrings[60-minute],
                                      hourstrings[hour+1]);break;

          default:
                   if(minute==1||minute==59)strcpy(minister,"Minute");
                   else strcpy(minister,"Minutes");
                   if(minute<30)
                     sprintf(timestuff[0],"%s %s after %s",
                                          minutestrings[minute],minister,
                                          hourstrings[hour]);
                   else
                     sprintf(timestuff[0],"%s %s to %s",
                                         minutestrings[60-minute],minister,
                                         hourstrings[hour+1]);
                   }
       sprintf(timestuff[1],"%2d:%2d",hour,minute);
       if(timestuff[1][3]==' ')timestuff[1][3]='0';

       pen_color(3);
       stuffcords[0][0]=x1-(strlen(timestuff[0])*4);
       move_to(stuffcords[0][0],stuffcords[0][1]);
       plots(timestuff[0]);
       stuffcords[1][0]=x1-(strlen(timestuff[1])*4);
       move_to(stuffcords[1][0],stuffcords[1][1]);
       plots(timestuff[1]);


   if(hour==12)hour = 0;
   if(oldhour == 12)oldhour = 0;

   hourdegrees= (float)30*hour;
   hourdegrees+= (float).5*minute;

   oldhourdegrees= (float)30*oldhour;
   oldhourdegrees+= (float).5*oldminute;

       /* erase the old hands */
       pen_color(0);
       x2=x1;
       y2=y1;
       circlepoints(&x2,&y2,minutebase,oldminutedegrees);
       move_to(x1,y1);
       line_to(x2,y2);
       x2=x1;
       y2=y1;
       circlepoints(&x2,&y2,hourbase,oldhourdegrees);
       move_to(x1,y1);
       line_to(x2,y2);

       /* draw the new hands */
       pen_color(2);
       x2=x1;
       y2=y1;
       circlepoints(&x2,&y2,minutebase,minutedegrees);
       move_to(x1,y1);
       line_to(x2,y2);
       pen_color(1);
       x2=x1;
       y2=y1;
       circlepoints(&x2,&y2,hourbase,hourdegrees);
       move_to(x1,y1);
       line_to(x2,y2);

       /* draw a small circle at the center */
       pen_color(3);
       move_to(x1,y1);
       circle(4,3);


}




main()
{

       int x1=160, y1=106, x2,y2,circlebase = 70, letterbase=80;
       int markout= 72, markin = 71;
       int xtemp, ytemp;

       int done = 0;
       int hour = 12, oldhour=12;
       int minute= 0, oldminute = 0;
       char c;
       char numbuf[40];
       int i, xfactor, yfactor=4;
       float hourdegrees;

    /* allow only CGA compatible adapters */
    if(((biosequip() >>4) &3)==3)
    {
        printf("Sorry... Cga Required...\n");
        exit(0);
    }

       setvmode(5);

       /* set the global aspect ratio */
       getvconfig(&_videostuff);
       aspect_rat =
       (float) _videostuff.aspect_v / (float) _videostuff.aspect_h;

       /* outline the screen */

       pen_color(2);
       move_to(0,0);
       box(319,21,0);
       pen_color(1);
       move_to(0,22);
       box(319,191-22,0);


       pen_color(3);
       strcpy(numbuf,"Little Ben(C) 1991 by Bill Buckels");
       xtemp = x1-(strlen(numbuf)*4);
       move_to(xtemp,2);
       plots(numbuf);
       pen_color(1);
       strcpy(numbuf,"Most Keys and Arrows Hot-Esc Exits");
       xtemp = x1-(strlen(numbuf)*4);
       move_to(xtemp,10);
       plots(numbuf);
       pen_color(2);
       strcpy(numbuf,"Made In Canada");
       xtemp = x1-(strlen(numbuf)*4);
       move_to(xtemp,192);
       plots(numbuf);



       /* do all the small marks */
       for(i=0;i<60;i++)
       {
         hourdegrees= (float)6*i;
         x2 = x1;
         y2 = y1;
         xtemp = x1;
         ytemp = y1;

         circlepoints(&x2,&y2,markin,hourdegrees);
         if(i%5==0)
         {
            pen_color(1);
            circlepoints(&xtemp,&ytemp,markout+yfactor,hourdegrees);
            }
         else
         {
           circlepoints(&xtemp,&ytemp,markout,hourdegrees);
           pen_color(2);
           }
         move_to(x2,y2);
         line_to(xtemp, ytemp);
         }

       /* do the clock face */
       pen_color(3);
       move_to(x1,y1);
       circle(circlebase,3);


       /* put on the numbers */
       for(i=1;i<13;i++)
       {
         sprintf(numbuf,"%d",i);
         xfactor = strlen(numbuf)*4;
         hourdegrees= (float)30*i;
         x2 = x1;
         y2 = y1;
         circlepoints(&x2,&y2,letterbase,hourdegrees);
         move_to(x2-xfactor,y2-yfactor);

         if(i%3==0)pen_color(2);
         else pen_color(1);

         plots(numbuf);
         }

       /* set the hands with the start value */
       strcpy(timestuff[0],"");
       strcpy(timestuff[1],"");
       dohands(hour,minute,oldhour,oldminute);

       do
       {
        /* we can put a timer loop in here */
        if(kbhit())
        {
            switch(getch())
            {
             case 27: setvmode(3);exit(0);

             case 0: c=getch();
                     if(c!=UPARROW)
                       if(c!=DOWNARROW)
                         if(c!=LEFTARROW)
                           if(c!=RIGHTARROW)
                                         break;
                     oldhour=hour;
                     oldminute=minute;


                     if(c==DOWNARROW)hour++;
                     if(c==UPARROW)hour--;

                      if(c==RIGHTARROW)
                      {
                        minute=(minute/5)*5; /* truncate to even intervals */
                        minute+=5;
                        if(minute>59)
                        {
                        minute-=60;
                        hour++;
                        }
                        }

                      if(c==LEFTARROW)
                      {
                      minute=(minute/5)*5;
                      minute-=5;
                      if(minute<0)
                      {
                       minute+=60;
                       hour--;
                       }
                       }

                     if(hour>12)hour=1;
                     if(hour<1)hour=12;

                     dohands(hour,minute,oldhour,oldminute);
                     break;


             default: oldminute=minute;
                      oldhour  =hour;
                      minute++;
                      if(minute>59)
                      {
                        minute=0;
                        hour++;
                        if(hour>12)hour=1;
                        }
                      dohands(hour,minute,oldhour,oldminute);
                      }
                    }
       }
       while(!(done));
       setvmode(3);
       exit(0);

}





