/***************************************************************************
 *   Copyright (C) 2007-2008 by Anistratov Oleg                            *
 *   ower@users.sourceforge.net                                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation;                         *
 *                                                                         *
 *   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.                          *
 *                                                                         *
 ***************************************************************************/

#ifndef PREFERENCES_H
#define PREFERENCES_H

#include <QColor>
#include <QHostAddress>
#include <QKeySequence>
#include <QDir>
#include <QVariant>
#include <QSettings>

class UserListIconFormat;
class MessageFilter;
class Option;

/**
  @author Anistratov Oleg <ower@users.sourceforge.net>
*/
// TODO finish moving all possible settings to m_options an m_generalOptions
class QChatSettings
{
  public:
    enum Mode{Serverless, Server, Combined};

    /** @enum SmilesPolicy
        NoSmiles - never use graphic smiles
        DontUseSmilesFromSender - never use smiles from sender
        UseSmilesFromSender - use smiles from sender only if smile isn't present in local smile theme
        AlwaysUseSmilesFromSender - use smiles from sender even if smile is present in local smile theme
    */
    enum SmilesPolicy{NoSmiles = 0, DontUseSmilesFromSender = 1, UseSmilesFromSender = 2, AlwaysUseSmilesFromSender = 3};

  private:
    static QChatSettings* m_currentSettings;
    static QChatSettings* m_defaultSettings;
    static QString m_profileName;
    static QString m_settingsDir;
    static QString m_loggingDir;

    // Messages
    QColor m_myMsgsColor;
    QColor m_sysMsgsColor;
    QColor m_baseMsgColor;

    MessageFilter* m_messageFilter;

    // Network
    static QHostAddress m_servBroadcast;
    /// ip list for using instead broadcasting
    static QList<QHostAddress> m_ipList;

    // Status
    QString m_statusDescription[6];
    QStringList m_statusDescriptions;

    // Now Listening
    /// 1 - send with message, 2 - change status, (1 | 2) - both
    int m_nlMode;
    /*static*/ QString m_nowListening;

    // Request message history
    /// -1 - request maximum messages
    int m_nHistoryMsgs;
    /// how long we will be wait answer for 'messages number request'
    int m_historyReqTimeout;

    // Smiles
    QString      m_smilesThemePath;
    SmilesPolicy m_smilesPolicy;

    // Shortcuts
    QMap< QString, QList<QKeySequence> > m_shortcuts;
    QMap< QString, QStringList>          m_shortcutsInfo;
    // Users List
    int m_usersListRefreshInterval;
    int m_usersListDeepRefreshInterval;

    QString m_executeCommandOnIncomingMsg;

    UserListIconFormat* m_iconFormat;

    static Mode m_mode;

    int m_toolbarIconsSize;

    QMap<QString, Option*> m_options;
    static QMap<QString, Option*> m_generalOptions;

  public:
    QChatSettings();
    ~QChatSettings(){};

    void initOptions();
    static void initGeneralOptions();

    void         setOption(const QString&, QVariant);
    QVariant     option(const QString&) const;
    bool         boolOption(const QString&) const;
    qint64       intOption(const QString&) const;
    QString      strOption(const QString&) const;
    QHostAddress hostAddressOption(const QString&) const;

    static QString defaultSmilesDir();
    static QString defaultSmilesDir(QList<QDir>);

    void saveOptions(QSettings*);
    void saveGeneralOptions(QSettings*);
    void loadOptions(QSettings*);
    void loadGeneralOptions(QSettings*);
    void save(QSettings*, QMap<QString, Option*>);
    void load(QSettings*, QMap<QString, Option*>&);

    static void setSettingsDir    (const QString & dir){m_settingsDir = dir;}

    void setMyColor        (const QColor & color)   {m_myMsgsColor   = color;}
    void setSysColor       (const QColor & color)   {m_sysMsgsColor  = color;}
    void setBaseColor      (const QColor & color)   {m_baseMsgColor  = color;}

    void setStatusDescription(const QString & descr, int status);

    static QHostAddress realBroadcast();
    static QHostAddress broadcast();
    static const QString & settingsDir   (){return m_settingsDir;}

    const QString & statusDescription(int status) const;
    const QColor  & sysColor () const {return m_sysMsgsColor;}
    const QColor  & myColor  () const {return m_myMsgsColor;}
    const QColor  & baseColor() const {return m_baseMsgColor;}

    void setNHistoryMsgs(int value){m_nHistoryMsgs = value;}
    int  nHistoryMsgs() const {return m_nHistoryMsgs;}

    void setHistoryReqTimeout(int value){m_historyReqTimeout = value;}
    int historyReqTimeout() const {return m_historyReqTimeout;}

    void setNlMode(int value){Q_ASSERT(value >= 0 && value <= 3); m_nlMode = value;}
    int nlMode() const{return m_nlMode;}

    void setSmilesThemePath(const QString & value)
    {m_smilesThemePath = value; if(!value.isEmpty() && value[value.size() - 1] != '/') m_smilesThemePath += "/";}
    const QString & smilesThemePath() const {return m_smilesThemePath;}

    void setExecuteCommandOnIncomingMsg(const QString& value){m_executeCommandOnIncomingMsg = value;}
    const QString & executeCommandOnIncomingMsg() const {return m_executeCommandOnIncomingMsg;}

    void setUsersListRefreshInterval(int value){m_usersListRefreshInterval = value;}
    int usersListRefreshInterval() const {return m_usersListRefreshInterval;}

    void setUsersListDeepRefreshInterval(int value){m_usersListDeepRefreshInterval = value;}
    int usersListDeepRefreshInterval() const {return m_usersListDeepRefreshInterval;}

    void setStatusDescriptions(const QStringList & value){m_statusDescriptions = value;}
    void appendStatusDescription(const QString & value);
    void removeStatusDescription(const QString & value){m_statusDescriptions.removeAll(value);}
    QStringList statusDescriptions() const {return m_statusDescriptions;}

    void setNowListening(const QString& value){m_nowListening = value;}
    QString nowListening() const {return m_nowListening;}

    void setMode(Mode m) {m_mode = m;}
    Mode mode() const {return m_mode;}

    static void addIpListEntry(const QHostAddress& addr)
    {if(!m_ipList.contains(addr)) m_ipList.append(addr);}

    static void removeIpListEntry(const QHostAddress& addr)
    {m_ipList.removeAll(addr);}

    static const QList<QHostAddress> ipList(){return m_ipList;}
    static void clearIpList(){m_ipList.clear();}

    static void setSettings(QChatSettings* value){m_currentSettings = value;}
    static QChatSettings* settings();

    static QString profileName() {return m_profileName;}
    static void setProfileName(const QString & name){m_profileName = name;}

    void setIconFormat(UserListIconFormat* theValue){m_iconFormat = theValue;}
    UserListIconFormat* iconFormat() const {return m_iconFormat;}

    void setToolbarIconsSize(int theValue){m_toolbarIconsSize = theValue;}
    int toolbarIconsSize() const {return m_toolbarIconsSize;}

    // Shortcuts
    void createShortcut(const QString&, const QString&, const QString&, const QKeySequence&);

    void addShortcut(const QString& shrtctname, const QKeySequence& shrtct)
    {if(!m_shortcuts[shrtctname].contains(shrtct)) m_shortcuts[shrtctname].append(shrtct);}

    void setShortcut(const QString& shrtctname, const QKeySequence& shrtct)
    {m_shortcuts[shrtctname].clear(); m_shortcuts[shrtctname].append(shrtct);}

    void clearShortcut(const QString& shrtctname){m_shortcuts[shrtctname].clear();}

    QList<QKeySequence> shortcuts(const QString& shctname) const {return m_shortcuts[shctname];}
    QKeySequence shortcut(const QString& shctname) const
    {if(m_shortcuts[shctname].size() > 0) return m_shortcuts[shctname][0]; return QKeySequence();}

    const QMap< QString, QList<QKeySequence> >& allShortcuts(){return m_shortcuts;}
    void setAllShortcuts(const QMap< QString, QList<QKeySequence> >& value){m_shortcuts = value;}

    const QString& shortcutDisplayName(const QString& name)
    {Q_ASSERT(m_shortcutsInfo.value(name).size() > 0); return m_shortcutsInfo.value(name)[0];}

    const QString& shortcutGroup(const QString& name)
    {Q_ASSERT(m_shortcutsInfo.value(name).size() > 1); return m_shortcutsInfo.value(name)[1];}

    bool shortcutExists(const QString& name)
    {return m_shortcutsInfo.value(name).size();}

    void setSmilesPolicy(SmilesPolicy theValue ){m_smilesPolicy = theValue;}
    void setSmilesPolicy(int theValue ){m_smilesPolicy = (QChatSettings::SmilesPolicy)theValue;}
    SmilesPolicy smilesPolicy() const {return m_smilesPolicy;}

    void setMessageFilter(MessageFilter* theValue){m_messageFilter = theValue;}
    MessageFilter* messageFilter() const {return m_messageFilter;}

    static void setLoggingDir(const QString& theValue){m_loggingDir = theValue;}
    static QString loggingDir(){return m_loggingDir;}
};

#endif
