// Copyright 1993-5 by Jon Dart.  All Rights Reserved.

#include "stdafx.h"
#include "clock.h"
#include "display.h"
#include "globals.h"
#include "resource.h"

Clock::Clock( HWND parent )
: pWin(parent), running(TRUE), side_to_move(White), dir(Up)
{
    limit[White] = limit[Black] = 0;
    reset();
}

Clock::~Clock()
{
}

void Clock::reset()
{
     etime[White] = etime[Black] = 0;
     last_start[White] = time(NULL);
     show_time(White);
     show_time(Black);
     was_reset = TRUE;
     running = TRUE;
     stopped = FALSE;
     time_up = FALSE;
}

void Clock::start( const ColorType side )
{
     const ColorType oside = OppositeColor(side);
     if (!was_reset)
     {
        etime[oside] += time(NULL) - last_start[oside];
        show_time(oside);
     }
     was_reset = FALSE;
     last_start[side] = time(NULL);
     side_to_move = side;
     running = TRUE;
     stopped = FALSE;
}

void Clock::pause()
{
     etime[side_to_move] += time(NULL) - last_start[side_to_move];
     show_time(side_to_move);
     running = FALSE;
}

void Clock::resume()
{
     running = TRUE;
     last_start[side_to_move] = time(NULL);
}

void Clock::stop()
{
     running = FALSE;
     stopped = TRUE;
}

// This is only really meaningful when "counting down":
time_t Clock::time_left( const ColorType side )
{
     time_t elapsed = elapsed_time(side) + time(NULL) - 
        last_start[side];
     elapsed = (limit[side] > elapsed) ? 
        limit[side] - elapsed : 0;
     return elapsed;
}


void Clock::update()
{
   if (running)
   {
       time_t elapsed = elapsed_time(side_to_move) + time(NULL) - 
                last_start[side_to_move];
       time_t display_time = elapsed;   
       if (dir == Down)
          display_time = (limit[side_to_move] > elapsed) ? 
                          limit[side_to_move] - elapsed : 0;
       Display::show_time(pWin, display_time, side_to_move);
       if (dir == Down && display_time == 0 && !time_up)
       {
          time_up = TRUE;
          etime[side_to_move] = elapsed;
          stop(); // prevent further updates
          AfxGetMainWnd()->SendMessage(WM_COMMAND,ID_LOSSONTIME,0L);
       }
   }
}

void Clock::count_up()
{
    dir = Up;
}

void Clock::count_down(time_t lim, const ColorType side)
{
    dir = Down; 
    limit[side] = lim;
    etime[side] = 0;
}

void Clock::show_time( ColorType side )
{
    time_t elapsed = elapsed_time(side);
    if (dir == Down)
        elapsed = (limit[side] > elapsed) ? 
                   limit[side] - elapsed : 0;
    Display::show_time(pWin,elapsed,side);
}
