/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   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.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * A date editor with more features.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgdatepickerpopup.h"

#include <KDatePicker>
#include <KLocale>

#include <QtCore/QDateTime>
#include <QtGui/QWidgetAction>

/**
 * The date picker action
 */
class SKGDatePickerAction : public QWidgetAction
{
public:
    /**
     * Constructor
     * @param widget the date picker
     * @param parent the parent
     */
    explicit SKGDatePickerAction(KDatePicker* widget, QObject* parent)
        : QWidgetAction(parent),
          mDatePicker(widget), mOriginalParent(widget->parentWidget()) {
    }

protected:
    /**
     * This function is called whenever the action is added to a container widget that supports custom widgets.
     * If you don't want a custom widget to be used as representation of the action in the specified parent widget then 0 should be returned
     * @param parent the parent
     * @return the date picker
     */
    QWidget* createWidget(QWidget* parent) {
        mDatePicker->setParent(parent);
        return mDatePicker;
    }

    /**
     * This function is called whenever the action is removed from a container widget that displays the action using a custom widget previously created using createWidget().
     * The default implementation hides the widget and schedules it for deletion using QObject::deleteLater().
     * @param widget the widget
     */
    void deleteWidget(QWidget* widget) {
        if (widget != mDatePicker) {
            return;
        }

        mDatePicker->setParent(mOriginalParent);
    }

private:
    KDatePicker* mDatePicker;
    QWidget* mOriginalParent;
};

SKGDatePickerPopup::SKGDatePickerPopup(Items items, const QDate& date, QWidget* parent)
    : QMenu(parent)
{
    m_items = items;

    m_datePicker = new KDatePicker(this);
    m_datePicker->setCloseButton(false);

    connect(m_datePicker, SIGNAL(dateEntered(QDate)), SLOT(slotDateChanged(QDate)));
    connect(m_datePicker, SIGNAL(dateSelected(QDate)), SLOT(slotDateChanged(QDate)));
    m_datePicker->setDate(date);
    buildMenu();
}

void SKGDatePickerPopup::buildMenu()
{
    if (isVisible()) return;
    clear();

    if (m_items & DatePicker) {
        addAction(new SKGDatePickerAction(m_datePicker, this));

        if ((m_items & NoDate) || (m_items & Words)) {
            addSeparator();
        }
    }

    if (m_items & Words) {
        addAction(i18nc("@option today", "Today"), this, SLOT(slotToday()));
        addAction(i18nc("@option tomorrow", "Tomorrow"), this, SLOT(slotTomorrow()));
        addAction(i18nc("@option next week", "Next Week"), this, SLOT(slotNextWeek()));
        addAction(i18nc("@option next month", "Next Month"), this, SLOT(slotNextMonth()));

        if (m_items & NoDate) {
            addSeparator();
        }
    }

    if (m_items & NoDate) {
        addAction(i18nc("@option do not specify a date", "No Date"), this, SLOT(slotNoDate()));
    }
}

KDatePicker* SKGDatePickerPopup::datePicker() const
{
    return m_datePicker;
}

void SKGDatePickerPopup::setDate(const QDate& date)
{
    if (m_datePicker) m_datePicker->setDate(date);
}

void SKGDatePickerPopup::slotDateChanged(const QDate& date)
{
    Q_EMIT dateChanged(date);
    hide();
}

void SKGDatePickerPopup::slotToday()
{
    Q_EMIT dateChanged(QDate::currentDate());
}

void SKGDatePickerPopup::slotTomorrow()
{
    Q_EMIT dateChanged(QDate::currentDate().addDays(1));
}

void SKGDatePickerPopup::slotNoDate()
{
    Q_EMIT dateChanged(QDate());
}

void SKGDatePickerPopup::slotNextWeek()
{
    Q_EMIT dateChanged(QDate::currentDate().addDays(7));
}

void SKGDatePickerPopup::slotNextMonth()
{
    Q_EMIT dateChanged(QDate::currentDate().addMonths(1));
}

#include "skgdatepickerpopup.moc"
