#include <QtGui>
#include <QtCore>

#include "psiplugin.h"
#include "stanzafilter.h"
#include "accountinfoaccessor.h"
#include "accountinfoaccessinghost.h"
#include "applicationinfoaccessor.h"
#include "applicationinfoaccessinghost.h"
#include "stanzasender.h"
#include "stanzasendinghost.h"
#include "optionaccessor.h"
#include "optionaccessinghost.h"
#include "popupaccessor.h"
#include "popupaccessinghost.h"
#include "iconfactoryaccessinghost.h"
#include "iconfactoryaccessor.h"
#include "plugininfoprovider.h"

#define cVer "0.2.5"
#define constLastCheck "lstchck"
#define constDays "days"
#define constInterval "intrvl"
#define consttimeout "timeout"
#define constStartCheck "strtchck"
#define constCheckFromRoster "chckfrmrstr"
#define constUseCache "usecache"
#define constLastUpdate "lstupdt"
#define constUpdateInterval "updtintvl"
#define constPopupNotify "popupntf"
#define constDialogNotify "dlgntf"
#define constSoundFile "sndfl"

class Reminder : public QObject, public PsiPlugin, public StanzaFilter, public AccountInfoAccessor, public ApplicationInfoAccessor,
		public StanzaSender, public OptionAccessor, public PopupAccessor, public IconFactoryAccessor, public PluginInfoProvider
{
	Q_OBJECT
	Q_INTERFACES(PsiPlugin StanzaFilter AccountInfoAccessor ApplicationInfoAccessor StanzaSender OptionAccessor
		     PopupAccessor IconFactoryAccessor PluginInfoProvider)

public:
        Reminder();
	virtual QString name() const;
	virtual QString shortName() const;
	virtual QString version() const;
        virtual QWidget* options();
	virtual bool enable();
        virtual bool disable();
        virtual void applyOptions();
        virtual void restoreOptions();
        virtual bool incomingStanza(int account, const QDomElement& xml);
        virtual void setAccountInfoAccessingHost(AccountInfoAccessingHost* host);
        virtual void setApplicationInfoAccessingHost(ApplicationInfoAccessingHost* host);
        virtual void setStanzaSendingHost(StanzaSendingHost *host);
        virtual void setOptionAccessingHost(OptionAccessingHost* host);
        virtual void optionChanged(const QString& option);
        virtual void setPopupAccessingHost(PopupAccessingHost* host);
        virtual void setIconFactoryAccessingHost(IconFactoryAccessingHost* host);
	virtual QString pluginInfo();

private:
        bool enabled;
        OptionAccessingHost *psiOptions;
        AccountInfoAccessingHost *AccInfoHost;
        ApplicationInfoAccessingHost *AppInfoHost;
        StanzaSendingHost *StanzaHost;
        PopupAccessingHost* popup;
        IconFactoryAccessingHost* IcoHost;
        QString id;
        QString Dir;
        QString CheckBirthdays();
        QString LastCheck;
        int Days;
        QSpinBox *DaysWidget;
        int Interval;
        QSpinBox *IntervalWidget;
        QPushButton *Close;
        int timeout;
        int timeout2;
        QDialog *window;
        QTimer *timer;
        QSpinBox *timeoutWidget;
        bool StartCheck;
        QCheckBox *StartCheckWidget;
        QCheckBox *CheckFromRosterWidget;
        bool CheckFromRoster;
        bool UseCache;
        QCheckBox *UseCacheWidget;
        QString LastUpdate;
        int UpdateInterval;
        QSpinBox *UpdateIntervalWidget;
        bool PopupNotify;
        QCheckBox *PopupNotifyWidget;
        bool DialogNotify;
        QCheckBox *DialogNotifyWidget;
        QString SoundFile;
        QLineEdit *SoundFileWidget;       

private slots:
         void UpdateVCard();
         bool Check();
         void setDontCheck();
         void updateTimer();
         void close();
         void stopTimer();
         void CheckFromRosterWidgetIsChecked();
         void clearCache();
         void getSound();
         void checkSound();
         void playSound(QString);
};

Q_EXPORT_PLUGIN(Reminder);

Reminder::Reminder() {
        enabled = false;        
        AppInfoHost = 0;
        AccInfoHost = 0;
        StanzaHost = 0;
        psiOptions = 0;
        popup = 0;
        Dir = "";
        id = "";
        LastCheck = "1901010101";
        Days = 5;
        DaysWidget = 0;
        Interval = 24;
        IntervalWidget = 0;
        Close = 0;
        timeout = 15;
        window = 0;
        StartCheck = true;
        StartCheckWidget = 0;
        CheckFromRoster = false;
        CheckFromRosterWidget = 0;
        QTextCodec *codec = QTextCodec::codecForName("UTF-8");
        QTextCodec::setCodecForLocale(codec);
        UseCache = false;
        UseCacheWidget = 0;
        LastUpdate = "1901010101";
        UpdateInterval = 30;
        UpdateIntervalWidget = 0;
        PopupNotify = true;
        PopupNotifyWidget = 0;
        DialogNotify = true;
        DialogNotifyWidget = 0;
        SoundFile = "sound/reminder.wav";
        SoundFileWidget = 0;


    }

QString Reminder::name() const {
        return "Birthday Reminder Plugin";
    }

QString Reminder::shortName() const {
        return "reminder";
}

QString Reminder::version() const {
        return cVer;
}

bool Reminder::enable() {
  if(psiOptions) {

    QFile *file = new QFile(":/reminder/birthday.png");
    if ( file->open(QIODevice::ReadOnly) ) {
        QByteArray image = file->readAll();
        IcoHost->addIcon("reminder/birthdayicon",image);
        file->close();
    } else {
        return enabled;
    }

    enabled = true;
    id = "111aaa222bbb";
    QVariant vLastCheck(LastCheck);
    vLastCheck = psiOptions->getPluginOption(constLastCheck);
    if(!vLastCheck.isNull()) {
        LastCheck = vLastCheck.toString();
    }
    QVariant vtimeout(timeout);
    vtimeout = psiOptions->getPluginOption(consttimeout);
    if(!vtimeout.isNull()) {
        timeout = vtimeout.toInt();
    }
    QVariant vDays(Days);
    vDays = psiOptions->getPluginOption(constDays);
    if(!vDays.isNull()) {
        Days = vDays.toInt();
    }
    QVariant vInterval(Interval);
    vInterval = psiOptions->getPluginOption(constInterval);
    if(!vInterval.isNull()) {
        Interval = vInterval.toInt();
    }
    QVariant vStartCheck(StartCheck);
    vStartCheck = psiOptions->getPluginOption(constStartCheck);
    if(!vStartCheck.isNull()) {
        StartCheck = vStartCheck.toBool();
    }
    QVariant vCheckFromRoster(CheckFromRoster);
    vCheckFromRoster = psiOptions->getPluginOption(constCheckFromRoster);
    if(!vCheckFromRoster.isNull()) {
        CheckFromRoster = vCheckFromRoster.toBool();
    }
    QVariant vUseCache(UseCache);
    vUseCache = psiOptions->getPluginOption(constUseCache);
    if(!vUseCache.isNull()) {
        UseCache = vUseCache.toBool();
    }
    QVariant vUpdateInterval(UpdateInterval);
    vUpdateInterval = psiOptions->getPluginOption(constUpdateInterval);
    if(!vUpdateInterval.isNull()) {
        UpdateInterval = vUpdateInterval.toInt();
    }
    QVariant vLastUpdate(LastUpdate);
    vLastUpdate = psiOptions->getPluginOption(constLastUpdate);
    if(!vLastUpdate.isNull()) {
        LastUpdate = vLastUpdate.toString();
    }
    QVariant vPopupNotify(PopupNotify);
    vPopupNotify = psiOptions->getPluginOption(constPopupNotify);
    if(!vPopupNotify.isNull()) {
        PopupNotify = vPopupNotify.toBool();
    }
    QVariant vDialogNotify(DialogNotify);
    vDialogNotify = psiOptions->getPluginOption(constDialogNotify);
    if(!vDialogNotify.isNull()) {
        DialogNotify = vDialogNotify.toBool();
    }

    SoundFile = psiOptions->getPluginOption(constSoundFile, QVariant(SoundFile)).toString();

    Dir = AppInfoHost->appVCardDir() + QDir::separator() + "Birthdays";
    QDir BirthDay(Dir);
    if(!BirthDay.exists(Dir)) {
        BirthDay.mkdir(Dir);
        return enabled;
    }
    if(StartCheck && !CheckFromRoster) {
        if((LastCheck.toLong() + Interval) <= QDateTime::currentDateTime().toString("yyyyMMddhh").toLong()) {
            Check();
            LastCheck = QDateTime::currentDateTime().toString("yyyyMMddhh");
            vLastCheck = LastCheck;
            psiOptions->setPluginOption(constLastCheck, vLastCheck);
        }
    }
}
  return enabled;
}

bool Reminder::disable() {
	enabled = false;        
	return true;
}

QWidget* Reminder::options() {
    if(!enabled) {
    return 0;
}
    QWidget *options = new QWidget();
    QVBoxLayout *vlayout = new QVBoxLayout(options);
    DaysWidget = new QSpinBox();
    DaysWidget->setMaximum(60);
    DaysWidget->setMinimum(1);
    DaysWidget->setValue(Days);
    IntervalWidget = new QSpinBox();
    IntervalWidget->setMinimum(1);
    IntervalWidget->setMaximum(24);
    IntervalWidget->setValue(Interval);
    timeoutWidget = new QSpinBox();    
    timeoutWidget->setMinimum(-1);
    timeoutWidget->setValue(timeout);
    UpdateIntervalWidget = new QSpinBox();
    UpdateIntervalWidget->setMinimum(0);
    UpdateIntervalWidget->setValue(UpdateInterval);
    QHBoxLayout *UpdateIntervalLayout = new QHBoxLayout;
    UpdateIntervalLayout->addWidget(new QLabel(tr("Update birthdays every")));
    UpdateIntervalLayout->addWidget(UpdateIntervalWidget);
    UpdateIntervalLayout->addWidget(new QLabel(tr("days (0 - automatic update disabled)")));
    UpdateIntervalLayout->addStretch();
    UseCacheWidget = new QCheckBox(tr("Use vCards cache"));
    UseCacheWidget->setChecked(UseCache);
    DialogNotifyWidget = new QCheckBox(tr("Notify with notification window"));
    DialogNotifyWidget->setChecked(DialogNotify);
    PopupNotifyWidget = new QCheckBox(tr("Notify with popup"));
    PopupNotifyWidget->setChecked(PopupNotify);
    QPushButton *CheckButton = new QPushButton(tr("Check Birthdays"));
    QPushButton *UpdateButton = new QPushButton(tr("Update Birthdays"));
    QPushButton *ClearCacheButton = new QPushButton(tr("Clear Birthdays Cache"));
    QHBoxLayout *layout = new QHBoxLayout();
    vlayout->addWidget(new QLabel(tr("If you use this plugin at first time, make sure that all your accounts \nis online and then press \"Update Birthdays\" button. It takes some time.")));
    layout->addWidget(UpdateButton);
    layout->addWidget(ClearCacheButton);
    layout->addStretch();
    layout->addWidget(CheckButton);
    vlayout->addLayout(layout);
    QHBoxLayout *spinLayout = new QHBoxLayout();    
    spinLayout->addWidget(new QLabel(tr("Start notifying")));
    spinLayout->addWidget(DaysWidget);
    spinLayout->addWidget(new QLabel(tr("days in advance")));
    spinLayout->addStretch();
    QHBoxLayout *IntervalLayout = new QHBoxLayout();
    IntervalLayout->addWidget(new QLabel(tr("Check birthdays every")));
    IntervalLayout->addWidget(IntervalWidget);
    IntervalLayout->addWidget(new QLabel(tr("hours")));
    IntervalLayout->addStretch();
    QHBoxLayout *timeoutLayout = new QHBoxLayout();
    timeoutLayout->addWidget(new QLabel(tr("Show popup/notification window")));
    timeoutLayout->addWidget(timeoutWidget);
    timeoutLayout->addWidget(new QLabel(tr("sec (-1=infinite)")));
    timeoutLayout->addStretch();
    StartCheckWidget = new QCheckBox(tr("Check birthdays on startup"));
    StartCheckWidget->setChecked(StartCheck);
    StartCheckWidget->setEnabled(!CheckFromRoster);
    CheckFromRosterWidget = new QCheckBox(tr("Remind for contacts from active accounts only"));
    CheckFromRosterWidget->setChecked(CheckFromRoster);

    SoundFileWidget = new QLineEdit;
    SoundFileWidget->setText(SoundFile);
    QPushButton *chooseSound = new QPushButton;
    chooseSound->setIcon(IcoHost->getIcon("psi/browse"));
    QPushButton *playSound = new QPushButton;
    playSound->setIcon(IcoHost->getIcon("psi/play"));
    QHBoxLayout *sLayout = new QHBoxLayout;
    sLayout->addWidget(new QLabel(tr("Play sound:")));
    sLayout->addWidget(SoundFileWidget);
    sLayout->addWidget(chooseSound);
    sLayout->addWidget(playSound);

    QLabel *wikiLink = new QLabel(tr("<a href=\"http://code.google.com/p/psi-dev/wiki/plugins#Birthday_Reminder_Plugin\">Wiki (Online)</a>"));
    wikiLink->setOpenExternalLinks(true);

    QGridLayout *grid = new QGridLayout;

    grid->addWidget(PopupNotifyWidget,1,0);
    grid->addWidget(DialogNotifyWidget,1,1);
    grid->addWidget(UseCacheWidget,2,0);
    grid->addWidget(StartCheckWidget,2,1);

    vlayout->addLayout(spinLayout);
    vlayout->addLayout(IntervalLayout);
    vlayout->addLayout(UpdateIntervalLayout);
    vlayout->addLayout(timeoutLayout);
    vlayout->addWidget(CheckFromRosterWidget);
    vlayout->addLayout(grid);
    vlayout->addLayout(sLayout);
    vlayout->addStretch();
    vlayout->addWidget(wikiLink);

    connect(UpdateButton,SIGNAL(released()),SLOT(UpdateVCard()));
    connect(CheckButton,SIGNAL(released()),SLOT(Check()));
    connect(CheckFromRosterWidget, SIGNAL(clicked()), SLOT(CheckFromRosterWidgetIsChecked()));
    connect(ClearCacheButton, SIGNAL(released()), SLOT(clearCache()));
    connect(playSound, SIGNAL(released()), this, SLOT(checkSound()));
    connect(chooseSound, SIGNAL(released()), this, SLOT(getSound()));

    return options;
}

bool Reminder::incomingStanza(int account, const QDomElement& stanza) {
    Q_UNUSED(account);
     if (enabled) {
         if(stanza.tagName() == "iq") {             
             if(stanza.attribute("id") == id) {
                 QDomNode VCard = stanza.firstChild();
                 QDomElement BDay = VCard.firstChildElement("BDAY");
                 if(!BDay.isNull()) {
                     QString Jid = stanza.attribute("from");
                     QString Nick = VCard.firstChildElement("NICKNAME").text();
                     QString Date = BDay.text();
                     if(Date != "") {                         
                         Jid.replace("@", "_at_");
                         QFile file(Dir + QDir::separator() + Jid);
                         if(file.open(QIODevice::ReadWrite)) {
                             QTextStream out(&file);
                             out.setGenerateByteOrderMark(false);
                             out << Date << "__" << Nick << endl;
                         }
                     }
                 }
                 return true;
             }
         }
         if(stanza.tagName() == "presence") {
          if((LastCheck.toLong() + Interval) <= QDateTime::currentDateTime().toString("yyyyMMddhh").toLong()) {
            Check();
            LastCheck = QDateTime::currentDateTime().toString("yyyyMMddhh");
            QVariant vLastCheck(LastCheck);
            psiOptions->setPluginOption(constLastCheck, vLastCheck);
         }
          if(UpdateInterval) {
              if((LastUpdate.toLong() + UpdateInterval) <= QDateTime::currentDateTime().toString("yyyyMMddhh").toLong()) {
                  UpdateVCard();
                  LastUpdate = QDateTime::currentDateTime().toString("yyyyMMddhh");
                  QVariant vLastUpdate(LastUpdate);
                  psiOptions->setPluginOption(constLastUpdate, vLastUpdate);
              }
         }
        }
     }
     return false;
 }

void Reminder::setAccountInfoAccessingHost(AccountInfoAccessingHost* host) {
     AccInfoHost = host;
 }

void Reminder::setApplicationInfoAccessingHost(ApplicationInfoAccessingHost* host) {
     AppInfoHost = host;
 }

void Reminder::applyOptions() {
    if(!DaysWidget || !IntervalWidget || !timeoutWidget || !StartCheckWidget || !CheckFromRosterWidget
        || !UseCacheWidget || !UpdateIntervalWidget || !DialogNotifyWidget || !PopupNotifyWidget || !SoundFileWidget) {
        return;
    }
    QVariant vDays(DaysWidget->value());
    psiOptions->setPluginOption(constDays, vDays);
    Days = vDays.toInt();
    QVariant vInterval(IntervalWidget->value());
    psiOptions->setPluginOption(constInterval, vInterval);
    Interval = vInterval.toInt();
    QVariant vtimeout(timeoutWidget->value());
    psiOptions->setPluginOption(consttimeout, vtimeout);
    timeout = vtimeout.toInt();
    QVariant vStartCheck(StartCheckWidget->isChecked());
    psiOptions->setPluginOption(constStartCheck, vStartCheck);
    StartCheck = vStartCheck.toBool();
    QVariant vCheckFromRoster(CheckFromRosterWidget->isChecked());
    psiOptions->setPluginOption(constCheckFromRoster, vCheckFromRoster);
    CheckFromRoster = vCheckFromRoster.toBool();
    QVariant vUseCache(UseCacheWidget->isChecked());
    psiOptions->setPluginOption(constUseCache, vUseCache);
    UseCache = vUseCache.toBool();
    QVariant vUpdateInterval(UpdateIntervalWidget->value());
    psiOptions->setPluginOption(constUpdateInterval, vUpdateInterval);
    UpdateInterval = vUpdateInterval.toInt();
    QVariant vDialogNotify(DialogNotifyWidget->isChecked());
    psiOptions->setPluginOption(constDialogNotify, vDialogNotify);
    DialogNotify = vDialogNotify.toBool();
    QVariant vPopupNotify(PopupNotifyWidget->isChecked());
    psiOptions->setPluginOption(constPopupNotify, vPopupNotify);
    PopupNotify = vPopupNotify.toBool();
    QVariant vSoundFile(SoundFileWidget->text());
    psiOptions->setPluginOption(constSoundFile, vSoundFile);
    SoundFile = vSoundFile.toString();
}

void Reminder::restoreOptions() {
    if(!DaysWidget || !IntervalWidget || !timeoutWidget || !StartCheckWidget || !CheckFromRosterWidget
        || !UseCacheWidget || !UpdateIntervalWidget || !DialogNotifyWidget || !PopupNotifyWidget || !SoundFileWidget) {
        return;
    }
    QVariant vDays(Days);
    vDays = psiOptions->getPluginOption(constDays);
    if(!vDays.isNull()) {
        DaysWidget->setValue(vDays.toInt());
    }
    else {
        DaysWidget->setValue(Days);
    }
    QVariant vInterval(Interval);
    vInterval = psiOptions->getPluginOption(constInterval);
    if(!vInterval.isNull()) {
        IntervalWidget->setValue(vInterval.toInt());
    }
    else {
        IntervalWidget->setValue(Interval);
    }
    QVariant vtimeout(timeout);
    vtimeout = psiOptions->getPluginOption(consttimeout);
    if(!vtimeout.isNull()) {
        timeoutWidget->setValue(vtimeout.toInt());
    }
    else {
        timeoutWidget->setValue(timeout);
    }
    QVariant vStartCheck(StartCheck);
    vStartCheck = psiOptions->getPluginOption(constStartCheck);
    if(!vStartCheck.isNull()) {
        StartCheckWidget->setChecked(vStartCheck.toBool());
    }
    else {
        StartCheckWidget->setChecked(StartCheck);
    }
    QVariant vCheckFromRoster(CheckFromRoster);
    vCheckFromRoster = psiOptions->getPluginOption(constCheckFromRoster);
    if(!vCheckFromRoster.isNull()) {
        CheckFromRosterWidget->setChecked(vCheckFromRoster.toBool());
    }
    else {
        CheckFromRosterWidget->setChecked(CheckFromRoster);
    }
    QVariant vUseCache(UseCache);
    vUseCache = psiOptions->getPluginOption(constUseCache);
    if(!vUseCache.isNull()) {
        UseCacheWidget->setChecked(vUseCache.toBool());
    }
    else {
        UseCacheWidget->setChecked(UseCache);
    }
    QVariant vUpdateInterval(UpdateInterval);
    vUpdateInterval = psiOptions->getPluginOption(constUpdateInterval);
    if(!vUpdateInterval.isNull()) {
        UpdateIntervalWidget->setValue(vUpdateInterval.toInt());
    }
    else {
        UpdateIntervalWidget->setValue(UpdateInterval);
    }
    QVariant vDialogNotify(DialogNotify);
    vDialogNotify = psiOptions->getPluginOption(constDialogNotify);
    if(!vDialogNotify.isNull()) {
        DialogNotifyWidget->setChecked(vDialogNotify.toBool());
    }
    else {
        DialogNotifyWidget->setChecked(DialogNotify);
    }
    QVariant vPopupNotify(PopupNotify);
    vPopupNotify = psiOptions->getPluginOption(constPopupNotify);
    if(!vPopupNotify.isNull()) {
        PopupNotifyWidget->setChecked(vPopupNotify.toBool());
    }
    else {
        PopupNotifyWidget->setChecked(PopupNotify);
    }
    QVariant vSoundFile(SoundFile);
    vSoundFile = psiOptions->getPluginOption(constSoundFile);
    if(!vSoundFile.isNull()) {
        SoundFileWidget->setText(vSoundFile.toString());
    }
    else {
        SoundFileWidget->setText(SoundFile);
    }
}

void Reminder::setStanzaSendingHost(StanzaSendingHost *host) {
    StanzaHost = host;
}

void Reminder::UpdateVCard() {
    if(enabled) {
        if(UseCache) {
            QString path = AppInfoHost->appVCardDir();
            QDir dir(path);
            foreach (QString filename, dir.entryList(QDir::Files)) {
                QFile file(path + QDir::separator() + filename);
                if(file.open(QIODevice::ReadOnly)) {
                    QTextStream in(&file);
                    QDomDocument doc;
                    doc.setContent(in.readAll());
                    QDomElement vCard = doc.documentElement();
                    QDomElement BDay = vCard.firstChildElement("BDAY");
                    if(!BDay.isNull()) {
                        QString Nick = vCard.firstChildElement("NICKNAME").text();
                        QString Date = BDay.text();
                        if(Date != "") {
                            filename.replace("%5f", "_");
                            filename.replace("%2d", "-");
                            filename.remove(".xml");
                            QFile file(Dir + QDir::separator() + filename);
                            if(file.open(QIODevice::ReadWrite)) {
                                QTextStream out(&file);
                                out.setGenerateByteOrderMark(false);
                                out << Date << "__" << Nick << endl;
                            }
                        }
                    }
                 }
            }
        }

    int accs = -1;
    bool b = true;
    while(b) {
        QStringList Jids = AccInfoHost->getRoster(++accs);
        if(!Jids.isEmpty()) {
            if(Jids.takeFirst() == "-1") {
                b = false;
            }
            else {
                if(AccInfoHost->getStatus(accs) != "offline") {
                    foreach(QString Jid, Jids) {
                        QString text = "<iq type=\"get\" to=\"" + Jid + "\" id=\"" + id + "\"><vCard xmlns=\"vcard-temp\" version=\"2.0\" prodid=\"-//HandGen//NONSGML vGen v1.0//EN\" /></iq>";
                        StanzaHost->sendStanza(accs, text);
                    }
                }
            }
        }               
    }   
}
}

QString Reminder::CheckBirthdays() {
    QSet<QString> Roster_;
    if(CheckFromRoster) {
        int accs = -1;
        bool b = true;
        while(b) {
            QStringList Jids = AccInfoHost->getRoster(++accs);
            if(!Jids.isEmpty()) {
                if(Jids.takeFirst() == "-1") {
                    b = false;
                }
                else {
                    Roster_ += Jids.toSet();
                }
            }
        }
    }
    QString CheckResult = "";
    if(enabled) {
    QDir dir(Dir);
    foreach(QString jid, dir.entryList(QDir::Files)) {
      if(jid.contains("_at_")) {
        QFile file(Dir + QDir::separator() + jid);
        if(file.open(QIODevice::ReadOnly)) {
            QTextStream in(&file);
            QString line = in.readLine();
            QStringList fields = line.split("__");
            QString Date = fields.takeFirst();
            QString Nick = "";
            if(!fields.isEmpty()) {
                Nick = fields.takeFirst();
            }
            QDate Birthday = QDate::currentDate();
            if(Date.contains("-")) {
                Birthday = QDate::fromString(Date, "yyyy-MM-dd");
            } else {
                if(Date.contains(".")) {
                    Birthday = QDate::fromString(Date, "d.MM.yyyy");
                } else {
                    if(Date.contains("/")) {
                        Birthday = QDate::fromString(Date, "d/MM/yyyy");
                    }
                }
            }
            QDate current = QDate::currentDate();
            if(current != Birthday) {
                int years = current.year() - Birthday.year();
                Birthday = Birthday.addYears(years);
                int daysTo = current.daysTo(Birthday);
                QString days;
                days.setNum(daysTo);
                jid.replace("_at_", "@");
                if(!CheckFromRoster || Roster_.contains(jid)) {
                    if(daysTo == 0) {
                        CheckResult += Nick + " (" + jid + ") " + tr("celebrates birthday today!") + "\n";
                    } else {
                        if(daysTo <= Days && daysTo > 0) {
                            CheckResult += Nick + " (" + jid + ") " + tr("celebrates birthday in ") + days + tr(" day(s)") + "\n";
                        } else {
                            if(daysTo == -1) {
                                CheckResult += Nick + " (" + jid + ") " + tr("celebrates birthday yesterday.") + "\n";
                            }
                        }
                    }
                }
            }
        }
      }
    }
}
    return CheckResult;
}

void Reminder::optionChanged(const QString &option) {
    Q_UNUSED(option);
}

void Reminder::setOptionAccessingHost(OptionAccessingHost *host) {
    psiOptions = host;
}

void Reminder::setIconFactoryAccessingHost(IconFactoryAccessingHost* host) {
    IcoHost = host;
}

bool Reminder::Check() {
    bool isBirthday = false;
    QString text = CheckBirthdays();
    if(text == "") return isBirthday;
    text.chop(1);
    isBirthday = true;
    if(DialogNotify) {
        if(window) {
            timer->stop();
            delete(window);
            window = 0;
        }
        window = new QDialog();
        window->setWindowTitle("Birthday Reminder Plugin");
        QVBoxLayout *layout = new QVBoxLayout(window);
        QHBoxLayout *layoutButton = new QHBoxLayout();        
        Close = new QPushButton(tr("Close"));
        QPushButton *DontRemind = new QPushButton(tr("Don't remind today"));
        QPushButton *stopTimer = new QPushButton(tr("Stop Timer"));
        layout->addWidget(new QLabel(text));
        layoutButton->addWidget(DontRemind);
        layoutButton->addStretch();
        layoutButton->addWidget(stopTimer);        
        layoutButton->addWidget(Close);        
        layout->addLayout(layoutButton);
        timer = new QTimer(window);
        if(timeout != -1) {
            timeout2 = timeout;
            QString textClose;
            textClose.setNum(timeout2);
            textClose = tr("Close ") + textClose;
            connect(timer, SIGNAL(timeout()), SLOT(updateTimer()));
            timer->start(1000);
            Close->setText(textClose);
        }
        connect(Close, SIGNAL(released()), SLOT(close()));
        connect(DontRemind, SIGNAL(released()), SLOT(setDontCheck()));
        connect(stopTimer, SIGNAL(released()), SLOT(stopTimer()));
        window->setWindowModality(Qt::WindowModal);        
        window->show();
    }

    if(psiOptions->getGlobalOption("options.ui.notifications.sounds.enable").toBool())
        playSound(SoundFile);

    if(PopupNotify) {
        QVariant delay(timeout*1000);
        int delay_ = psiOptions->getGlobalOption("options.ui.notifications.passive-popups.delays.status").toInt();
        psiOptions->setGlobalOption("options.ui.notifications.passive-popups.delays.status", delay);

        bool enbl_ = psiOptions->getGlobalOption("options.ui.notifications.passive-popups.enabled").toBool();
        QVariant enbl(true);
        psiOptions->setGlobalOption("options.ui.notifications.passive-popups.enabled", enbl);

        text = text.replace("\n", "<br>");
        popup->initPopup(text, tr("Birthday Reminder"), "reminder/birthdayicon");

        delay = QVariant(delay_);
        psiOptions->setGlobalOption("options.ui.notifications.passive-popups.delays.status", delay);

        enbl = QVariant(enbl_);
        psiOptions->setGlobalOption("options.ui.notifications.passive-popups.enabled", enbl);
    }

    return isBirthday;
}

void Reminder::setDontCheck() {
    QDateTime Date = QDateTime::currentDateTime();
    Date.setTime(QTime::fromString("010000", "hhmmss"));
    Date = Date.addDays(1);
    LastCheck = Date.toString("yyyyMMddhh");
    QVariant vLastCheck(LastCheck);
    psiOptions->setPluginOption(constLastCheck, vLastCheck);
    timer->stop();
    delete window;
    window = 0;
}

void Reminder::updateTimer() {
     QString textClose;
     textClose.setNum(--timeout2);
     textClose = tr("Close ") + textClose;
     if(timeout2 > 0) {
         Close->setText(textClose);
     }
     else {
         timer->stop();
         delete window;
         window = 0;
     }
}

void Reminder::close() {
    timer->stop();
    delete window;
    window = 0;
}

void Reminder::stopTimer() {
    timer->stop();
    Close->setText(tr("Close"));
}

void Reminder::CheckFromRosterWidgetIsChecked() {
    if(CheckFromRosterWidget->isChecked()) {
        StartCheckWidget->setEnabled(false);
    } else {
        StartCheckWidget->setEnabled(true);
    }
}

void Reminder::clearCache() {
    QDir dir(Dir);
    foreach(QString file, dir.entryList(QDir::Files)) {
        QFile File(Dir + QDir::separator() + file);
        if(File.open(QIODevice::ReadWrite)) {
            File.remove();
        }
    }
    LastUpdate = "1901010101";
    QVariant vLastUpdate(LastUpdate);
    psiOptions->setPluginOption(constLastUpdate, vLastUpdate);
}

void Reminder::setPopupAccessingHost(PopupAccessingHost* host) {
    popup = host;
}

void Reminder::playSound(QString f) {
    QFile file(f);
    if(!file.exists()) {
        QString newF = AppInfoHost->appResourcesDir() + "/" + f;
        file.setFileName(newF);
        if(!file.exists()) {
            newF = AppInfoHost->appHomeDir() + "/" + f;
            file.setFileName(newF);
            if(!file.exists())
                return;
        }
    }

    QString str = file.fileName();

    QString player_;
    if (QFile("/proc/asound").exists()) {
        player_ =  "aplay";
    } else {
        player_ =  "play";
    }

#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
        QSound::play(str);
#else
        QString player = psiOptions->getGlobalOption("options.ui.notifications.sounds.unix-sound-player").toString();
        if (player == "") player = player_;
        QStringList args = player.split(' ');
        args += str;
        QString prog = args.takeFirst();
        QProcess::startDetached(prog, args);
#endif

}

void Reminder::getSound() {
    QString fileName = QFileDialog::getOpenFileName(0,tr("Choose a sound file"),"", tr("Sound (*.wav)"));
    if(fileName.isEmpty()) return;
    SoundFileWidget->setText(fileName);
}

void Reminder::checkSound() {
    playSound(SoundFileWidget->text());
}

QString Reminder::pluginInfo() {
	return tr("Author: ") +  "Dealer_WeARE\n"
			+ tr("Email: ") + "wadealer@gmail.com\n\n"
			+ trUtf8("This plugin is designed to show reminders of upcoming birthdays.\n"
			 "The first time you install this plugin, you need to log on to all of your accounts, go to the plugin settings and click \"Update Birthdays\"."
			 "The plugin will then collect the information about the birthdays of all the users in your roster, but when the 'Use vCards cache' option is"
			 "selected, the users' vCards that are cached on your hard disk will be used. ");
}

#include "birthdayreminderplugin.moc"
