/***************************************************************************
                          c6.h  -  description
                             -------------------
    begin                : Fri Feb 14 16:20:30 CET 2003
    copyright            : (C) 2003 by Giorgio A.
    email                : openc6@hotmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef C6_H
#define C6_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

class QString;
class C6_Main;
class C6Proto;
class C6ChatRoom;
class C6Users;
class C6Login;
class C6Search;
class C6Profile;
class C6Report;
class C6RoomList;
class ChatView;
class QHostAddress;
class C6About;
class C6TabQWidget;
class C6TabWidget;
class QGridLayout;
class QTimer;
class C6Conf;

#include <vector>
#include "c6proto.h"
#include "c6global.h"
#include <qstringlist.h>
#include <qptrlist.h>

class C6 : public QObject
{
    Q_OBJECT
public:
    /** construtor */
    C6();
    /** destructor */
    ~C6();

    static C6* self();
    static C6* getInstance();
    
    QWidget* getMainDialogPtr();    
    
    QApplication* loadPlugin(QString plugin);
    void forceClientExit();
    void restoreWidget(QWidget &widget);
    void setTabTo(QString const &nick);
    QWidget *getTabDialogPtr()
    {
        return reinterpret_cast<QWidget*>(tabbedDialog);
    }
    QWidget *getLoginWidget()
    {
        return  reinterpret_cast<QWidget*>(loginDialog);
    }

    bool isStartedApp() const
    {
        return(_startedApp);
    }
    void setStartedApp()
    {
        _startedApp = true;
    }

public slots: // Public slots
    void showShortProfile(QString const& nick);
    void ConnectClicked(bool);
    void showAbout();
    /** This receive signal from socket and show login error */
    void signalError(int err,const QString& error = QString::null);
    /** called when online */
    void imOnLine();
    /** handle root popup menu  */
    void doMainAction(const QString & child,USER_MENU_ACTIONS action,QString root);
    /** write log file for each conversation */
    void chatWriteOnLog(QString &,QString &,QString &);
    /** write log file for each romm */
    void roomWriteOnLog(QString&,QString&);
    /** write on system log file */
    void WriteOnSystemLog(QString);
    /** open the configuration dialog */
    void openConfig();
    /** handle menu cases from chatview  */
    void HandleMenuCommand(int);
    void ShowUserLog(QString user);
    void playWav(QString path);

private: // Private attributes
    C6_Main* mainDialog;
    C6Proto* _c6socket;
    QPtrList<ChatView> ChatForm;
    QPtrList<C6ChatRoom> chatRoomList;
    QStringList passwList,userList;
    C6Login *loginDialog;   
    C6Report *reportDialog;
    C6Search *searchDialog;
    C6Profile *profileDialog;
    C6About *aboutDialog;
    C6RoomList *roomList;
    C6ChatRoom *chatRoom;
    C6TabQWidget *tabbedDialog;
    C6TabWidget *tabHandler;
    QGridLayout *tabLayout;
    bool flashing;
    bool fastReconnect;
    int fastNickID;
    std::vector<int> _portBindChatVector;
    QStringList autoRoom;
    bool _startedApp;
    QTimer *_idleTimer;
    C6Global* _global;
    static C6* _self;
      
private slots: // Private slots
    void currentTabChanged(QWidget*);
    void exitClicked();
    void restoreLogin();
    /** set user online/offline */
    bool setNetfriendProperty(C6Users const & c6user);
    /** Initialize the chat  */
    ChatView* buildChat(const QString & nick,bool receiveEvent = false);
    /** remove the chat view from list  */
    void removeChatFromList(const QString &nick);
    /** receive a message mess from nick
        and update chat view  */
    void receiveChatMessage(QString &nickStr,QString &messStr,C6Proto::C6MessageStyle *style = 0);
    /** check if some user went offline during a chat */
    void notifyOnOfflineStatus(QString const & ,int,bool showMsg = true);
    /** add a nick from chat  */
    void AddNickFromChat(QString &,QString & );
    /** handle offline status when signal received */
    void closeConnection(bool);
    /** request closing the connection  */
    void clientExit();
    void messageSent();
    void userMenuAction(const QString & nick, USER_MENU_ACTIONS select);
    void getUserInfo(const QString &,unsigned char *,int packL=0,bool toGUI=false);
    void fireConnection(QHostAddress ip,int port,QString,QString);
    void sendFile(QString ,QString,int);
    void prepareFileReception(QString&,QString&);
    void updateNetFriendStatus(C6Users::C6UsersVector &,bool);
    void nowSelectUser(unsigned char *data);
    void reloadPassword(const QString & text);
    void sendToRoom(QString & channel,QString &msg,int type);
    void exitFromRoom(QString &);
    void createRoom(const QString& roomName,const QString& caption,bool isPublic,int index,const QString& password);
    void searchRoom(int roomSearchAttribute,unsigned char *property);
    void searchResultReady(std::vector<C6Proto::RoomSearchResult>& result);
    void execUrl(QString & url);
    void enterRoom(const QString& room_name,const QString& password=QString::null);
    void roomEnterInfo(const QString& roomName,const QString& roomTopic,int roomAttribute,int allowedUserRole,QMap<QString,int>& users);  
    void eventFromRoom(QString &room_name,QString &nick,C6Proto::SERVER_COMMAND_ID action);
    void messageFromRoom(QString &room_name,QString &nickfrom,QString &msg);
    void showChatRooms();
    void infoLogin(bool oldAccount);    
    void showRoomLog(QString &name);
    void reconnect(int nick = -1);
    void switchToRoom(QString & room);
    void markAsRead(ChatView *pchat);
    void checkIfIdle();
    void changeMyStatus(C6Users::C6USER_STATUS,const QString& message);
    void sendChatMessage(QString& nick, bool isOnline, QString& message);
    
signals: // Signals
    void saveSpecialList();
    void specialChatNotify(QString nick,C6Users::C6USER_STATUS status);
    void requestProfile(const QString &);
    void notifyReport(QString,QString);
    void queryForRooms();
    void exit_main();

    void online();
    void offline();
    void restoreLoginSession();
    void enqueueIncomingMessage(QString time,QString& nick,void* pchat);
    void chatHasFocus(ChatView*);
    void statusChanged(C6Users::C6USER_STATUS status);
    
private: // Private methods
    C6ChatRoom const *getPtrRoom(QString const &room);
    ChatView const *getChatViewPtr(QString const & nick);
    QStringList getNickStringList();
    void startConnection();
    void loadLoginAccounts();
    void saveCurrentUserDetails();
    /** handle child pop up menu  */
    void doMenuAction(QString const &,USER_MENU_ACTIONS action,QString const& parent = QString::null);
    void addUser(QString const & root,QString const & nick);   
    void addUser(QString const & root,QString const & user,QString const & nick);   
    void removeUser(QString const & nick);
    /** check if nick is in black list  */
    bool IsInBlackList(QString const & nick);
    /** move a nick from a list to another */
    void moveUser(QString nick,QString from,QString to);
    void postConfigureUpdates();
    void hideChildrenDialogs(QWidget * obj);
    void setAllUsersOffline();
    /** get a user status  */
    C6Users::C6USER_STATUS getNetfriendStatus(QString const & nick);
    int messageBox(QString const & cap,QString const & text);
    void showSearchForm();
    int getSuitableBindPort();
    void freeBindPort(int port);    
    void loadPassword(QString login);
    /** import netfriend list from original c6 list */
    void ImportC6List();
    /** show the log view window */
    void ShowLogWin(int choice);
    void loadSpecialList();
    void addToTab(ChatView const *chat,bool setCurrent=false);
    void removeFromTab(ChatView const *chat);
    void initTabStuff();
    void setAwayMode(bool state);
    void playSoundOnReceivedMessage();
    void tryAway(long idleTime);
    void initConnection(QString const & nick,QString const &passw);
    void sendUserList();
    
private slots:
    void closeTab(int tabno);
    void extendedChangeStatus(const C6Users::C6Users &c6user);
    void hideTabWidget();
    void chatIsActive(ChatView*);
    void inviteNetfriend(const QString &room,const QStringList &nick,const QString &message);   
    void applyConfig(C6Conf& conf);
    void parseBuddyList(QByteArray &data);   
    void parseBuddyAuth(QByteArray &data);     
    void parseBuddyConfig(QByteArray &data);          
    void sendGatewayBind(const QString &ip,int port,const QString &nickToGrant);   
    void reloadInitialization();    
    void showReport(const QString& nick,const QString& mess,const QString& timeString = QString::null);   
    
private:
    void addGroup(const QString & group);
    void removeGroup(const QString & group);
    void deleteAllChat();
    void deleteAllRooms();
    void renameGroup(QString const & group);
    void deleteReadChat();
    void changeTabName(ChatView *chat,QString const &caption);
    void saveNetfriendList();   
    bool mergeLocalList(bool firstAttempt = false);
    void addNickDialog(QString const & group);
    void showFullUserProfile(QString const& nick);
    void openChat();
    void calibrateSystemFontSize();   
    void setFontOnWidgets();
private slots:
    void acceptReception(bool accept,const QString & from);
    void acceptAuthorization(bool accept,const QString & from);
    void roomMenuUserAction(const QString& roomName,const QString& nick,USER_MENU_ACTIONS action);
    void askForPassword(const QString& roomName);
    void searchByNick(const QString& nick);
    void userSearchResultsFound(QStringList*,std::vector<C6Users::C6USER_STATUS>);
    void showUserProfile(const QString&,bool full);   
private slots:
    void showMainDialog(int progress);
};

#endif

