#include <wx/wx.h>
#include <wx/datetime.h>
#include <wx/socket.h>
#include <wx/wfstream.h>
#include "xml.h"


//////////////////////////////////////////////////////////
// Utilities
///////////////////////////////////////////////////////////

wxString Date2String(const wxDateTime& date);
wxDateTime String2Date(const wxString& str);

//////////////////////////////////////////////////////////
// THashString
///////////////////////////////////////////////////////////

class THashString : public wxObject
{
public:
  wxString m_str;
	THashString(const wxChar* str) : m_str(str) { }
};

//////////////////////////////////////////////////////////
// THashTable
///////////////////////////////////////////////////////////

class THashTable : public wxObject
{
	wxHashTable m_Hash;

public:
  void Put(const wxString& key, const wxString& value);
	wxString Get(const wxChar* key) const;
  int GetInt(const wxChar* key) const { return atoi(Get(key)); }
  wxDateTime GetDate(const wxChar* key) const { return String2Date(Get(key)); }

	size_t GetCount() const { return m_Hash.GetCount(); } 
	void BeginFind() { m_Hash.BeginFind(); } 
  wxNode* Next() { return m_Hash.Next(); } 

	THashTable(size_t size = 13);
};

//////////////////////////////////////////////////////////
// TBaseServerApp
///////////////////////////////////////////////////////////

// Define a new application type
class TBaseServerApp : public wxApp
{
private:
  wxSocketServer* m_server;
	wxFileOutputStream* m_log;
	wxString m_strTempDir;
	bool m_bRunning;
	int m_nTmpCounter;
  
protected:
	// Pure virtual functions!
	virtual const wxChar* GetAppName() const = 0;
  virtual void ProcessCommand(wxString cmd, wxSocketBase& outs) = 0;

	virtual bool CanProcessCommand(wxString& cmd, wxSocketBase& outs);
	
	virtual int GetDefaultPort() const;       // Retrieves Port usig GetConfigInt
	virtual wxString GetLogFileName() const;  // Retrieves Port usig GetConfigString 
	virtual wxString GetDocumentRoot() const; // Retrieves Port usig GetConfigString 

	TXmlItem& AddLogo(TXmlItem& td) const;

public:
  // Utilities
	virtual const wxChar* GetConfigName() const;
	virtual void SetConfigString(const wxChar* key, const wxChar* val, const wxChar* app = NULL) const;
	void SetConfigInt(const wxChar* key, int val, const wxChar* app = NULL) const;
	virtual wxString GetConfigString(const wxChar* key, const wxChar* def = "", const wxChar* app = NULL) const;
	int GetConfigInt(const wxChar* key, int def = 0, const wxChar* app = NULL) const;        // Uses GetConfigString
	bool GetConfigBool(const wxChar* key, bool def = false, const wxChar* app = NULL) const; // Uses GetConfigString
	wxString GetTempFilename();
	TXmlItem& CreatePageBody(TXmlItem& html, wxString header = "") const;
  TXmlItem& AddLinkButton(TXmlItem& body, const wxChar* strCaption, const wxChar* strHref) const;

  void SendFile(wxString strFilename, wxSocketBase& outs);
  void MessageBox(const wxChar* caption, const wxChar* msg, wxSocketBase& outs);

	wxString UnformatString(const wxString& strFormString) const;
  int ParseArguments(wxString args, THashTable& hashArgs) const;

	virtual void WriteLog(const wxChar* str) const; // Writes on log file if present                   
	virtual bool Ok() const { return m_server->Ok(); }
	virtual bool Initialization() { return true; }
	virtual bool Deinitialization() { return true; }

  // Initialization (Do NOT use nor reimplement!)
  virtual bool OnInit();
  virtual int OnExit();
  void OnServerEvent(wxSocketEvent& event);
  void OnSocketEvent(wxSocketEvent& event);
	DECLARE_EVENT_TABLE();
};

TBaseServerApp& GetServerApp();