#ifndef DATE_TIME_DST_RULES_HPP__
#define DATE_TIME_DST_RULES_HPP__

/* Copyright (c) 2002,2003, 2007 CrystalClear Software, Inc.
 * Use, modification and distribution is subject to the 
 * Boost Software License, Version 1.0. (See accompanying
 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 * Author: Jeff Garland, Bart Garst
 * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
 */

/*! @file dst_rules.hpp
  Contains template class to provide static dst rule calculations
*/

#include "boost/date_time/date_generators.hpp"
#include "boost/date_time/period.hpp"
#include "boost/date_time/date_defs.hpp"
#include <stdexcept>

namespace boost {
  namespace date_time {

    enum time_is_dst_result {is_not_in_dst, is_in_dst, 
                             ambiguous, invalid_time_label};


    //! Dynamic class used to caluclate dst transition information
    template<class date_type_, 
             class time_duration_type_>
    class dst_calculator
    {
    public:
      typedef time_duration_type_ time_duration_type;
      typedef date_type_ date_type;

      //! Check the local time offset when on dst start day
      /*! On this dst transition, the time label between
       *  the transition boundary and the boudary + the offset
       *  are invalid times.  If before the boundary then still 
       *  not in dst.  
       *@param time_of_day Time offset in the day for the local time
       *@param dst_start_offset_minutes Local day offset for start of dst
       *@param dst_length_minutes Number of minutes to adjust clock forward
       *@retval status of time label w.r.t. dst
       */
      static time_is_dst_result 
      process_local_dst_start_day(const time_duration_type& time_of_day,
                                  unsigned int dst_start_offset_minutes,
                                  long dst_length_minutes)
      {
        //std::cout << "here" << std::endl;
        if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) {
          return is_not_in_dst;
        }
        long offset = dst_start_offset_minutes + dst_length_minutes;
        if (time_of_day >= time_duration_type(0,offset,0)) {
          return is_in_dst;
        }
        return invalid_time_label; 
      }

      //! Check the local time offset when on the last day of dst
      /*! This is the calculation for the DST end day.  On that day times
       *  prior to the conversion time - dst_length (1 am in US) are still 
       *  in dst.  Times between the above and the switch time are 
       *  ambiguous.  Times after the start_offset are not in dst.
       *@param time_of_day Time offset in the day for the local time
       *@param dst_end_offset_minutes Local time of day for end of dst
       *@retval status of time label w.r.t. dst
       */
      static time_is_dst_result 
      process_local_dst_end_day(const time_duration_type& time_of_day,
                                unsigned int dst_end_offset_minutes,
                                long dst_length_minutes)
      {
        //in US this will be 60 so offset in day is 1,0,0
        int offset = dst_end_offset_minutes-dst_length_minutes;
        if (time_of_day < time_duration_type(0,offset,0)) {
          return is_in_dst;
        }
        if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) {
          return is_not_in_dst;
        }
        return ambiguous;
      }

      //! Calculates if the given local time is dst or not
      /*! Determines if the time is really in DST or not.  Also checks for 
       *  invalid and ambiguous.
       *  @param current_day The day to check for dst
       *  @param time_of_day Time offset within the day to check 
       *  @param dst_start_day  Starting day of dst for the given locality
       *  @param dst_start_offset Time offset within day for dst boundary
       *  @param dst_end_day    Ending day of dst for the given locality
       *  @param dst_end_offset Time offset within day given in dst for dst boundary
       *  @param dst_length lenght of dst adjusment
       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
       */
      static time_is_dst_result 
      local_is_dst(const date_type& current_day,
                   const time_duration_type& time_of_day,
                   const date_type& dst_start_day,
                   const time_duration_type& dst_start_offset,
                   const date_type& dst_end_day,
                   const time_duration_type& dst_end_offset,
                   const time_duration_type& dst_length_minutes)
      {
        unsigned int start_minutes = 
          dst_start_offset.hours() * 60 + dst_start_offset.minutes();
        unsigned int end_minutes = 
          dst_end_offset.hours() * 60 + dst_end_offset.minutes();
        long length_minutes =  
          dst_length_minutes.hours() * 60 + dst_length_minutes.minutes();

        return local_is_dst(current_day, time_of_day,
                            dst_start_day, start_minutes,
                            dst_end_day, end_minutes,
                            length_minutes);
      }

      //! Calculates if the given local time is dst or not
      /*! Determines if the time is really in DST or not.  Also checks for 
       *  invalid and ambiguous.
       *  @param current_day The day to check for dst
       *  @param time_of_day Time offset within the day to check 
       *  @param dst_start_day  Starting day of dst for the given locality
       *  @param dst_start_offset_minutes Offset within day for dst 
       *         boundary (eg 120 for US which is 02:00:00)
       *  @param dst_end_day    Ending day of dst for the given locality
       *  @param dst_end_offset_minutes Offset within day given in dst for dst 
       *         boundary (eg 120 for US which is 02:00:00)
       *  @param dst_length_minutes Length of dst adjusment (eg: 60 for US)
       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
       */
      static time_is_dst_result 
      local_is_dst(const date_type& current_day,
                   const time_duration_type& time_of_day,
                   const date_type& dst_start_day,
                   unsigned int dst_start_offset_minutes,
                   const date_type& dst_end_day,
                   unsigned int dst_end_offset_minutes,
                   long dst_length_minutes)
      {
        //in northern hemisphere dst is in the middle of the year
        if (dst_start_day < dst_end_day) {
          if ((current_day > dst_start_day) && (current_day < dst_end_day)) {
            return is_in_dst;
          }
          if ((current_day < dst_start_day) || (current_day > dst_end_day)) {
            return is_not_in_dst;
          }
        }
        else {//southern hemisphere dst is at begining /end of year
          if ((current_day < dst_start_day) && (current_day > dst_end_day)) {
            return is_not_in_dst;
          }
          if ((current_day > dst_start_day) || (current_day < dst_end_day)) {
            return is_in_dst;
          }
        }

        if (current_day == dst_start_day) {
          return process_local_dst_start_day(time_of_day,
                                             dst_start_offset_minutes,
                                             dst_length_minutes);
        }
      
        if (current_day == dst_end_day) {
          return process_local_dst_end_day(time_of_day,
                                           dst_end_offset_minutes,
                                           dst_length_minutes);
        }
        //you should never reach this statement
        return invalid_time_label;
      }

    };


    //! Compile-time configurable daylight savings time calculation engine
    /* This template provides the ability to configure a daylight savings
     * calculation at compile time covering all the cases.  Unfortunately
     * because of the number of dimensions related to daylight savings
     * calculation the number of parameters is high.  In addition, the
     * start and end transition rules are complex types that specify 
     * an algorithm for calculation of the starting day and ending
     * day of daylight savings time including the month and day 
     * specifications (eg: last sunday in October).
     *
     * @param date_type A type that represents dates, typically gregorian::date
     * @param time_duration_type Used for the offset in the day calculations
     * @param dst_traits A set of traits that define the rules of dst 
     *        calculation.  The dst_trait must include the following:
     * start_rule_functor - Rule to calculate the starting date of a
     *                      dst transition (eg: last_kday_of_month).
     * start_day - static function that returns month of dst start for 
     *             start_rule_functor
     * start_month -static function that returns day or day of week for 
     *              dst start of dst
     * end_rule_functor - Rule to calculate the end of dst day.
     * end_day - static fucntion that returns end day for end_rule_functor
     * end_month - static function that returns end month for end_rule_functor
     * dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U.
     * dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U. 
     * dst_length_minutes - number of minutes that dst shifts clock
     */
    template<class date_type, 
             class time_duration_type,
             class dst_traits>
    class dst_calc_engine
    {
    public:
      typedef typename date_type::year_type year_type;
      typedef typename date_type::calendar_type calendar_type;
      typedef dst_calculator<date_type, time_duration_type> dstcalc;

      //! Calculates if the given local time is dst or not
      /*! Determines if the time is really in DST or not.  Also checks for 
       *  invalid and ambiguous.
       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
       */
      static time_is_dst_result local_is_dst(const date_type& d,
                                             const time_duration_type& td) 
      {

        year_type y = d.year();
        date_type dst_start = local_dst_start_day(y);
        date_type dst_end   = local_dst_end_day(y);
        return dstcalc::local_is_dst(d,td,
                                     dst_start,
                                     dst_traits::dst_start_offset_minutes(),
                                     dst_end, 
                                     dst_traits::dst_end_offset_minutes(), 
                                     dst_traits::dst_shift_length_minutes());
      
      }

      static bool is_dst_boundary_day(date_type d)
      {
        year_type y = d.year();
        return ((d == local_dst_start_day(y)) ||
                (d == local_dst_end_day(y)));
      }

      //! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00)
      static time_duration_type dst_offset() 
      {
        return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0);
      }

      static date_type local_dst_start_day(year_type year)
      {
        return dst_traits::local_dst_start_day(year);      
      }

      static date_type local_dst_end_day(year_type year)
      {
        return dst_traits::local_dst_end_day(year);
      }


    };

    //! Depricated: Class to calculate dst boundaries for US time zones
    /* Use dst_calc_engine instead.
     * In 2007 US/Canada DST rules changed
     * (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time).
     */
    template<class date_type_, 
             class time_duration_type_,
             unsigned int dst_start_offset_minutes=120, //from start of day 
             short dst_length_minutes=60>  //1 hour == 60 min in US
    class us_dst_rules 
    {
    public:
      typedef time_duration_type_ time_duration_type;
      typedef date_type_ date_type;
      typedef typename date_type::year_type year_type;
      typedef typename date_type::calendar_type calendar_type;
      typedef date_time::last_kday_of_month<date_type> lkday;
      typedef date_time::first_kday_of_month<date_type> fkday;
      typedef date_time::nth_kday_of_month<date_type> nkday;
      typedef dst_calculator<date_type, time_duration_type> dstcalc;

      //! Calculates if the given local time is dst or not
      /*! Determines if the time is really in DST or not.  Also checks for 
       *  invalid and ambiguous.
       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
       */
      static time_is_dst_result local_is_dst(const date_type& d,
                                             const time_duration_type& td) 
      {

        year_type y = d.year();
        date_type dst_start = local_dst_start_day(y);
        date_type dst_end   = local_dst_end_day(y);
        return dstcalc::local_is_dst(d,td,
                                     dst_start,dst_start_offset_minutes,
                                     dst_end, dst_start_offset_minutes, 
                                     dst_length_minutes);
      
      }


      static bool is_dst_boundary_day(date_type d)
      {
        year_type y = d.year();
        return ((d == local_dst_start_day(y)) ||
                (d == local_dst_end_day(y)));
      }

      static date_type local_dst_start_day(year_type year)
      {
        if (year >= year_type(2007)) {
          //second sunday in march
          nkday ssim(nkday::second, Sunday, gregorian::Mar);
          return ssim.get_date(year);      
        } else {
          //first sunday in april
          fkday fsia(Sunday, gregorian::Apr);
          return fsia.get_date(year);      
        }
      }

      static date_type local_dst_end_day(year_type year)
      {
        if (year >= year_type(2007)) {
          //first sunday in november
          fkday fsin(Sunday, gregorian::Nov);
          return fsin.get_date(year);      
        } else {
          //last sunday in october
          lkday lsio(Sunday, gregorian::Oct);
          return lsio.get_date(year);
        }
      }

      static time_duration_type dst_offset()
      {
        return time_duration_type(0,dst_length_minutes,0);
      }

     private:


    };

    //! Used for local time adjustments in places that don't use dst
    template<class date_type_, class time_duration_type_>
    class null_dst_rules
    {
    public:
      typedef time_duration_type_ time_duration_type;
      typedef date_type_ date_type;


      //! Calculates if the given local time is dst or not
      /*! @retval Always is_not_in_dst since this is for zones without dst
       */
      static time_is_dst_result local_is_dst(const date_type&, 
                                             const time_duration_type&) 
      {
        return is_not_in_dst;
      }
    
      //! Calculates if the given utc time is in dst
      static time_is_dst_result utc_is_dst(const date_type&, 
                                           const time_duration_type&) 
      {
        return is_not_in_dst;
      }

      static bool is_dst_boundary_day(date_type d)
      {
        return false;
      }

      static time_duration_type dst_offset() 
      {
        return time_duration_type(0,0,0);
      }

    };


  } } //namespace date_time



#endif
