import calendar
calendar.setfirstweekday(6)
from DateTime import DateTime
import Products.CMFCalendar.CalendarTool as CalendarTool

def getEventsForCalendar(self, month='1', year='2002', **kw):
    """
    recreates a sequence of weeks, by days each day is a mapping.
    {'day': #, 'url': None}
    """
    year = int(year)
    month = int(month)
    daysByWeek = calendar.monthcalendar(year, month)
    weeks = []

    events = self.catalog_getevents(year, month, **kw)

    for week in daysByWeek:
        days=[]
        for day in week:
            if events.has_key(day):
                days.append(events[day])
            else:
                days.append({'day': day, 'event': 0, 'eventslist':[]})
        weeks.append(days)

    return weeks

def catalog_getevents(self, year, month, **kw):
    """
    given a year and month return a list of days that have events
    """
    first_date=DateTime(str(month)+'/1/'+str(year))
    last_day=calendar.monthrange(year, month)[1]
    last_date=first_date + last_day

    if not kw:
        # If we don't get any keyword arguments, we go w/
        # default CalendarTool behaviour
        kw['review_state'] = 'published'

    kw.update( { 'Type':self.calendar_types,
                 'start':{ 'query': last_date,
                           'range': 'max' },
                 'end':{ 'query': first_date,
                         'range': 'min' },
                 'sort_on':'start' })

    query = self.portal_catalog(**kw)

    # compile a list of the days that have events
    eventDays={}
    for daynumber in range(1, 32): # 1 to 31
        eventDays[daynumber] = {'eventslist':[], 'event':0, 'day':daynumber}
    includedevents = []
    for result in query:
        if result.getRID() in includedevents:
            break
        else:
            includedevents.append(result.getRID())
        event={}
        # we need to deal with events that end next month
        if  result.end.month() != month:  # doesn't work for events that last ~12 months - fix it if it's a problem, otherwise ignore
            eventEndDay = last_day
            event['end'] = None
        else:
            eventEndDay = result.end.day()
            event['end'] = result.end.Time()
        # and events that started last month
        if result.start.month() != month:  # same as above re: 12 month thing
            eventStartDay = 1
            event['start'] = None
        else:
            eventStartDay = result.start.day()
            event['start'] = result.start.Time()
        event['title'] = result.Title or result.id
        if eventStartDay != eventEndDay:
            allEventDays = range(eventStartDay, eventEndDay+1)
            eventDays[eventStartDay]['eventslist'].append({'end':None, 'start':result.start.Time(), 'title':result.Title})
            eventDays[eventStartDay]['event'] = 1
            for eventday in allEventDays[1:-1]:
                eventDays[eventday]['eventslist'].append({'end':None, 'start':None, 'title':result.Title})
                eventDays[eventday]['event'] = 1
            eventDays[eventEndDay]['eventslist'].append({'end':result.end.Time(), 'start':None, 'title':result.Title})
            eventDays[eventEndDay]['event'] = 1
        else:
            eventDays[eventStartDay]['eventslist'].append(event)
            eventDays[eventStartDay]['event'] = 1
    # This list is not uniqued and isn't sorted
    # uniquing and sorting only wastes time
    # and in this example we don't need to because
    # later we are going to do an 'if 2 in eventDays'
    # so the order is not important.
    # example:  [23, 28, 29, 30, 31, 23]
    return eventDays

CalendarTool.CalendarTool.getEventsForCalendar = getEventsForCalendar
CalendarTool.CalendarTool.catalog_getevents = catalog_getevents
