/***************************************************************************
                          timecontrol.cpp  -  description
                             -------------------
    begin                : Son Jan 12 2003
    copyright            : (C) 2003 by Martin Witte
    email                : witte@kawo1.rwth-aachen.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <tdeaboutdata.h>
#include <tdeconfig.h>

#include "timecontrol.h"
#include "timecontrol-configuration.h"
#include "../../src/include/pluginmanager.h"
#include "../../src/include/aboutwidget.h"

//const char *AlarmListElement            = "alarmlist";
//const char *AlarmElement                = "alarm";
const char *AlarmDateElement            = "date";
const char *AlarmTimeElement            = "time";
const char *AlarmDailyElement           = "daily";
const char *AlarmWeekdayMaskElement     = "weekdayMask";
const char *AlarmEnabledElement         = "enabled";
const char *AlarmStationIDElement       = "stationID";
//const char *AlarmFrequencyElement       = "frequency";
const char *AlarmVolumeElement          = "volume";
const char *AlarmTypeElement            = "type";


///////////////////////////////////////////////////////////////////////
//// plugin library functions

PLUGIN_LIBRARY_FUNCTIONS(TimeControl, "tderadio-timecontrol", i18n("Time Control and Alarm Functions"));

///////////////////////////////////////////////////////////////////////


TimeControl::TimeControl (const TQString &n)
    : PluginBase(n, i18n("TimeControl Plugin")),
      m_waitingFor(NULL),
      m_countdownSeconds(0),
      m_alarmTimer(this),
      m_countdownTimer(this)
{
    TQObject::connect(&m_alarmTimer,     TQT_SIGNAL(timeout()), this, TQT_SLOT(slotQTimerAlarmTimeout()));
    TQObject::connect(&m_countdownTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotQTimerCountdownTimeout()));
}


TimeControl::~TimeControl ()
{
    m_waitingFor = NULL;
}

bool   TimeControl::connectI (Interface *i)
{
    bool a = ITimeControl::connectI(i);
    bool b = PluginBase::connectI(i);
    return a || b;
}

bool   TimeControl::disconnectI (Interface *i)
{
    bool a = ITimeControl::disconnectI(i);
    bool b = PluginBase::disconnectI(i);
    return a || b;
}

bool TimeControl::setAlarms (const AlarmVector &al)
{
    if (m_alarms != al) {
        m_waitingFor = NULL;

        m_alarms = al;

        slotQTimerAlarmTimeout();

        notifyAlarmsChanged(m_alarms);
    }
    return true;
}


bool TimeControl::setCountdownSeconds(int n)
{
    int old = m_countdownSeconds;
    m_countdownSeconds = n;
    if (old != n)
        notifyCountdownSecondsChanged(n);
    return true;
}


bool TimeControl::startCountdown()
{
    m_countdownEnd = TQDateTime::currentDateTime().addSecs(m_countdownSeconds);
    m_countdownTimer.start(m_countdownSeconds * 1000, true);

    notifyCountdownStarted(getCountdownEnd());

    return true;
}


bool TimeControl::stopCountdown()
{
    m_countdownTimer.stop();
    m_countdownEnd = TQDateTime();

    notifyCountdownStopped();

    return true;
}


TQDateTime TimeControl::getNextAlarmTime() const
{
    const Alarm *a = getNextAlarm();
    if (a)
        return a->nextAlarm();
    else
        return TQDateTime();
}


const Alarm *TimeControl::getNextAlarm () const
{
    TQDateTime now = TQDateTime::currentDateTime(),
              next;

    const Alarm *retval = NULL;

    for (ciAlarmVector i = m_alarms.begin(); i != m_alarms.end(); ++i) {
        TQDateTime n = i->nextAlarm();
        if (n.isValid() && n > now && ( ! next.isValid() || n < next)) {
            next = n;
            retval = &(*i);
        }
    }

    TQDateTime old = m_nextAlarm_tmp;
    m_nextAlarm_tmp = next;
    if (old != m_nextAlarm_tmp) {
        notifyNextAlarmChanged(retval);
    }

    return retval;
}


TQDateTime TimeControl::getCountdownEnd () const
{
    if (m_countdownTimer.isActive())
        return m_countdownEnd;
    else
        return TQDateTime();
}


void TimeControl::slotQTimerCountdownTimeout()
{
    stopCountdown();

    notifyCountdownZero();
}


void TimeControl::slotQTimerAlarmTimeout()
{
    if (m_waitingFor) {
        notifyAlarm(*m_waitingFor);
    }

    TQDateTime now  = TQDateTime::currentDateTime();
    Alarm const *n = getNextAlarm();
    TQDateTime na   = getNextAlarmTime();

    m_waitingFor = NULL;

    if (na.isValid()) {

        int days  = now.daysTo(na);
        int msecs = now.time().msecsTo(na.time());

        if (days > 1) {
            m_alarmTimer.start(24 * 3600 * 1000, true);

        } else if (days >= 0) {

            if (days > 0)
                msecs += days * 24 * 3600 * 1000;

            if (msecs > 0) {
                m_waitingFor = n;
                m_alarmTimer.start(msecs, true);
            }
        }
    }
}


void    TimeControl::restoreState (TDEConfig *config)
{
    AlarmVector al;

    config->setGroup(TQString("timecontrol-") + name());

    int nAlarms = config->readNumEntry ("nAlarms", 0);
    for (int idx = 1; idx <= nAlarms; ++idx) {

        TQString num = TQString().setNum(idx);
        TQDateTime d = config->readDateTimeEntry(AlarmTimeElement       + num);
        bool enable = config->readBoolEntry(AlarmEnabledElement        + num, false);
        bool daily  = config->readBoolEntry(AlarmDailyElement          + num, false);
        int weekdayMask = config->readNumEntry(AlarmWeekdayMaskElement + num, 0x7F);
        float vol   = config->readDoubleNumEntry(AlarmVolumeElement    + num, 1);
        TQString sid = config->readEntry(AlarmStationIDElement          + num, TQString());
        int type    = config->readNumEntry(AlarmTypeElement            + num, 0);

        enable &= d.isValid();

        Alarm a ( d, daily, enable);
        a.setVolumePreset(vol);
        a.setWeekdayMask(weekdayMask);
        a.setStationID(sid);
        a.setAlarmType((Alarm::AlarmType)type);
        al.push_back(a);
    }

    setAlarms(al);
    setCountdownSeconds(config->readNumEntry("countdownSeconds", 30*60));
}


void    TimeControl::saveState    (TDEConfig *config) const
{
    config->setGroup(TQString("timecontrol-") + name());

    config->writeEntry("nAlarms", m_alarms.size());
    int idx = 1;
    ciAlarmVector end = m_alarms.end();
    for (ciAlarmVector i = m_alarms.begin(); i != end; ++i, ++idx) {
        TQString num = TQString().setNum(idx);
        config->writeEntry (AlarmTimeElement      + num, i->alarmTime());
        config->writeEntry (AlarmEnabledElement   + num, i->isEnabled());
        config->writeEntry (AlarmDailyElement     + num, i->isDaily());
        config->writeEntry (AlarmWeekdayMaskElement + num, i->weekdayMask());
        config->writeEntry (AlarmVolumeElement    + num, i->volumePreset());
        config->writeEntry (AlarmStationIDElement + num, i->stationID());
        config->writeEntry (AlarmTypeElement      + num, i->alarmType());
    }

    config->writeEntry("countdownSeconds",  m_countdownSeconds);
}


ConfigPageInfo TimeControl::createConfigurationPage()
{
    TimeControlConfiguration *conf = new TimeControlConfiguration(NULL);
    connectI(conf);
    return ConfigPageInfo (conf, i18n("Alarms"), i18n("Setup Alarms"), "tderadio_kalarm");
}


AboutPageInfo TimeControl::createAboutPage()
{
/*    TDEAboutData aboutData("tderadio",
                         NULL,
                         NULL,
                         I18N_NOOP("Time Control Plugin for TDERadio."
                                   "<P>"
                                   "Provides Alarms and Sleep Countdown"
                                   "<P>"),
                         TDEAboutData::License_GPL,
                         "(c) 2002-2005 Martin Witte, Klas Kalass",
                         0,
                         "http://sourceforge.net/projects/tderadio",
                         0);
    aboutData.addAuthor("Martin Witte",  "", "witte@kawo1.rwth-aachen.de");
    aboutData.addAuthor("Klas Kalass",   "", "klas.kalass@gmx.de");

    return AboutPageInfo(
              new TDERadioAboutWidget(aboutData, TDERadioAboutWidget::AbtTabbed),
              i18n("Alarms"),
              i18n("Time Control Plugin"),
              "tderadio_kalarm"
           );*/
    return AboutPageInfo();
}


#include "timecontrol.moc"
