// ---------------------------------------------------------------------------
// - cclk.cxx                                                                -
// - standard system library - c time function implementation                -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - 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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2008 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "cclk.hpp"
#include "cclk.hxx"

namespace afnix {

  // pause for a certain time

  void c_sleep (const long time) {
    struct timespec tval;
    if (time <= 0) return;
    long sval = time / 1000;
    long nval = (time % 1000) * 1000000;
    tval.tv_sec  = sval;
    tval.tv_nsec = nval;
    nanosleep (&tval, NULL);
  }

  // return the machine time stamp

  t_octa c_stamp (void) {
    struct timeval tval;
    if (gettimeofday (&tval, NULL) == -1) return 0;
    t_octa result = (((t_octa) tval.tv_sec) << 32) | (t_octa) tval.tv_usec;
    return result;
  }

  // return the atc time in seconds since the origin

  t_long c_time (void) {
    struct timeval tval;
    if (gettimeofday (&tval, NULL) == -1) return -1;
    t_long result = (t_long) tval.tv_sec + AFNIX_ATC_EPOCH;
    return result;
  }

  // return the timezone in seconds

  t_long c_tzone (void) {
    // get the time at the call
    struct timeval tval;
    if (gettimeofday (&tval, NULL) == -1) return 0;
    time_t time = tval.tv_sec;
    // initialize local and utc structure
    struct tm utm;
    struct tm ltm;
    if (gmtime_r    (&time, &utm) == NULL) return 0;
    if (localtime_r (&time, &ltm) == NULL) return 0;
    // compute local time in second
    t_long lts = (ltm.tm_yday * 86400) + (ltm.tm_hour * 3600) + 
                 (ltm.tm_min  * 60) + ltm.tm_sec;
    // compute universal time in second
    t_long uts = (utm.tm_yday * 86400) + (utm.tm_hour * 3600) + 
                 (utm.tm_min  * 60) + utm.tm_sec;
    // compute timezeone
    return (lts - uts);
  }
}
