/*
  This file is part of libkdepim.

  Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
  Copyright (c) 2002 David Jarvie <software@astrojar.org.uk>
  Copyright (c) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

// krazy:excludeall=qclasses as we want to subclass from QComboBox, not KComboBox

#include "kdatevalidator.h"

#include <KDE/KGlobal>
#include <KDE/KLocale>

#include <QtCore/QDate>
#include <QtCore/QStringList>

namespace KPIM
{

class KDateValidatorPrivate
{
public:
    KDateValidatorPrivate()
        : behavior(KDateValidator::FixupCurrent) {}

    QStringList keywords;
    KDateValidator::FixupBehavior behavior;
};

}

using namespace KPIM;

KDateValidator::KDateValidator(QObject* iParent)
    : QValidator(iParent), d(new KDateValidatorPrivate)
{
}

KDateValidator::~KDateValidator()
{
    delete d;
}

QValidator::State KDateValidator::validate(QString& str, int& /*pos*/) const
{
    int length = str.length();

    // empty string is intermediate so one can clear the edit line and start from scratch
    if (length <= 0) {
        return Intermediate;
    }

    if (d->keywords.contains(str.toLower())) {
        return Acceptable;
    }

    bool ok = false;
    KGlobal::locale()->readDate(str, &ok);
    if (ok) {
        return Acceptable;
    } else {
        return Intermediate;
    }
}

void KDateValidator::fixup(QString& input) const
{
    if (d->behavior == NoFixup) {
        return;
    }

    QDate result;
    QStringList items = input.split('/');
    int size = items.count();
    bool ok = false;

    if (size == 1) {
        int dayCount = items.at(0).toInt(&ok);

        result = QDate::currentDate();
        result = result.addDays(-result.day());
        result = result.addDays(dayCount);

        switch (d->behavior) {
        case FixupBackward:
            if (result > QDate::currentDate()) {
                result = result.addMonths(-1);
            }
            break;
        case FixupForward:
            if (result < QDate::currentDate()) {
                result = result.addMonths(1);
            }
            break;
        default:
            break;
        }
    } else if (size == 2) {
        int dayCount = items.at(0).toInt(&ok);
        int monthCount = items.at(1).toInt(&ok);

        result = QDate::currentDate();
        result = result.addDays(-result.day());
        result = result.addDays(dayCount);
        result = result.addMonths(-result.month());
        result = result.addMonths(monthCount);

        switch (d->behavior) {
        case FixupBackward:
            if (result > QDate::currentDate()) {
                result = result.addYears(-1);
            }
            break;
        case FixupForward:
            if (result < QDate::currentDate()) {
                result = result.addYears(1);
            }
            break;
        default:
            break;
        }
    }

    if (ok) {
        input = KGlobal::locale()->formatDate(result, KLocale::ShortDate);
    }
}

void KDateValidator::setKeywords(const QStringList& iKeywords)
{
    d->keywords = iKeywords;
}

QStringList KDateValidator::keywords() const
{
    return d->keywords;
}

void KDateValidator::setFixupBehavior(FixupBehavior behavior)
{
    d->behavior = behavior;
}

KDateValidator::FixupBehavior KDateValidator::fixupBehavior() const
{
    return d->behavior;
}


