//---------------------------------------------------------------------------
#ifndef wxToolsH
#define wxToolsH
//---------------------------------------------------------------------------
#include <wx/string.h>
#include <wx/stream.h>
#include <wx/ffile.h>
#include <wx/html/htmlwin.h>
#include <wx/mstream.h>

#include <wx/msw/msvcrt.h>

#include "structs.h"
//---------------------------------------------------------------------------
typedef unsigned int uint4;
typedef unsigned char uint1;
//---------------------------------------------------------------------------
//Кросс платформенные функции
//#if defined( _WX )
	//wxString getExecutablePath();

	wxString getStringOnUrl(const wxString path); //Получить строку с веб севера
	bool getFileOnWebServer(const wxString url,const wxString path); //Сохранить файл с веб сервера
	unsigned char* getDataFromURL(const wxString url,unsigned int* size); //получить массив байт с веб сервера (Если!=NULL то первый uint4 кол-во байт)

	wxString getBeforeFirst(wxString str,wxString separator);
	wxString getBeforeLast(wxString str,wxChar separator);
	wxString getAfterFirst(wxString str,wxString separator);
	wxString getAfterLast(wxString str,wxChar separator);
	wxString getSubString(wxString str, wxString bracket1,wxString bracket2);
	wxString replaceStrings(wxString sors,wxString find,wxString repl); //заменить все вхождения строки find в sors на строку repl

	void replaseChars(wxString& str,wxChar oldCh,wxChar newCh); ///<Заменить символ на новый
		
	wxString cutFirstSubStr(wxString &string,wxChar separator); //вырезать под строку
	wxString cutFirstSubStr(wxString &string,char ch); //вырезать под строку

	wxString getFloatString(wxString str); ///<Вырезать из строки всё кроме цифр
	wxString IntToStr(unsigned long i);
	wxString FloatToStr(float f, int numdigits = -1);
	wxString DoubleToStr(double d, int numdigits = -1);
	int StrToInt(wxString str);
	int StrFullToInt(wxString str); //Вырезать из строки только циферки и преобразовать
	unsigned int StrFullToUInt(wxString str); //Вырезать из строки только циферки и преобразовать
	double StrToDouble(wxString str);
	wxString md5String(wxString val);


	wxString loadUTF8String(wxInputStream *is);
	wxString loadUTF8String(wxFFile *is);
	void saveUTF8String(wxOutputStream *os, wxString str);
	void saveUTF8String(wxFFile *os, wxString str);
	void saveUTF8String2(wxOutputStream *os, wxString str); //2 байти под размер строки
//#endif
//------------------------------------------------------------------------------
class MyHtmlWindow : public wxHtmlWindow
{
public:
    MyHtmlWindow(wxWindow *parent) : wxHtmlWindow( parent, -1, wxPoint(10,10), wxSize(200,200) ) { }
    virtual wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType WXUNUSED(type),
                                             const wxString& WXUNUSED(url),
                                             wxString *WXUNUSED(redirect)) const;
    virtual void OnLinkClicked(const wxHtmlLinkInfo& link);
private:
    DECLARE_NO_COPY_CLASS(MyHtmlWindow)
};
//------------------------------------------------------------------------------
typedef float (*MyFuncPtrType)(unsigned int, unsigned char*, void*);
struct RClientData //элемент задания
{
	wxString url; //Откуда будут взяты данные
	int clientInt; //Клиентские данные
	wxString clientStr; //Клиентские данные
	void* clientData; //Клиентские данные
	MyFuncPtrType clientFun; //Функция для обработки данныых (в рамках текущего потока)

	//А вот и самое главное
	unsigned int size; //Размер данных с сервера
	unsigned char* data; //Сами данные с сервера
};
//------------------------------------------------------------------------------
//Класс - менеджер заданий
class TTask: public wxThread
{
protected:
	wxCriticalSection* critsectA; //Для ответа
	wxCriticalSection* critsectR; //Для запроса
	TSimpleList<RClientData*>* listAnswer; //Список ответов
	TSimpleList<RClientData*>* listRequest; //Список запросов
	bool m_Cancel;
	int m_delay; //Задержка в милисекундап перед выполнением следующего задания
public:
	TTask(int delay);
	~TTask()
	{
		delete critsectA;
		delete critsectR;
		delete listAnswer;
		delete listRequest;
	};
	void addTask(RClientData* task) //Добавить задание в список
	{
		critsectR->Enter();
		listRequest->add(task);
		critsectR->Leave();
	};
	RClientData* getTask() //Тот же объект что и добавили только с данными
	{	RClientData* result=NULL;
		critsectR->Enter();
		if(listRequest->count()>0)
		{
			result=listRequest->get(0);
			listRequest->del((unsigned int)0);
		}
		critsectR->Leave();
		return result;
	};
	void addAnswer(RClientData* answer)
	{
		critsectA->Enter();
		listAnswer->add(answer);
		critsectA->Leave();
	};
	RClientData* getAnswer() //Тот же объект что и добавили только с данными
	{	RClientData* result=NULL;
		critsectA->Enter();
		if(listAnswer->count()>0)
		{
			result=listAnswer->get(0);
			listAnswer->del((unsigned int)0);
		}
		critsectA->Leave();
		return result;
	};
	virtual void* Entry(); //Функция потока для обработки заданий
	void Cancel(){m_Cancel=true;};
};
//------------------------------------------------------------------------------
//типа ассоциативный массив для строк
struct TAssoStruct
{
	wxString ident;
	wxString value;
};

class TAMas
{
	public:
		wxString getAt(wxString id);
		void setAt(wxString id,wxString val);
		//void del(wxString id);
		void Copy(TAMas& res);

		//wxString operator [](int i) { return m_val[i]; };

	private:
		wxString str;
		wxArrayString m_id,m_val;
};
//------------------------------------------------------------------------------
struct TIniStruct
{
	TIniStruct *next; //След. значение
	wxString section; //Секция
	wxString ident; //Идентификатор
	wxString value; //Значение
};

class TIniFile
{
private:
	wxString path;
	TIniStruct *first; //Первый из списка
	TIniStruct *last;
public:
	TIniFile(wxString path);
	virtual ~TIniFile();
	wxString ReadString(wxString Section,wxString Ident,wxString Default);
	float ReadFloat(wxString Section,wxString Ident,float Default);
	long ReadLong(wxString Section,wxString Ident,long Default);
	unsigned long ReadULong(wxString Section,wxString Ident,unsigned long Default);
	bool ReadBool(wxString Section,wxString Ident,bool Default);
	void WriteString(wxString Section,wxString Ident,wxString Value);
	void WriteFloat(wxString Section,wxString Ident,float Value);
	void WriteLong(wxString Section,wxString Ident,long Value);
	void WriteULong(wxString Section,wxString Ident,unsigned long Value);
	void WriteBool(wxString Section,wxString Ident,bool Value);
	void Save(); //Сохранить из памяти в файл
};
//------------------------------------------------------------------------------
//для массива потоков
struct LStream
{
	wxMemoryInputStream *is;
	wxString name; //название файла
	char *data; //используеться в wxMemoryInputStream до его удаления
	unsigned int size; //на всяк случай размер буфера
};
//------------------------------------------------------------------------------
//список именнованных потоков
class TFileList
{
private:
	LStream **List; //Массив потоков
	unsigned int count; //количество заполненных
	unsigned int size; //размер массива List
public:
	TFileList();
	~TFileList();
	void add(wxInputStream *is,wxString name);
	wxInputStream* get(wxString name);
	unsigned int getCount();
	LStream* item(unsigned int i);
};
//------------------------------------------------------------------------------
extern const wxEventType wxID_DOWNLOAD_COMPLETE;
//Загрузка файла в отдельном потоке по http
class THTTPDownload: public wxThread
{
private:
protected:
	wxEvtHandler *m_Parent; //слушатель события завершения загрузки
	RClientData* m_CD; //Задание для потока
	bool m_Cancel;
public:
	THTTPDownload(wxEvtHandler *parent,wxString url,int userInt,wxString userStr,void* userData,MyFuncPtrType userFun);
	~THTTPDownload();
	virtual void* Entry();
	//void Cancel();
};
//------------------------------------------------------------------------------
#endif