#ifdef _MSC_VER
#pragma once
#endif

#ifndef CKG_LIB_EVENTMANAGER_DATETIME_H_
#define CKG_LIB_EVENTMANAGER_DATETIME_H_

/** Includes ***********************/
#include <time.h>

/** Macros *************************/
#pragma warning(disable:4514)
#define CKG_LIB_ALLOW_NON_CONST_OPERATORS 1

/** Forward Declarations ***********/
namespace CKG
{
    namespace Lib
    {
        namespace EventManager
        {
            /*!
                \brief  
            */
            class DateTime
            {
            public:
                /** Construction/Destruction **/
                inline DateTime();
                inline DateTime(const time_t &time);
                inline DateTime(const struct tm *tmStruct);
                inline ~DateTime();

                /** Accessors **/
                inline const time_t &GetTime() const;

                /** Overloads **/
                inline const DateTime operator+(const DateTime &rhs) const;
                inline const DateTime operator-(const DateTime &rhs) const;
                
            #if CKG_LIB_ALLOW_NON_CONST_OPERATORS
                inline DateTime &operator+(const DateTime &rhs);
                inline DateTime &operator-(const DateTime &rhs);
            #endif

            protected:

            private:
                time_t      mTime;
            };
        }
    }
}

/** Implementations ****************/
namespace CKG
{
    namespace Lib
    {
        namespace EventManager
        {
            /*!
                \brief  Default Constructor
            */
            DateTime::DateTime()
                : mTime(0)
            {

            }

            /*!
                \brief  Constructs a DateTime using a time_t

                \param  time    - Time to set
                \return         - none.
            */
            DateTime::DateTime(const time_t &time)
                : mTime(time)
            {

            }

            /*!
                \brief  Constructs a DateTime using a struct tm

                \param  tmStruct    - Time to set
                \return             - none.
            */
            DateTime::DateTime(const struct tm *tmStruct)
                : mTime(0)
            {
                if (tmStruct)
                {
                    mTime = mktime(const_cast<struct tm*>(tmStruct));
                }
            }

            /*!
                \brief  Destroys the DateTime
            */
            DateTime::~DateTime()
            {

            }

            /*!
                \brief  Get the time

                \return     - Time in time_t
            */
            const time_t &DateTime::GetTime() const
            {
                return mTime;
            }

            /*!
                \brief  Adds 
            */
            const DateTime DateTime::operator+(const DateTime &rhs) const
            {
                return DateTime(mTime + rhs.mTime);
            }

            /*!
                \brief  Subtract DateTime's to get relative time difference

                \param  rhs     - right hand side Time
                \return         - Time delta
            */
            const DateTime DateTime::operator-(const DateTime &rhs) const
            {
                return DateTime(mTime - rhs.mTime);
            }

        #if CKG_LIB_ALLOW_NON_CONST_OPERATORS
            /*!
                \brief  Add times together
            */
            DateTime &DateTime::operator+(const DateTime &rhs)
            {
                mTime += rhs.mTime;
                return *this;
            }

            /*!
                \brief  
            */
            DateTime &DateTime::operator-(const DateTime &rhs)
            {
                mTime = mTime - rhs.mTime;
                return *this;
            }
        #endif
        }
    }
}

/** Undefines **********************/
#undef CKG_LIB_ALLOW_NON_CONST_OPERATORS

#endif
