// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1996
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        rfc1123.h
// 
// Purpose:     
// 
// Created:     12 Sep 1996   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// $Id: robustdate.h,v 1.4 1997/02/13 12:32:28 gorasche Exp $
// 
// $Log: robustdate.h,v $
// Revision 1.4  1997/02/13 12:32:28  gorasche
// changes for WIN32
// - enums cast
// - types.h included for bool type
//
// Revision 1.3  1996/12/09 18:35:11  tvollmer
// comsumed -> consumed
//
// Revision 1.2  1996/12/09 13:28:48  tvollmer
// added int consumed() (always positive)
//
// Revision 1.1  1996/11/27 16:27:43  tvollmer
// Initial revision
//
// Revision 1.1  1996/11/27 13:03:55  tvollmer
// Initial revision
//
// 
// </file> 
#ifndef hg_utils_rfcdate_h
#define hg_utils_rfcdate_h

#include "verbose.h"

#include <time.h>
#include "types.h"

class TMDate : public tm {
public:
   TMDate() ;

   int errpos() const { return errpos_; }
   int consumed() const {return  (errpos_ < 0 ? -errpos_ : errpos_) ; }
   bool ok() const { return errpos_<0; }
   operator void*() const { return (void*)ok(); }
   bool operator !() const { return !ok(); }

protected:
   void set_error_(int pos) { errpos_=pos; }

private:
   int errpos_ ;

public:
   static const char* version1 ;
} ;
static const char* hg_utils_rfcdate_version = TMDate::version1 ;



class DateUtils
{
public:
    
    enum WkDay { Sun, Mon, Tue, Wed, Thu, Fri, Sat } ;
    enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } ;
    static int weekday(const char* s, int len, tm&) ;
    static int wkday(const char* s, int len, tm&) ;
    static int date1(const char* s, int len, tm&) ;
    static int date2(const char* s, int len, tm&) ;
    static int date3(const char* s, int len, tm&) ;
    static int date4(const char* s, int len, tm&) ;
    static int time(const char* s, int len, tm&) ;
    static int month(const char* s, int len, tm&) ;
    static void incr_int_(int&, char) ;
    
    static Verbose verbose;
    static const char* version1;
};

inline void DateUtils :: incr_int_(int& i, char c) {
   i *= 10 ;
   i += c - '0' ;
}

static const char* hg_utils_dateutils_version = DateUtils::version1 ;

class RFC1123 : virtual public TMDate , public DateUtils
{
public:
   static Verbose verbose ;

public:
   RFC1123() {}
   RFC1123 (const char*, int) ;

    
protected:
   int parse_(const char* s, int len) ;

public:
   static const char* version1 ;
} ;
static const char* hg_utils_rfc1123_version = RFC1123::version1 ;

inline RFC1123 :: RFC1123 (const char* s, int len) {
   set_error_(-parse_(s, len)) ;
}



class RFC1036 : public virtual TMDate, public DateUtils
{
public:
   static Verbose verbose ;

public:
   RFC1036() {}
   RFC1036(const char*, int) ;

    
protected:
   int parse_(const char* s, int len) ;

public:
   static const char* version1 ;
} ;
static const char* hg_utils_rfc1036_version = RFC1036::version1 ;

inline RFC1036 :: RFC1036 (const char* s, int len) {
   set_error_(-parse_(s, len)) ;
}


class AscTimeDate : virtual public TMDate, public DateUtils
{
public:
   static Verbose verbose ;

public:
   AscTimeDate() {}
   AscTimeDate(const char*, int) ;

    
protected:
   int parse_(const char* s, int len) ;

public:
   static const char* version1 ;
} ;
static const char* hg_utils_asctimedate_version = AscTimeDate::version1 ;

inline AscTimeDate :: AscTimeDate (const char* s, int len) {
   set_error_(-parse_(s, len)) ;
}

class HWDate : virtual public TMDate, public DateUtils
{
public:
   static Verbose verbose ;

public:
   HWDate() {}
   HWDate(const char*, int) ;

    
protected:
   int parse_(const char* s, int len) ;

public:
   static const char* version1 ;
} ;
static const char* hg_utils_hwdate_version = HWDate::version1 ;

inline HWDate :: HWDate (const char* s, int len) {
   set_error_(-parse_(s, len)) ;
}


class RobustDate : virtual public RFC1036 , virtual public RFC1123 ,  virtual public AscTimeDate, virtual HWDate
{
public:   
   RobustDate(const char* w ,int l );
    static const char* version1 ;
};
static const char* hg_utils_robustdate_version = RobustDate::version1 ;

#endif
