/*
 * Created by IntelliJ IDEA.
 * User: Mike
 * Date: Jul 15, 2004
 * Time: 5:48:39 PM
 */
package com.atlassian.confluence.extra.calendar.model;

import org.joda.time.DateMidnight;

import java.util.*;

import com.atlassian.gregory.ICalendar;
import com.atlassian.gregory.components.ICalEvent;

public class CalendarModel
{
    int year = -1;
    int month = -1;
    int day = -1;
    private DateMidnight date;
    private ICalendar calendar;
    private Map eventsByDay;
    private static final long DAY_MILLIS = 24 * 60 * 60 * 1000;
    private DateMidnight prevDay;
    private DateMidnight nextDay;

    public CalendarModel(ICalendar calendar)
    {
        this.calendar = calendar;
    }

    public void init()
    {
        DateMidnight now = new DateMidnight();

        if (month <= 0)
            month = now.getMonthOfYear();

        if (day <= 0)
            day = now.getDayOfMonth();

        if (year <= 0)
            year = now.getYear();

        date = new DateMidnight(year, month, day);

        eventsByDay = new HashMap();

        for (Iterator iterator = calendar.getEvents().iterator(); iterator.hasNext();)
        {
            ICalEvent event = (ICalEvent) iterator.next();

            DateMidnight eventStart = new DateMidnight(event.getDateStart());

            List events = (List) eventsByDay.get(eventStart);

            if (events == null)
                events = new ArrayList(1);

            events.add(event);

            eventsByDay.put(eventStart, events);
        }
    }

    public int getDay()
    {
        return day;
    }

    public void setDay(int day)
    {
        this.day = day;
    }

    public int getMonth()
    {
        return month;
    }

    public void setMonth(int month)
    {
        this.month = month;
    }

    public int getYear()
    {
        return year;
    }

    public void setYear(int year)
    {
        this.year = year;
    }

    public int getNextMonth()
    {
        if (month == 12)
            return 1;

        return month + 1;
    }

    public int getPrevMonth()
    {
        if (month == 1)
            return 12;

        return month - 1;
    }

    public DateMidnight getDate()
    {
        return date;
    }

    public String getMonthName()
    {
        return date.monthOfYear().getAsText(Locale.getDefault());
    }

    public String getDayTitle()
    {
        return date.dayOfWeek().getAsText(Locale.getDefault()) + ", " + getMonthName() + " " + date.getDayOfMonth();
    }

    public DateMidnight getPrevDay()
    {
        if (prevDay == null)
            prevDay = new DateMidnight(date.getMillis() - DAY_MILLIS);

        return prevDay;
    }

    public DateMidnight getNextDay()
    {
        if (nextDay == null)
            nextDay = new DateMidnight(date.getMillis() + DAY_MILLIS);

        return nextDay;
    }

    public int getMonthWeeks()
    {
        int firstWeekOfMonth = new DateMidnight(date.getYear(), date.getMonthOfYear(), 1).getWeekOfWeekyear();
        int lastWeekOfMonth = new DateMidnight(date.getYear(), date.getMonthOfYear(), date.dayOfMonth().getMaximumValue()).getWeekOfWeekyear();

        return lastWeekOfMonth - firstWeekOfMonth;
    }

    public CalendarModelDay getModelDay(int row, int col)
    {
        try
        {
            if (row < 0 || col < 0)
                return null;

            int monthStart = new DateMidnight(date.getYear(), date.getMonthOfYear(), 1).getDayOfWeek();

            int dayOfMonth = row * 7 + col - monthStart + 1;

            if (dayOfMonth > 0)
            {
                if (dayOfMonth > date.dayOfMonth().getMaximumValue())
                {
                    return new CalendarModelDay(new DateMidnight(date.getYear(), getNextMonth(), dayOfMonth - date.dayOfMonth().getMaximumValue()), false);
                }
                else
                {
                    return new CalendarModelDay(new DateMidnight(date.getYear(), date.getMonthOfYear(), dayOfMonth), true);
                }
            }
            else
            {
                DateMidnight prevMonth = new DateMidnight(date.getYear(), getPrevMonth(), 1);
                return new CalendarModelDay(new DateMidnight(date.getYear(), getPrevMonth(), prevMonth.dayOfMonth().getMaximumValue() + dayOfMonth), false);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    public List getEvents(DateMidnight eventDate)
    {
        return (List) eventsByDay.get(eventDate);
    }
}