# format python
# -*- coding: iso-8859-1 -*-
r"""
    MoinMoin - AlertDate Macro

    This very complicated macro takes in a date
    and produces a label automatically based on
    how soon that date will occur. 
    
    Depending  on when  it is,  by  default the
    following labels are used:
        Next Week (or Weekend)
        This Week (or Weekend)
        Tomorrow! or,
        Today!
    

    Also, a  label for  things further than two
    weeks into the future,  or past  events can
    be  configured.  Images could just  as well
    be inserted.
    
    Configure  the labels in moin_config.py  by
    adding: 
         alert_date_format = ""    # format str
         alert_labels = {}      # dict defining
                                # the following
                                # labels:
           "today", "tomorrow",
           "thisweek", "thisweekend",
           "nextweek", "nextweekend",
           "future", "passed"

    default usage is [[AlertDate(mm/dd/yyyy)]]

    @copyright: 2004 by Arel Cordero <arel@cs.berkeley.edu>
    @license: GNU GPL, see COPYING for details.
"""

import time
import moin_config

Dependencies = []

# default variables. These can be overwritten in moin_config.py
class glob:
    alert_date_fmt = "%m/%d/%Y"      # see time module for expl.
    alert_labels = {                 # could just as well insert icons...
          "nextweek":   '(Next Week)',
          "nextweekend":'(Next Weekend)',
          "thisweek":   '(This Week)',
          "thisweekend":'(This Weekend)',
          "tomorrow":   '(Tomorrow!)',
          "today":      '(<b>Today!</b>)',
          "passed":     '',
          "future":     ''}

# converts time tuple t into:
#    d     number of days since epoch.
#    wd    day of the week (with monday being 0)
def indays(t):
    a = list(t)
    a[3:6] = [0, 0, 0]
    d = int(time.mktime(a) / 86400.0) # divide by sec./day
    wd = t[6]                         # day of week, 0 = monday
    return (d,wd)

# Expects a single string in args that contains due date
# formatted to configured format. Default is mm/dd/yyyy 
def execute(macro, args):
    
    # Check and import config variables
    if hasattr(moin_config, "alert_date_config"):
        glob.alert_date_config = moin_config.alert_date_config
    if hasattr(moin_config, "alert_labels"):
        glob.alert_labels = moin_config.alert_labels

    # Attempt to parse time according to format
    try:

       (due,   d_dow) = indays( time.strptime(args, glob.alert_date_fmt) )
       (local, l_dow) = indays( time.localtime() )
       delta          = due - local
       monday         = due - d_dow

       if   delta <  0: return glob.alert_labels.get("passed",   "")
       elif delta == 0: return glob.alert_labels.get("today",    "")
       elif delta == 1: return glob.alert_labels.get("tomorrow", "")
       elif local >= monday:
          if d_dow in [5, 6]: return glob.alert_labels.get("thisweekend", "")
          else:               return glob.alert_labels.get("thisweek",    "")
       elif local >= monday - 7: 
          if d_dow in [5, 6]: return glob.alert_labels.get("nextweekend", "")
          else:               return glob.alert_labels.get("nextweek",    "")
       else: return glob.alert_labels.get("future", "")

    except:
       # Format was not understood.
       if args :
          return   """<p> [ <u>Error:</u> The date <%s> could not be parsed.
                      It should look like: AlertDate(%s) ] </p>""" % (
                      args, time.strftime(glob.alert_date_fmt))
       else:
          return   """<p> [ <u>Usage:</u>
                      <b>AlertDate(<i>some_future_date</i>)</b><br> Where
                      <i>some_future_date</i> takes the format: (%s).<br>
                      For example, AlertDate(%s) ] </p>""" % (
                      glob.alert_date_fmt,
                      time.strftime(glob.alert_date_fmt))
