/*
 * Copyright(C) 2004 Проект ИОК
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто Про.
 */

/*!
 * \file $RCSfile$
 * \version $Revision: 151182 $
 * \date $Date:: 2017-01-12 12:12:28 +0300#$
 * \author $Author: dim $
 *
 * \brief Класс для работы со временем.
 */

#ifndef __DATE_H
#define __DATE_H

#include <string>
#ifdef _WIN32
    #include <windows.h>
#endif // _WIN32
#ifdef UNIX
    #include "CSP_WinCrypt.h"
    #include <sys/time.h>
#endif // UNIX
#include "ASN1Exceptions.h"

#ifdef ANDROID
namespace std {
	typedef basic_string<wchar_t> wstring;
}
#endif

class date_exception : public CAException
{
public:
    explicit date_exception( const char msg[] = "Invalid date/time value.", const char *f = NULL, int l = 0 )
	: CAException( msg, f, l ) {}
};

class CACMPT_Date;

class CACMPT_Period
{
public:
    explicit CACMPT_Period();
    explicit CACMPT_Period( const char* alya_generalizedTime);
    CACMPT_Period( const CACMPT_Period& );
    static CACMPT_Period from_normal( const char *date );

    std::string tostring() const;
    std::wstring towstring() const;

    std::string getGeneralizedTime() const;

    CACMPT_Period& operator=( const CACMPT_Period& src);
    void swap( CACMPT_Period &src ) throw();

    friend bool operator==( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
    friend bool operator!=( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
    friend bool operator<=( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
    friend bool operator>=( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
    friend bool operator<( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
    friend bool operator>( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
    friend CACMPT_Date& operator +=( CACMPT_Date &lhs, const CACMPT_Period& rhs);
    friend CACMPT_Date& operator -=( CACMPT_Date &lhs, const CACMPT_Period& rhs);
    friend CACMPT_Period& operator -=( CACMPT_Period &lhs, const CACMPT_Period& rhs);
    friend CACMPT_Period& operator +=( CACMPT_Period &lhs, const CACMPT_Period& rhs);

    friend CACMPT_Period& operator *=( CACMPT_Period &lhs, unsigned rhs);
    friend CACMPT_Period& operator /=( CACMPT_Period &lhs, unsigned rhs);
    friend CACMPT_Period& operator %=( CACMPT_Period &lhs, unsigned rhs);

    friend unsigned operator / ( const CACMPT_Period &lhs, const CACMPT_Period &rhs );
    friend unsigned operator % ( const CACMPT_Period &lhs, const CACMPT_Period &rhs );

    friend CACMPT_Period operator -( const CACMPT_Date &lhs, const CACMPT_Date& rhs);

    static const CACMPT_Period OneYear;
    static const CACMPT_Period OneMonth;
    static const CACMPT_Period OneDay;
    static const CACMPT_Period OneHour;
    static const CACMPT_Period OneMinute;
    static const CACMPT_Period OneSecond;
    static const CACMPT_Period OneMilli;
    static const CACMPT_Period OneMicro;
    //сделал puplic - иначе не компилилось на VS2005
    bool operator>( const CACMPT_Date& rhs) const;
private:
    CACMPT_Period( unsigned secs, unsigned micro = 0 );    
    unsigned int high_;
    unsigned int low_;
};

class CACMPT_Date
{
public:
    explicit CACMPT_Date( time_t time = 0, unsigned int micro = 0);
    explicit CACMPT_Date( const std::string& generalizedTime);
    CACMPT_Date( timeval tval);
    CACMPT_Date( const CACMPT_Date& time);

    static bool is_valid_date( const std::string& generalizedTime);

    unsigned int year() const;
    unsigned int month() const;
    unsigned int day() const;
    unsigned int hour() const;
    unsigned int minute() const;
    unsigned int second() const;
    unsigned int millisecond() const;
    unsigned int microsecond() const;

    std::string getGeneralizedTime() const;
    time_t getTime() const;
    timeval getTimeval() const;

    std::string tostring() const;
    std::wstring towstring() const;

    CACMPT_Date& operator=( const CACMPT_Date& src);

    static CACMPT_Date Now();

    friend bool operator==( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
    friend bool operator!=( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
    friend bool operator<=( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
    friend bool operator>=( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
    friend bool operator<( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
    friend bool operator>( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
    friend CACMPT_Date& operator +=( CACMPT_Date &lhs, const CACMPT_Period& rhs);
    friend CACMPT_Date& operator -=( CACMPT_Date &lhs, const CACMPT_Period& rhs);
    friend bool CACMPT_Period::operator>( const CACMPT_Date& rhs) const;
    friend CACMPT_Period operator -( const CACMPT_Date &lhs, const CACMPT_Date& rhs);

    CACMPT_Date( FILETIME filetime);
    CACMPT_Date( SYSTEMTIME systemtime);
    FILETIME getFileTime() const;

private:
    unsigned int high_;
    unsigned int low_;
};

bool operator==( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
bool operator!=( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
bool operator<=( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
bool operator>=( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
bool operator<( const CACMPT_Date& lhs, const CACMPT_Date& rhs);
bool operator>( const CACMPT_Date& lhs, const CACMPT_Date& rhs);

bool operator==( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
bool operator!=( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
bool operator<=( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
bool operator>=( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
bool operator<( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
bool operator>( const CACMPT_Period& lhs, const CACMPT_Period& rhs);
CACMPT_Date& operator +=( CACMPT_Date &lhs, const CACMPT_Period& rhs);
CACMPT_Date& operator -=( CACMPT_Date &lhs, const CACMPT_Period& rhs);

CACMPT_Period& operator +=( CACMPT_Period &lhs, const CACMPT_Period& rhs);
CACMPT_Period& operator -=( CACMPT_Period &lhs, const CACMPT_Period& rhs);

CACMPT_Period& operator *=( CACMPT_Period &lhs, unsigned rhs);
CACMPT_Period& operator /=( CACMPT_Period &lhs, unsigned rhs);
CACMPT_Period& operator %=( CACMPT_Period &lhs, unsigned rhs);

CACMPT_Period operator -( const CACMPT_Date &lhs, const CACMPT_Date& rhs);
#endif //__DATE_H
