/****************************** Chess clock program ************************
Full-featured chess clock: Digital displays of time
			   Move counter
			   White and Black clocks separately settable
			   Times from 1 minute to 99 hours
			   Low-time warning (optional)
			   Flashing "tick" indicator (optional)
****************************************************************************/


#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <dos.h>
#include "oscr.hpp"
#include "chessclk.hpp"

void main()
{
   randomize();
   opening_screen();
   play();
}

void CountdownTimer::clock_on()
{
   time_t prev_sec;
   int ch;

      if( p == WHITE_ )
	 text_color = LIGHTBLUE;
      else
	 text_color = DARKGRAY;

      setcolor( text_color );
      settextstyle( TRIPLEX_FONT, HORIZ_DIR, 5 );
      settextjustify( LEFT_TEXT, TOP_TEXT );

      startn_t = time ( NULL );  //Click on stopwatch.
      gotoxy( 60 * p + 1, 14 );
      outtextxy( NAME_POS * p, 100, player [p] );
      display_time();  //Otherwise initial time not displayed...

      while( !( ch = kbhit() ) )
	 {
	 prev_sec = seconds;
	 if( running_flag) //Is this 2nd or later lap?
	    interval_t = time( NULL ) - startn_t;
	 else
	    interval_t = time( NULL ) - start_t;
	 running_t = total_seconds - interval_t;
	 convert( running_t );

	 if( seconds - prev_sec )
	    {
	    display_time();

	    if( !seconds )
	       if( minutes == warning )
		  if( !hours )
		     if( time_warning_flag )
			blatt();

	    if( visual_ticking_flag ) // Show blinking box ticks?
	       {
	       setfillstyle( random ( PATTERNS ), random ( COLORS ) );
	       setcolor ( random ( COLORS ) );
	       setlinestyle( SOLID_LINE, 0xFFF, NORM_WIDTH );
	       bar( X_C - RADIUS, Y_C - RADIUS,
		    X_C + RADIUS, Y_C + RADIUS );
	       }
	    }

	 if( timeout() )
	    exit_();
	 }

      ch = getch();
      if( ch == ESC )
	 exit__();  // Quit.

      total_seconds = hours * 3600 + minutes * 60 + seconds;
      running_flag = ON;  // Remember that clock was already running.

      return;

}

void CountdownTimer::display_moves()
{
   char buf[ 5 ];
   static char ebuf[ 5 ];

      if( moves > 1 )
	 {
	 setcolor( WHITE );
	 settextstyle( TRIPLEX_FONT, HORIZ_DIR, 1 );
	 settextjustify( CENTER_TEXT, TOP_TEXT );
	 outtextxy( MOVES_X, MOVES_Y, ebuf );
	 }

      sprintf( buf, "%003d", moves );
      sprintf( ebuf, buf );
      setcolor( LIGHTRED );
      settextstyle( TRIPLEX_FONT, HORIZ_DIR, 1 );
      settextjustify( CENTER_TEXT, TOP_TEXT );
      outtextxy( MOVES_X, MOVES_Y, buf );
      
      return;
}

void graphics_setup( int background_color )
{
   int grdriver = VGA,
       grmode = VGAHI;

       registerfarbgidriver( EGAVGA_driver_far );
       registerfarbgifont( gothic_font_far );
       registerfarbgifont( triplex_font_far );
       initgraph( &grdriver, &grmode, "" );
       setbkcolor( background_color );

}

void exit__()
{
      closegraph();
      exit( QUIT );
}

	/***************Routine to erase old numbers*************/
void CountdownTimer::erase_numbers()
{
      setcolor ( WHITE ); 

      if( seconds == 59 )
	 outtextxy( p * BLK_TIME, Y_TIMEPOS, line_clear );
      else
	 if( seconds == 9 || seconds == 19 || seconds == 29
	     || seconds == 39 || seconds == 49 )
		outtextxy( p * BLK_TIME + POS1_OFFSET, Y_TIMEPOS,
			   line_clear + 6 );
	  else
	     outtextxy( p * BLK_TIME + POS_OFFSET, Y_TIMEPOS,
			line_clear + 7 ); 

	 return;

}


void play()
{
   int hrs,
       min;
   char inputstr[ MAXLEN ],
	inp;

      clrscr();

      textcolor ( LIGHTCYAN );
      cprintf( "\n                              WHITE hours: " );
      gets( inputstr );
      hrs = atoi( inputstr );
      cprintf( "                              WHITE minutes: " );
      gets( inputstr );
      min = atoi( inputstr );
      CountdownTimer t1( hrs, min, WHITE_ );

      textcolor( RED );
      cprintf( "\n                              BLACK hours: " );
      gets( inputstr );
      hrs = atoi( inputstr );
      cprintf( "                              BLACK minutes: " );
      gets( inputstr );
      min = atoi( inputstr );
      CountdownTimer t2( hrs, min, BLACK_ );

      textcolor( YELLOW );
      cprintf( "\n\n                         Enable flashing clock ticks? " );
      inp = getche();
      if( inp == 'y' || inp == 'Y' )
	 t1.visual_ticking_flag = t2.visual_ticking_flag = ON;
      else
	 t1.visual_ticking_flag = t2.visual_ticking_flag = OFF;

      cprintf( "\n                                                      Enable time warning? " );
      inp = getche();
      if( inp == 'y' || inp == 'Y' )
	 {
	 t1.time_warning_flag = t2.time_warning_flag = ON;
	 cprintf( "                                                          At how many minutes? " );
	 gets( inputstr );
	 t1.warning = t2.warning = atoi( inputstr );
	 }
      else
	 t1.time_warning_flag = t2.time_warning_flag = OFF;

      textcolor( GREEN | BLINK );
      _setcursortype( _NOCURSOR );
      printf( "\n\n\n\n\n\n\n\n\n\n\n\n" );
      cprintf( "                             PRESS A KEY TO BEGIN" );
      while ( !getch() );

      graphics_setup( WHITE );

      t1.initialize_clock();
      t1.moves++;
      t1.display_moves();
      t1.clock_on();
      t2.initialize_clock();
      t2.clock_on();

      while ( PLAY )
	 {
	 t1.moves++;  
	 t1.display_moves();
	 t1.clock_on();
	 t2.clock_on(); 
	 }

} // End play()


void opening_screen()
{
   char topline[] = "Chess Clock",
	by_line[] = "by",
	name_line[] = "M\\Cooper",
	endline[] = "PRESS A KEY";

      graphics_setup( CYAN );
      settextstyle( GOTHIC_FONT, HORIZ_DIR, HEADLINE_SIZE );
      settextjustify( CENTER_TEXT, CENTER_TEXT );
      setcolor( MAGENTA );
      outtextxy( TOPX, TOPY, topline );

      settextstyle( TRIPLEX_FONT, HORIZ_DIR, BY_LINE_SIZE );
      setcolor( BLUE );
      outtextxy( BY_LINE_X, BY_LINE_Y, by_line );

      setfillstyle( BAR_PATTERN, BAR_COLOR );
      bar3d( BAR_LEFT, BAR_TOP, BAR_RIGHT, BAR_BOTTOM, BAR_DEPTH, BAR_TOPFLAG );

      setfillstyle( PIE_PATTERN, PIE_COLOR );
      pieslice( PIE1_X, PIE_Y, PIE_STARTANGLE, PIE_ENDANGLE, PIE_RADIUS );
      pieslice( PIE2_X, PIE_Y, PIE_STARTANGLE, PIE_ENDANGLE, PIE_RADIUS );
      circle( PIE1_X, PIE_Y, CIRC_RAD );
      circle( PIE2_X, PIE_Y, CIRC_RAD );
      line( LINE1_X, LINE_Y1, LINE1_X, LINE_Y2 );
      line( LINE2_X, LINE_Y1, LINE2_X, LINE2_Y2 );
      setfillstyle( PIE_PATTERN, WHITE );
      bar( B1_LEFT, B1_TOP, B1_RIGHT, B_BOTTOM );
      bar( B2_LEFT, B2_TOP, B2_RIGHT, B_BOTTOM );


      settextstyle( TRIPLEX_FONT, HORIZ_DIR, NAME_LINE_SIZE );
      setcolor( BLUE );
      outtextxy( NAME_LINE_X, NAME_LINE_Y, name_line );

      sleep( DELAY );

      settextstyle( TRIPLEX_FONT, HORIZ_DIR, ENDLINE_SIZE );
      setcolor( RED );
      outtextxy( ENDLINE_X, ENDLINE_Y, endline );

      getch();
      closegraph();

      return;
}


