#ifndef __VDR_ICQHOOK_H
#define __VDR_ICQHOOK_H


#include <map>


#include <sigc++/signal_system.h>
#include <set>
#include <libicq2000/Client.h>
#include <libicq2000/events.h>

using namespace std;

#include "History.h"
#include "Select.h"
#include "MessageQueue.h"
 
class cTitlebarWnd;
class cMessagelistWnd;
class cContactWnd;
class cStatusbarWnd;
class cNumberList;

enum EConfirmMessage { cmNotConfirmed, cmConfirmed, cmMessage };

class SimpleClient : public SigC::Object, public cThread 
{
private:
  ICQ2000::Client cli;
	Select input;
	std::map<int, SigC::Connection> m_sockets;
  bool acked;
	unsigned int m_iRetries;
  bool m_bStartUpVDR;
	bool m_bRunning;
	bool m_bShutdown;
	MessageQueue m_message_queue;
	std::map<unsigned int, std::string> m_settingsmap; 
	std::map<unsigned int, History *> m_histmap;
  cNumberList *m_pIgnoreList;
  cNumberList *m_pWaitList;
	string  m_basedir;
	string  m_contactdir;
  bool    m_bConnectOnStartup;
  int     m_iDetailInfoUpdateCounter;
  History *m_pLostEventHistory;
  
  cTitlebarWnd    *m_pTitlebarWnd;
  cMessagelistWnd *m_pMessagelistWnd;
  cContactWnd     *m_pContactWnd;
  cStatusbarWnd   *m_pStatusbarWnd;
  ICQ2000::ContactRef m_ActiveContact;

  void connected_cb(ICQ2000::ConnectedEvent *c);
  void disconnected_cb(ICQ2000::DisconnectedEvent *c);
  void logger_cb(ICQ2000::LogEvent *c);
	string get_unique_historyname() throw (std::runtime_error);
	void contactlist_cb(ICQ2000::ContactListEvent *ev);
	void status_change_cb(ICQ2000::StatusChangeEvent *ev);
  void userinfo_change_cb(ICQ2000::UserInfoChangeEvent *ev);
  void self_userinfo_change_cb(ICQ2000::UserInfoChangeEvent *ev);
  void self_status_change_cb(ICQ2000::StatusChangeEvent *ev);
	void message_cb(ICQ2000::MessageEvent *ev);
	void messageack_cb(ICQ2000::MessageEvent *ev);
  void socket_cb(ICQ2000::SocketEvent *ev);
	void select_socket_cb(int fd, Select::SocketInputCondition cond);
/*void want_auto_resp_cb(ICQ2000::ICQMessageEvent *ev);*/
  void server_based_contact_list_cb(ICQ2000::ServerBasedContactEvent *ev);
  void search_result_cb(ICQ2000::SearchResultEvent *ev);
	MessageEvent* convert_libicq2000_event(ICQ2000::MessageEvent *ev);
  bool mkdir_BASE_DIR();
  void saveContact(ICQ2000::ContactRef c, const string& s, bool self);
  void saveSelfContact();
  void loadContactList();
  void loadContact(const string& s, bool self);
  void loadSelfContact();
  void AddToLostEventHistory(ICQ2000::MessageEvent *ev);

public:
  SimpleClient(unsigned int ourUIN, const string pass);
  ~SimpleClient(void);
      
  void SetConnectParameters(unsigned int ourUIN, const string pass);
	void SetStatus(ICQ2000::Status eStatus, bool bInfisible = false);

  void SetTitlebarWnd(cTitlebarWnd *pTitlebarWnd);
  void SetMessagelistWnd(cMessagelistWnd *pMessagelistWnd);
  void SetContactWnd(cContactWnd *pContactWnd);
  void SetStatusbarWnd(cStatusbarWnd *pStatusbarWnd);

  void SetActiveContact(ICQ2000::ContactRef ActiveContact);
  ICQ2000::ContactRef GetActiveContact() { return m_ActiveContact; }
  void SendMessage(ICQ2000::ContactRef c, const std::string& msg, bool multi = false);
  
  ICQ2000::ContactRef GetSelfContact() { return cli.getSelfContact(); }
  ICQ2000::Client *GetClient() { return &cli; }

  void Message(eMessageType MessageType, const char *pMessage, int iSeconds = 5);
  EConfirmMessage Confirm(const char *pMessage, const char *pMessageIfICQClose = NULL, int iSeconds = 10, 
                          bool WaitForTimeout = false);

  int getDetailInfoUpdateCounter() { return m_iDetailInfoUpdateCounter; }
  cNumberList *GetIgnoreList() { return m_pIgnoreList; }
  cNumberList *GetWaitList()  { return m_pWaitList; }

  bool IsLostEventHistoryEmpty(void);
  void ReadLostMessage(void);

protected:
	virtual void Action(void);
};

#endif // __VDR_ICQHOOK_H
