//
//  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
#define BOOST_LOCALE_SOURCE
#include <boost/locale/date_time_facet.hpp>
#include <boost/locale/date_time.hpp>
#include <boost/locale/formatting.hpp>
#include "all_generator.hpp"

#include <boost/thread.hpp>
#include <unicode/calendar.h>
#include <unicode/gregocal.h>
#include <unicode/utypes.h>

#include <memory>
#include <math.h>

#include "cdata.hpp"
#include "uconv.hpp"
#include "time_zone.hpp"

#include <iostream>


namespace boost {
namespace locale {
namespace impl_icu {
    
    static void check_and_throw_dt(UErrorCode &e)
    {
        if(U_FAILURE(e)) {
            date_time_error(u_errorName(e));
        }
    }
    using period::marks::period_mark;

    static UCalendarDateFields to_icu(period::marks::period_mark f)
    {
        using namespace period::marks;

        switch(f) {
        case era: return UCAL_ERA;
        case year: return UCAL_YEAR;
        case extended_year: return UCAL_EXTENDED_YEAR;
        case month: return UCAL_MONTH;
        case day: return UCAL_DATE;
        case day_of_year: return UCAL_DAY_OF_YEAR;
        case day_of_week: return UCAL_DAY_OF_WEEK;
        case day_of_week_in_month:  return UCAL_DAY_OF_WEEK_IN_MONTH;
        case day_of_week_local: return UCAL_DOW_LOCAL;
        case hour: return UCAL_HOUR_OF_DAY;
        case hour_12: return UCAL_HOUR;
        case am_pm: return UCAL_AM_PM;
        case minute: return UCAL_MINUTE;
        case second: return UCAL_SECOND;
        case week_of_year: return UCAL_WEEK_OF_YEAR;
        case week_of_month: return UCAL_WEEK_OF_MONTH;
        default:
            throw std::invalid_argument("Invalid date_time period type");
        }
    }


    class calendar_impl : public abstract_calendar {
    public:
        
        calendar_impl(cdata const &dat)
        {
            UErrorCode err=U_ZERO_ERROR;
            calendar_.reset(icu::Calendar::createInstance(dat.locale,err));
            check_and_throw_dt(err);
            #if U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM < 402
            // workaround old/invalid data, it should be 4 in general
            calendar_->setMinimalDaysInFirstWeek(4);
            #endif
            encoding_ = dat.encoding;
        }
        calendar_impl(calendar_impl const &other)
        {
            calendar_.reset(other.calendar_->clone());
            encoding_ = other.encoding_;
        }

        calendar_impl *clone() const
        {
            return new calendar_impl(*this);
        }

        void set_value(period::marks::period_mark p,int value)
        {
            calendar_->set(to_icu(p),int32_t(value));
        }

        int get_value(period::marks::period_mark p,value_type type) const
        {
            UErrorCode err=U_ZERO_ERROR;
            int v=0;
            if(p==period::marks::first_day_of_week) {
                guard l(lock_);
                v=calendar_->getFirstDayOfWeek(err);
            }
            else {
                UCalendarDateFields uper=to_icu(p);
                guard l(lock_);
                switch(type) {
                case absolute_minimum:
                    v=calendar_->getMinimum(uper);
                    break;
                case actual_minimum:
                    v=calendar_->getActualMinimum(uper,err);
                    break;
                case greatest_minimum:
                    v=calendar_->getGreatestMinimum(uper);
                    break;
                case current:
                    v=calendar_->get(uper,err);
                    break;
                case least_maximum:
                    v=calendar_->getLeastMaximum(uper);
                    break;
                case actual_maximum:
                    v=calendar_->getActualMaximum(uper,err);
                    break;
                case absolute_maximum:
                    v=calendar_->getMaximum(uper);
                    break;
                }
            }
            check_and_throw_dt(err);
            return v;
        }

        virtual void set_time(posix_time const &p)
        {
            double utime = p.seconds * 1000.0 + p.nanoseconds / 1000000.0;
            UErrorCode code=U_ZERO_ERROR;
            calendar_->setTime(utime,code);
            check_and_throw_dt(code);
        }
        virtual void normalize()
        {
            // Can't call complete() explicitly (protected)
            // calling get wich calls complete
            UErrorCode code=U_ZERO_ERROR;
            calendar_->get(UCAL_YEAR,code);
            check_and_throw_dt(code);
        }
        virtual posix_time get_time() const
        {
            
            UErrorCode code=U_ZERO_ERROR;
            double rtime = 0;
            {
                guard l(lock_);
                rtime = calendar_->getTime(code);
            }
            check_and_throw_dt(code);
            rtime/=1000.0;
            double secs = floor(rtime);
            posix_time res;
            res.seconds = static_cast<int64_t>(secs);
            res.nanoseconds = static_cast<uint32_t>((rtime - secs) / 1e9);
            if(res.nanoseconds > 999999999)
                res.nanoseconds = 999999999;
            return res;
        }
        virtual void set_option(calendar_option_type opt,int /*v*/) 
        {
            switch(opt) {
            case is_gregorian:
                throw date_time_error("is_gregorian is not settable options for calendar");
            case is_dst:
                throw date_time_error("is_dst is not settable options for calendar");
            default:
                ;
            }
        }
        virtual int get_option(calendar_option_type opt) const
        {
            switch(opt) {
            case is_gregorian:
                return dynamic_cast<icu::GregorianCalendar const *>(calendar_.get())!=0;
            case is_dst:
                {
                    guard l(lock_);
                    UErrorCode err = U_ZERO_ERROR;
                    bool res = ( calendar_->inDaylightTime(err) != 0 );
                    check_and_throw_dt(err);
                    return res;
                }
            default:
                return 0;
            }
        }
        virtual void adjust_value(period::marks::period_mark p,update_type u,int difference)
        {
            UErrorCode err=U_ZERO_ERROR;
            switch(u) {
            case move:
                calendar_->add(to_icu(p),difference,err);
                break;
            case roll:
                calendar_->roll(to_icu(p),difference,err);
                break;
            }
            check_and_throw_dt(err);
        }
        virtual int difference(abstract_calendar const *other_ptr,period::marks::period_mark p) const
        {
            UErrorCode err=U_ZERO_ERROR;
            double other_time = 0;
            //
            // fieldDifference has side effect of moving calendar (WTF?)
            // So we clone it for performing this operation
            // 
            std::auto_ptr<icu::Calendar> self(calendar_->clone());

            calendar_impl const *other_cal=dynamic_cast<calendar_impl const *>(other_ptr);
            if(other_cal){
                guard l(other_cal->lock_);
                other_time = other_cal->calendar_->getTime(err);
                check_and_throw_dt(err);
            }
            else {
                posix_time p = other_ptr->get_time();
                other_time = p.seconds * 1000.0 + p.nanoseconds / 1000000.0;
            }

            int diff = self->fieldDifference(other_time,to_icu(p),err);

            check_and_throw_dt(err);
            return diff;
        }
        virtual void set_timezone(std::string const &tz)
        {
            calendar_->adoptTimeZone(get_time_zone(tz));
        }
        virtual std::string get_timezone() const 
        {
            icu::UnicodeString tz;
            calendar_->getTimeZone().getID(tz);
            icu_std_converter<char> cvt(encoding_);
            return cvt.std(tz);
        }
        virtual bool same(abstract_calendar const *other) const 
        {
            calendar_impl const *oc=dynamic_cast<calendar_impl const *>(other);
            if(!oc)
                return false;
            return calendar_->isEquivalentTo(*oc->calendar_)!=0;
        }

    private:
        typedef boost::unique_lock<boost::mutex> guard;
        mutable boost::mutex lock_;
        std::string encoding_;
        hold_ptr<icu::Calendar> calendar_;
    };
    
    class icu_calendar_facet : public calendar_facet  {
    public:
        icu_calendar_facet(cdata const &d,size_t refs = 0) : 
            calendar_facet(refs),
            data_(d)
        {
        }
        virtual abstract_calendar *create_calendar() const
        {
            return new calendar_impl(data_);
        }
    private:
        cdata data_;
    };
    
    std::locale create_calendar(std::locale const &in,cdata const &d)
    {
        return std::locale(in,new icu_calendar_facet(d));
    }

} // impl_icu
} // locale
} // boost



// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4

