//-----------------------------------------------------------------------------
///
/// \brief  Class for RTC
///
/// \date   20121107
/// \author Maximilian Seesslen <development@seesslen.net>
///
//-----------------------------------------------------------------------------


//---Includes------------------------------------------------------------------


#include <biwak/rtc.hpp>
#include <biwak/biwak.h>            // assert
#include <lepto/time.h>             // Time Macros
#include <string.h>                 // memset
#include <stdint.h>                 // uint8_t
#include <sys/time.h>               // gettimeofday

#include <time.h>                   // localtime


//---Implementation------------------------------------------------------------


//static time_t rawtime;
static struct tm * timeinfo = NULL;
static struct timeval timeStamp;
int rtcKeeper;

static void updateTime()
{
   //time (&rawtime);
   //timeinfo = localtime (&rawtime);

   gettimeofday(&timeStamp, NULL);
   timeinfo = localtime (&timeStamp.tv_sec);

   return;
}


CRtc::CRtc()
{
}


CRtc::~CRtc()
{
}


int CRtc::init()
{
   return(0);
}


void CRtc::getTime( int &hour, int &min, int &sec /*, uint8_t &subsec*/) const
{
   updateTime();
   hour=timeinfo->tm_hour;
   min=timeinfo->tm_min;
   sec=timeinfo->tm_sec;
   return;
}


void CRtc::getDate( int &year, int &month, int &day) const
{
   updateTime();
   year=timeinfo->tm_year + 1900;
   month=timeinfo->tm_mon + 1;
   day=timeinfo->tm_mday;

   return;
}


void CRtc::getTime( int &hour, int &min, int &sec, int &msec) const
{
   updateTime();
   hour=timeinfo->tm_hour;
   min=timeinfo->tm_min;
   sec=timeinfo->tm_sec;
   msec=timeStamp.tv_usec/1000;

   return;
}


int CRtc::setTime( int8_t hour, int8_t min, int8_t sec)
{
   return(-1);
}


void CRtc::setRelativeTime(int relHour, int relMin, int relSec)
{
   return;
}

int CRtc::setDate( int16_t year, int8_t month, int8_t day)
{
   return(-1);
}


uint32_t CRtc::getMSec()
{
   uint8_t hour=0, min=0, sec=0, subsec=0;

    return( getMSec( hour, min, sec, subsec ) );
}


uint32_t CRtc::getMSec( uint8_t hour, uint8_t min, uint8_t sec, uint8_t subsec )
{
    // Subsecond 0xff..00-inc second-0xff..0x00
    return( ( ( ( ( ( (
          hour
        * MIN_PER_HOUR ) + min )
        * SEC_PER_MIN ) + sec )
        * SUBSEC_PER_SEC ) + ( 0xFF - subsec ) )
        * MSEC_PER_SUBSEC
        );
}


uint32_t CRtc::getSec()
{
   updateTime();

   return(getSec(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec));
}


uint32_t CRtc::getSec( uint8_t hour, uint8_t min, uint8_t sec) /* static */
{
    return(
          (hour * SEC_PER_HOUR )
         +(min * SEC_PER_MIN)
         + sec
        );
}


bool CRtc::isValid()
{
   return( true );
}


//---fin-----------------------------------------------------------------------
