/************************************************************************
* retroLP solves linear programs using the simplex method.             *
* Copyright (C) 2001, 2003, 2005 Gavriel Yarmish & Richard Van Slyke.  *
* For further information, and gpl licensing, see the end of this file.*
************************************************************************/


// long_clock.cpp 3/8/05
// Typically, the system clock() measures only 
// to a little more than 1/2 hour, or a little 
// more than an hour depending on whether the 
// clock_t is taken to be signed or not. In
// any case it wraps around.Long_clock is designed
// to measure an interval indefinitely long interval
// as long as it is called before the sytem
// clock wraps around and or goes "negative."
// If this is not done the
// long_clock routine MAY return an error string.
// Otherwise it returns a string of the form:
// ..hhhh:mm:ss where ss is seonds, mm is minutes,
// and ...hhhh is hours. The timer is intitialized
// when it is instantiated (constructed), or it 
// can be reinitialized using resetLongClock.

#include <time.h>
#include <math.h>
#include <iostream>
#include "long_clock.h"

////////////////////////////////////////
// Default constructor
LongClock::LongClock()
{
  resetLongClock();
  range = 0;
  out_of_range = false;
}

////////////////////////////////////////
// Check to see if reinitialization is needed
bool LongClock::reinitLongClock()
{
  if(range == 0)
  {
    range = static_cast<unsigned long>(pow(2, 8*sizeof(clock_t)-1)) -1;
  }
  // Call clock()
  tics = static_cast<long>(clock()-clock0);
  // Check for wrap around
  if(tics < 0){ out_of_range = true;}
  // Check if past half on range
  if(tics > range/2)
  {
    // Update hours, minutes, and seconds
    tm = seconds + tics/CLOCKS_PER_SEC;
    seconds = tm%60;
    tm = minutes + tm/60;
    minutes = tm%60;
    hours  = hours + tm/60;
    if(h > 999)out_of_range = true;
    clock0 = clock();
    // FOR DEBUGGIN ONLY; TAKE OUT
    printf("reinitialized\n");
    return true;
  }
  else return false;
  }
////////////////////////////////////////
// Check to see if reinitialization is needed
// This version used for pivot clock
long  LongClock::reinitLongClock(long pt)
{
  if(range == 0)
  {
    range = static_cast<unsigned long>(pow(2, 8*sizeof(clock_t)-1)) -1;
  }
  // Check for wrap around
  if(pt < 0){ out_of_range = true;}
  // Check if past half on range
  if(pt > range/2)
  {
    // Update hours, minutes, and seconds
    tm = seconds + pt/CLOCKS_PER_SEC;
    seconds = tm%60;
    tm = minutes + tm/60;
    minutes = tm%60;
    hours  = hours + tm/60;
    if(h > 999)out_of_range = true;
    pt = 0;
    // FOR DEBUGGIN ONLY; TAKE OUT
    printf("reinitialized\n");
  }
  return pt;
  }

////////////////////////////////////////
// This function returns a string with current running time
char *  LongClock::getInterval()
{
 static char sbuffer[10];
// Check to see if range calculated
  if(range == 0)
  {
    range = static_cast<unsigned long>(pow(2, 8*sizeof(clock_t)-1)) -1;
  }
  // Call clock()
  tics = static_cast<long>(clock()-clock0);
  // Check for wrap around
  if(tics < 0){ out_of_range = true;}
  // Update hours, minutes, and seconds
  tm = seconds + tics/CLOCKS_PER_SEC;
  s = tm%60;
  tm = minutes + tm/60;
  m = tm%60;
  h  = hours + tm/60;
  if(h > 999)out_of_range = true;
  // Put out time string if valid; error message if not
  if(out_of_range) 
  {
    sprintf(sbuffer, "Too much!\0");
  }
  else
  {  
    sprintf(sbuffer, "%3d:%#02d:%#02d",h, m, s);
  }
  // Check if past half on range
  if(tics > range/2) // If half of range used up reinitiate
  {
    clock0 = clock();
    seconds = s;
    minutes = m;
    hours = h; 
    // FOR DEBUGGIN ONLY; TAKE OUT
    printf("reinitialized\n");
  }

  return sbuffer;
}

////////////////////////////////////////
// This function returns a string with current running time
// this version used for pivot clock
// It does not reinitialize; it only gives output.
char *  LongClock::getInterval(long pt)
{
  static char sbuffer[10];
  // Update hours, minutes, and seconds
  tm = seconds + pt/CLOCKS_PER_SEC;
  seconds = tm%60;
  tm = minutes + tm/60;
  minutes = tm%60;
  hours  = hours + tm/60;
  if(hours > 999)out_of_range = true;
  // Put out time string if valid; error message if not
  if(out_of_range) 
  {
    sprintf(sbuffer, "Too much!\0");
  }
  else
  {  
    sprintf(sbuffer, "%3d:%#02d:%#02d",hours, minutes, seconds);
  }
  return sbuffer;
}

////////////////////////////////////////
void LongClock::resetLongClock()
{
  hours = minutes = seconds = 0;
  clock0 = clock();
}

/************************************************************************
* retroLP solves linear programs using the simplex method.             *
* Copyright (C) 2001, 2003, 2005 Gavriel Yarmish & Richard Van Slyke.  *
*                                                                      *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or    *
* (at your option) any later version.                                  *
*                                                                      *
* This program is distributed in the hope that it will be useful,      *
* but WITHOUT ANY WARRANTY; without even the implied warranty of       *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
* GNU General Public License for more details.                         *
*                                                                      *
* You should have received a copy of the GNU General Public License    *  
* along with this program; if not, write to the Free Software          *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,           *
*                                                                      *
************************************************************************/
