/* ============================================================
 * File  : calformatter.cpp
 * Author: Maciek Borowka <maciek_AT_borowka.net>
 * Date  : 2005-11-23
 * Description : The implementation of a class that decides which
 * cell of the calendar should be painted with which color.
 *
 * Copyright 2005 by Maciek Borowka
 * Revised by Orgad Shaneh, 2007
 *
 * This program 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 2, or (at your option)
 * any later version.
 *
 * This program 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.
 *
 * ============================================================ */

#include <tqdatetime.h>
#include <tqcolor.h>
#include <tqmap.h>

#include <kdebug.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <kcalendarsystem.h>
#include <libkcal/calendarlocal.h>

#include "calformatter.h"


namespace KIPICalendarPlugin {


class CalFormatter::Data
{
public:
    class Day {
    public:
        Day(){};
        Day(TQColor c, TQString d): color(c), description(d) {};

        TQColor color;
        TQString description;
     };


    TQString ohFile;
    TQString fhFile;

    TQMap<TQDate, Day> oh;//official holidays
    TQMap<TQDate, Day> fh;//family holidays

    Data()
    {

//you define a holiday that way:
oh[TQDate(2005, 1, 1)] = Day(TQt::red, "New year!");
//oh[TQDate(2005, 1, 4)] = Day(TQt::red, "Fete Nat");


fh[TQDate(2005,1,3)] = Day(TQt::green, "Adam");
//fh[TQDate(2005, 1, 14)] = Day(TQt::green, "Maciek");


    };

};

CalFormatter::CalFormatter() : initialized(false)
{

}


CalFormatter::~CalFormatter()
{
}

void CalFormatter::init(int year, const TQString & ohFile, const TQString & fhFile)
{
    if (initialized)
        return;

    d = new Data();
    year_ = year;
    d->ohFile = ohFile;
    d->fhFile = fhFile;

    kdDebug(51000) << "Loading calendar from file" << endl;
    KCal::CalendarLocal * calendar;

    if (not(ohFile.isEmpty())) {
        calendar = new KCal::CalendarLocal("UTC");
        if (calendar->load(ohFile)) {
                TQDate dtFirst, dtLast;
                TDEGlobal::locale()->calendar()->setYMD(dtFirst, year_, 1, 1);
                TDEGlobal::locale()->calendar()->setYMD(dtLast, year_ + 1, 1, 1);
                dtLast = dtLast.addDays(-1);

                KCal::Event::List list = calendar->rawEvents(dtFirst, dtLast);
                KCal::Event::List::iterator it;
		KCal::Recurrence *recur;

		TQDateTime dtCurrent;
                int counter = 0;
                for ( it = list.begin(); it != list.end(); ++it )
                {
                        kdDebug(51000) << (*it)->summary() << endl << "--------" << endl;
                        counter++;
			if ((*it)->doesRecur())
			{
				recur = (*it)->recurrence();
				for (dtCurrent = recur->getNextDateTime(dtFirst.addDays(-1)); (dtCurrent <= TQDateTime(dtLast)) && dtCurrent.isValid(); dtCurrent = recur->getNextDateTime(dtCurrent))
				{
					kdDebug(51000) << dtCurrent.toString() << endl;
					d->oh[dtCurrent.date()] = CalFormatter::Data::Day(TQt::red, (*it)->summary());
				}
				
			}
			else
	                        d->oh[(*it)->dtStart().date()] = CalFormatter::Data::Day(TQt::red, (*it)->summary());
                }
                kdDebug(51000) << "Loaded " << counter << " events for year " << year_ << endl;
        }
        delete calendar;
    }

    if (not(fhFile.isEmpty())) {
        calendar = new KCal::CalendarLocal("UTC");
        if (calendar->load(fhFile)) {

                KCal::Event::List list = calendar->rawEvents(TQDate(year_,1,1), TQDate(year_,12,31));
                KCal::Event::List::iterator it;

                TQString eventDate;
                int counter = 0;
                for ( it = list.begin(); it != list.end(); ++it )
                {
                        counter++;
                        d->fh[(*it)->dtStart().date()] = CalFormatter::Data::Day(TQt::red, (*it)->summary());
                        //kdDebug(51000) << eventDate << "----" <<  (*it)->summary() << endl;
                }
                kdDebug(51000) << "Loaded " << counter << " events for year " << year_ << endl;
        }
        delete calendar;
    }
}

bool CalFormatter::isPrayDay(int month, int day)
{
    TQDate dt;
    TDEGlobal::locale()->calendar()->setYMD(dt, year_, month, day);
    return (dt.dayOfWeek() == TDEGlobal::locale()->calendar()->weekDayOfPray());
}

/*!
    Returns true if special formatting is to be applied to the particular day
 */
bool KIPICalendarPlugin::CalFormatter::isSpecial(int month, int day)
{
    TQDate dt;
    TDEGlobal::locale()->calendar()->setYMD(dt, year_, month, day);

    return (isPrayDay(month,day) || d->oh.contains(dt) || d->fh.contains(dt));
}


/*!
    Returns the color to be used for painting of the day info
 */
TQColor KIPICalendarPlugin::CalFormatter::getDayColor(int month, int day)
{
    TQDate dt;
    TDEGlobal::locale()->calendar()->setYMD(dt, year_, month, day);

    if (isPrayDay(month, day))
        return TQt::red;

    if (d->oh.contains(dt))
        return TQt::red;

    if (d->fh.contains(dt))
        return TQt::green;

    //default
    return TQt::black;
}


/*!
    Returns the description of the day to be painted on the calendar.
 */
TQString KIPICalendarPlugin::CalFormatter::getDayDescr(int month, int day)
{
    TQDate dt;
    TDEGlobal::locale()->calendar()->setYMD(dt, year_, month, day);

    TQString ret;

    if (d->oh.contains(dt))
        ret = d->oh[dt].description;

    if (d->fh.contains(dt)) {
        if (ret.isNull()) 
            return d->fh[dt].description;
        else
            return ret.append(";").append(d->fh[dt].description);
    }

    return ret;
}
}
