# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Timeline is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Timeline.  If not, see <http://www.gnu.org/licenses/>.


from timelinelib.calendar.generic.datetime import DateTime
from timelinelib.calendar.pharaonic.time import PharaonicTime
from timelinelib.calendar.pharaonic.monthnames import abbreviated_name_of_month
from timelinelib.calendar.pharaonic.weekdaynames import abbreviated_name_of_weekday
from timelinelib.calendar.pharaonic.julian2pharaonic import julian_day_to_pharaonic_ymd
from timelinelib.calendar.pharaonic.pharaonic2julian import pharaonic_ymd_to_julian_day


class PharaonicDateTime(DateTime):

    def __init__(self, year, month, day, hour, minute, second):
        if not self.is_valid(year, month, day):
            raise ValueError("Invalid pharaonic date %s-%s-%s" % (year, month, day))
        DateTime.__init__(self, year, month, day, hour, minute, second)

    @classmethod
    def TimeClass(cls):
        return PharaonicTime

    @classmethod
    def julian_day_to_ymd_fn(cls):
        return julian_day_to_pharaonic_ymd

    @classmethod
    def ymd_to_julian_day_fn(cls):
        return pharaonic_ymd_to_julian_day

    # the 13th month is considered "inbetween" years so it returns a week number 0
    @property
    def week_number(self):

        if self.month == 13:
            return 0
        
        length_of_week = 10
        days_into_year = ((self.month - 1)*30) + self.day
               
        if self.day % length_of_week > 0:
            return (days_into_year // length_of_week) + 1

        return days_into_year // length_of_week

    @property
    def abbreviated_month_name(self):
        return abbreviated_name_of_month(self.month)

    @property
    def abbreviated_weekday_name(self):
        return abbreviated_name_of_weekday(self.to_time().day_of_week)

    @property
    def is_leap_year(self):
        """
        julian_day_to_pharaonic_ymd() don't produce any leap years!
        TODO:
        This method is only used in function days_in_year() and days in month() and is not
        needed at all for PharaonicDateTime!
        Maybe we should keep it to preserve the DateTime interface?
        """
        return False

    def days_in_month(self):
        return self.nbr_of_days_in_month(self.year, self.month)

    @classmethod
    def nbr_of_days_in_month(cls, year, month):
        if month <= 12:
            return 30
        else:
            return 5

    @property
    def days_in_week(self):
        if self.month == self.months_in_year:
            return 5
        else:
            return 10

    @property
    def days_in_year(self):
        return 365

    @classmethod
    def months_in_year(cls):
        return 13
