#!-*- coding:utf-8 -*-"

import calendar

from datetime import date, timedelta, datetime

from trac.util.datefmt import utc, format_date, format_datetime, parse_date
from trac.util.translation import _

weekdays = [_(u'月'), _(u'火'), _(u'水'), _(u'木'), _(u'金'), _(u'土'), _(u'日')]

def date_to_weekday(date):
    return weekdays[date.weekday()]

def num_to_weekday(num):
    return weekdays[num]

def today():
    return date.today()

def handle_current_date(req, year_key='year', month_key='month'):
    """リクエストパラメータから日付を取得する。指定が無い場合は、現在日付を返す。
    """
    yyear = req.args.get(year_key)
    ymonth = req.args.get(month_key)
    cday = date.today()
    if not (not ymonth or not yyear):
        cday = date(int(yyear), int(ymonth), 1)
    return cday

def format_utcepoch(epoch, format='%Y-%m-%d', tzinfo=None):
    dt = datetime.fromtimestamp(int(epoch), utc)
    return format_datetime(dt, format, tzinfo)
        
def is_today(year, month, day):
    today = date.today()
    return today.year == year and today.month == month and today.day == day

def is_holiday(year, month, day, holidays):
    import datetime
    date = datetime.date(year, month, day)
    if date.isoformat() in holidays:
        return True
    else:
        return False
    
def to_timestamp(datetime):
    import time
    return time.mktime(datetime.timetuple())

def to_localtime(req, date, format='%Y/%m/%d %H:%M:%S'):
    return format_datetime(date, format, req.tz)

def str_to_datetime(req, str_date):
    return parse_date(str_date, req.tz)

def monthtop(cday):
    return cday.replace(day=1)

def monthlast(cday):
    return next_monthtop(cday, 1).__add__(timedelta(days= -1))

def to_datetime(year=None, month=None, day=1):
    td = today()
    
    if year:
        td = td.replace(year=int(year))
    if month:
        td = td.replace(month=int(month))
    
    if td.month in [4, 6, 9, 11] and day > 30:
        return td.replace(day=30)
    
    if td.month == 2 and day > 28:
        return monthlast(td)     
    
    if day < 1:
        return monthtop(td)   
        
    return td.replace(day=day)

def cutoff_days(baseday, count=1):
    if isinstance(baseday, str) and baseday == 'last':
        to_day = monthlast(today())
        from_day = monthtop(today())
        return _cutoff_days(baseday, from_day, to_day, count)
    
    baseday = to_datetime(day=int(baseday))
    
    # 基準日によりto_dayを計算
    to_day = today()
    if to_day > baseday:
        to_day = next_monthtop(to_day, 1)
        to_day = to_day.replace(day=baseday.day)
    else:
        to_day = to_day.replace(day=baseday.day)
        
    # to_dayより一ヶ月前の日としてfrom_dayを計算
    from_day = prev_monthtop(to_day, 1)
    from_day = from_day.replace(day=baseday.day).__add__(timedelta(days=1))
        
    return _cutoff_days(baseday, from_day, to_day, count)

def _cutoff_days(baseday, from_day, to_day, count):
    if count < 2:
        return [(from_day, to_day)]
    
    if isinstance(baseday, str) and baseday == 'last':
        return [(prev_monthtop(from_day, x), prev_monthlast(to_day, x)) for x in range(count)]
            
    return [(prev_monthtop(from_day, x).replace(day=from_day.day),
             prev_monthlast(to_day, x).replace(day=to_day.day)) for x in range(count)]
    
def prev_monthlast(cday, num):
    from dateutil.relativedelta import relativedelta
    prev_month = cday - relativedelta(months=num)
    return monthlast(prev_month)

def prev_monthtop(cday, num):
    cday = cday.replace(day=1)
    for x in range(int(num)):
        cday = cday.replace(day=1).__add__(timedelta(days=-1)).replace(day=1)
    return cday

def next_monthtop(cday, num):
    cday = cday.replace(day=1)
    for x in range(int(num)):
        cday = cday.replace(day=1).__add__(timedelta(days=32)).replace(day=1)
    return cday

def validate_datestr(datestr):
    import re
    match = re.match(r'\d\d\d\d-\d\d-\d\d$', datestr)
    if match:
        return True
    else:
        return False