//---------------------------------------------------------------------------
#pragma hdrstop
//---------------------------------------------------------------------------
#include "stdTools.h"
#include "mathTools.h"

//#include <Math.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <locale>
#include <vector>
//---------------------------------------------------------------------------
//#include <atlbase.h> //Зло :-)
#if defined( _VC )
	#include < ctime >
#endif
#if defined( _BORLAND )
	#include <vcl.h>
#endif
#include <Windows.h> //Для Windows
#include <time.h> //Функция времени

#include "tcDebug.h"
//---------------------------------------------------------------------------
//260 was taken from windef.h
#ifndef MAX_PATH
	#define MAX_PATH 260
#endif

//---------------------------------------------------------------------------
/*template <typename T>
std::string toStdStr(T val)
{
	std::ostringstream oss;
	oss << val;
	return oss.str();
}*/
//---------------------------------------------------------------------------
std::wstring s2ws(const std::string& s)
{
	int len;
	int slength = (int)s.length();// + 1;
	if(slength==0) return L"";
	len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
	std::wstring r(len, L'\0');
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, &r[0], len);
	return r;
}
//---------------------------------------------------------------------------
std::string ws2s(const std::wstring& s)
{
	int len;
	int slength = (int)s.length();// + 1;
	if(slength==0) return "";
	len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
	std::string r(len, '\0');
	WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, &r[0], len, 0, 0);
	return r;
}
//---------------------------------------------------------------------------
//Конвертим из Unicode в DOS 866 кодировку
std::string UnicodeToDOS886(std::wstring str)
{
	std::string rez;
	rez.reserve(str.length()); //Количество символов не должно измениться

	for(uint4 i=0;i<str.length();i++)
	{
		switch(str[i])
		{
			case L'А': rez+=(char)0x80; break;
			case L'Б': rez+=(char)0x81; break;
			case L'В': rez+=(char)0x82; break;
			case L'Г': rez+=(char)0x83; break;
			case L'Д': rez+=(char)0x84; break;
			case L'Е': rez+=(char)0x85; break;
			case L'Ё': rez+=(char)0x85; break; //case L'Ё': rez+=(char)0xF0; break;
			case L'Ж': rez+=(char)0x86; break;
			case L'З': rez+=(char)0x87; break;
			case L'И': rez+=(char)0x88; break;
			case L'Й': rez+=(char)0x89; break;
			case L'К': rez+=(char)0x8A; break;
			case L'Л': rez+=(char)0x8B; break;
			case L'М': rez+=(char)0x8C; break;
			case L'Н': rez+=(char)0x8D; break;
			case L'О': rez+=(char)0x8E; break;
			case L'П': rez+=(char)0x8F; break;
			case L'Р': rez+=(char)0x90; break;
			case L'С': rez+=(char)0x91; break;
			case L'Т': rez+=(char)0x92; break;
			case L'У': rez+=(char)0x93; break;
			case L'Ф': rez+=(char)0x94; break;
			case L'Х': rez+=(char)0x95; break;
			case L'Ц': rez+=(char)0x96; break;
			case L'Ч': rez+=(char)0x97; break;
			case L'Ш': rez+=(char)0x98; break;
			case L'Щ': rez+=(char)0x99; break;
			case L'Ъ': rez+=(char)0x9A; break;
			case L'Ы': rez+=(char)0x9B; break;
			case L'Ь': rez+=(char)0x9C; break;
			case L'Э': rez+=(char)0x9D; break;
			case L'Ю': rez+=(char)0x9E; break;
			case L'Я': rez+=(char)0x9F; break;
			case L'а': rez+=(char)0xA0; break;
			case L'б': rez+=(char)0xA1; break;
			case L'в': rez+=(char)0xA2; break;
			case L'г': rez+=(char)0xA3; break;
			case L'д': rez+=(char)0xA4; break;
			case L'е': rez+=(char)0xA5; break;
			case L'ё': rez+=(char)0xA5; break; 	//case L'ё': rez+=(char)0xF1; break;
			case L'ж': rez+=(char)0xA6; break;
			case L'з': rez+=(char)0xA7; break;
			case L'и': rez+=(char)0xA8; break;
			case L'й': rez+=(char)0xA9; break;
			case L'к': rez+=(char)0xAA; break;
			case L'л': rez+=(char)0xAB; break;
			case L'м': rez+=(char)0xAC; break;
			case L'н': rez+=(char)0xAD; break;
			case L'о': rez+=(char)0xAE; break;
			case L'п': rez+=(char)0xAF; break;
			case L'р': rez+=(char)0xE0; break;
			case L'с': rez+=(char)0xE1; break;
			case L'т': rez+=(char)0xE2; break;
			case L'у': rez+=(char)0xE3; break;
			case L'ф': rez+=(char)0xE4; break;
			case L'х': rez+=(char)0xE5; break;
			case L'ц': rez+=(char)0xE6; break;
			case L'ч': rez+=(char)0xE7; break;
			case L'ш': rez+=(char)0xE8; break;
			case L'щ': rez+=(char)0xE9; break;
			case L'ъ': rez+=(char)0xEA; break;
			case L'ы': rez+=(char)0xEB; break;
			case L'ь': rez+=(char)0xEC; break;
			case L'э': rez+=(char)0xED; break;
			case L'ю': rez+=(char)0xEE; break;
			case L'я': rez+=(char)0xEF; break;
			//Каз-яз	 
/*			case L'?': rez+=(char)0xDB; break;
			case L'?': rez+=(char)0xDC; break;
			case L'?': rez+=(char)0xDE; break;
			case L'?': rez+=(char)0xDF; break;
			case L'?': rez+=(char)0xF0; break;
			case L'?': rez+=(char)0xF1; break;
			case L'?': rez+=(char)0xF3; break;
			case L'?': rez+=(char)0xF4; break;
			case L'?': rez+=(char)0xF5; break;
			case L'?': rez+=(char)0xF6; break;
			case L'?': rez+=(char)0xF7; break;
			case L'?': rez+=(char)0xF8; break;
			case L'?': rez+=(char)0xFD; break;
			case L'?': rez+=(char)0xFE; break;
 */
			default: rez+=(char)str[i]; break;
		}
	}
	return rez;
}
//---------------------------------------------------------------------------
//Обратная конвертация из DOS886 в Unicode
std::wstring DOS886ToUnicode(std::string str)
{
	std::wstring rez;
	rez.reserve(str.length()); //Количество символов не должно измениться

	for(uint4 i=0;i<str.length();i++)
	{
		switch(str[i])
		{
			case (char)0x80: rez+=L'А'; break;
			case (char)0x81: rez+=L'Б'; break;
			case (char)0x82: rez+=L'В'; break;
			case (char)0x83: rez+=L'Г'; break;
			case (char)0x84: rez+=L'Д'; break;
			case (char)0x85: rez+=L'Е'; break;
			//case (char)0xF0: rez+=L'Ё'; break; //В место "Ё" в принтере "?"
			case (char)0x86: rez+=L'Ж'; break;
			case (char)0x87: rez+=L'З'; break;
			case (char)0x88: rez+=L'И'; break;
			case (char)0x89: rez+=L'Й'; break;
			case (char)0x8A: rez+=L'К'; break;
			case (char)0x8B: rez+=L'Л'; break;
			case (char)0x8C: rez+=L'М'; break;
			case (char)0x8D: rez+=L'Н'; break;
			case (char)0x8E: rez+=L'О'; break;
			case (char)0x8F: rez+=L'П'; break;
			case (char)0x90: rez+=L'Р'; break;
			case (char)0x91: rez+=L'С'; break;
			case (char)0x92: rez+=L'Т'; break;
			case (char)0x93: rez+=L'У'; break;
			case (char)0x94: rez+=L'Ф'; break;
			case (char)0x95: rez+=L'Х'; break;
			case (char)0x96: rez+=L'Ц'; break;
			case (char)0x97: rez+=L'Ч'; break;
			case (char)0x98: rez+=L'Ш'; break;
			case (char)0x99: rez+=L'Щ'; break;
			case (char)0x9A: rez+=L'Ъ'; break;
			case (char)0x9B: rez+=L'Ы'; break;
			case (char)0x9C: rez+=L'Ь'; break;
			case (char)0x9D: rez+=L'Э'; break;
			case (char)0x9E: rez+=L'Ю'; break;
			case (char)0x9F: rez+=L'Я'; break;
			case (char)0xA0: rez+=L'а'; break;
			case (char)0xA1: rez+=L'б'; break;
			case (char)0xA2: rez+=L'в'; break;
			case (char)0xA3: rez+=L'г'; break;
			case (char)0xA4: rez+=L'д'; break;
			case (char)0xA5: rez+=L'е'; break;
			//case (char)0xF1: rez+=L'ё'; break; //В место "ё" в принтере "?"
			case (char)0xA6: rez+=L'ж'; break;
			case (char)0xA7: rez+=L'з'; break;
			case (char)0xA8: rez+=L'и'; break;
			case (char)0xA9: rez+=L'й'; break;
			case (char)0xAA: rez+=L'к'; break;
			case (char)0xAB: rez+=L'л'; break;
			case (char)0xAC: rez+=L'м'; break;
			case (char)0xAD: rez+=L'н'; break;
			case (char)0xAE: rez+=L'о'; break;
			case (char)0xAF: rez+=L'п'; break;
			case (char)0xE0: rez+=L'р'; break;
			case (char)0xE1: rez+=L'с'; break;
			case (char)0xE2: rez+=L'т'; break;
			case (char)0xE3: rez+=L'у'; break;
			case (char)0xE4: rez+=L'ф'; break;
			case (char)0xE5: rez+=L'х'; break;
			case (char)0xE6: rez+=L'ц'; break;
			case (char)0xE7: rez+=L'ч'; break;
			case (char)0xE8: rez+=L'ш'; break;
			case (char)0xE9: rez+=L'щ'; break;
			case (char)0xEA: rez+=L'ъ'; break;
			case (char)0xEB: rez+=L'ы'; break;
			case (char)0xEC: rez+=L'ь'; break;
			case (char)0xED: rez+=L'э'; break;
			case (char)0xEE: rez+=L'ю'; break;
			case (char)0xEF: rez+=L'я'; break;
			//Каз-яз	 
			case (char)0xDB: rez+=L'?'; break;
			case (char)0xDC: rez+=L'?'; break;
			case (char)0xDE: rez+=L'?'; break;
			case (char)0xDF: rez+=L'?'; break;
			case (char)0xF0: rez+=L'?'; break;
			case (char)0xF1: rez+=L'?'; break;
			case (char)0xF3: rez+=L'?'; break;
			case (char)0xF4: rez+=L'?'; break;
			case (char)0xF5: rez+=L'?'; break;
			case (char)0xF6: rez+=L'?'; break;
			case (char)0xF7: rez+=L'?'; break;
			case (char)0xF8: rez+=L'?'; break;
			case (char)0xFD: rez+=L'?'; break;
			case (char)0xFE: rez+=L'?'; break;

			default: rez+=(char)str[i]; break;
		}
	}
	return rez;
}
//---------------------------------------------------------------------------
//Float в строку
std::string FloatToStdStr(float val)
{
	std::ostringstream oss;
	oss << val;
	return oss.str();
}
//---------------------------------------------------------------------------
std::string IntToStdStr(int val)
{
	std::ostringstream oss;
	oss << val;
	return oss.str();
}
//---------------------------------------------------------------------------
template <typename T>
std::string toStringHex(T val)
{
	std::ostringstream oss;
	oss << std::hex << val;
	return oss.str();
}
//---------------------------------------------------------------------------
std::string toStringHex2(int val)
{
	std::ostringstream oss;
	oss << std::hex << val;
	return oss.str();
}
//---------------------------------------------------------------------------
//Преобразовать HEX строку в число
template <typename T>
T fromStringHex(std::string val)
{
	T value;
	std::istringstream iss(val);
	iss >> std::hex >> value;
	return value;
}
//----------------------------------------------------------------------------
//Закодировать двоично десятичное число
//Преобразовать строку цифр в строку байт пример "1234" в 2 байта [12h,34h] если нечётное то 0 в начале
std::string CodeBSD(std::string str)
{
	if(str.length()%2!=0) str="0"+str;
	//Преобразуем 2 символа в 1 байт
	std::string rez;
	size_t len=str.length()/2;
	for(size_t i=0;i<len;i++)
	{
		std::string ch;
		ch+=str[i*2];
		ch+=str[i*2+1];
		unsigned char hch = fromStringHex<int>(ch);
		rez+=hch;
	}
	return rez;
}
//---------------------------------------------------------------------------
//Закодировать двоично десятичное число
//Преобразовать строку цифр в строку байт пример "1234" в 2 байта [12h,34h] если нечётное то 0 в начале
//len - количество (байт)символов добавит нули в начале если получилось меньше
std::string CodeBSD(int val,int len)
{
	std::string str=CodeBSD(IntToStdStr(val));
	for(size_t i=str.length();i<len;i++) //Медленно
		str=(char)0x00+str;
	return str;
}
//---------------------------------------------------------------------------
//Двоично десятичный символ в int
int BSDToInt(char chr)
{
	//return StdStrToInt(DecodeBSD(chr)); //TODO исправить для билдера
	return 0;
}
//---------------------------------------------------------------------------
//Двоично десятичную строку в int
int BSDToInt(std::string str, size_t start, size_t len)
{
	//return StdStrToInt(DecodeBSD(str,start,len)); //TODO исправить для билдера
	return 0;
}
//---------------------------------------------------------------------------
//Раскодировать двоично десятичное число 2 байта [12h,34h] преобразуются в строку "1234"
std::string DecodeBSD(char chr)
{
	std::string rez;
	unsigned char ch;

	ch=(chr >> 4) & 0x0F;
	if(ch<10) rez+=(char)(48+ch); 
	else rez+='0';  //такого не должно быть

	ch=chr & 0x0F;
	if(ch<10) rez+=(char)(48+ch); 
	else rez+='0';  //такого не должно быть

	return rez;
}
//---------------------------------------------------------------------------
//Раскодировать двоично десятичное число 2 байта [12h,34h] преобразуются в строку "1234"
std::string DecodeBSD(std::string str, size_t start, size_t len)
{
	if(len==0) len=str.length();
	len=start+len;
	if(len>str.length()) len=str.length();
	std::string rez;
	for(size_t i=start;i<len;i++)
	{
		rez+=DecodeBSD(str[i]);
	}
	return rez;
}
//---------------------------------------------------------------------------
//std::wstring StringToWString( const std::string& in, std::locale loc )
std::wstring StringToWString(const std::string& in, const std::locale &loc)
{
	std::wstring out;
	std::string::const_iterator i( in.begin() ), ie( in.end() );
	for( ; i!=ie; ++i )
		out += std::use_facet<std::ctype<wchar_t> > ( loc ).widen( *i );
	return out;
}
//---------------------------------------------------------------------------
void replaseChars(std::string& str, char oldCh, char newCh)
{
	int indexCh = str.find(oldCh);
	while (indexCh != -1)
	{
		str.replace(indexCh,1,1,newCh);
		indexCh = str.find(oldCh,indexCh);
	}
}
//---------------------------------------------------------------------------
/*inline std::string replace(std::string text, std::string s, std::string d)
{
	for(unsigned index=0; index=text.find(s, index), index!=std::string::npos;)
	{
		text.replace(index, s.length(), d);
		index+=d.length();
	}
	return text;
}*/
//---------------------------------------------------------------------------
/*std::string getExePath()
{
	//если EXE то
	//return ExtractFilePath(ParamStr(0)).c_str();
	//Если DLL то
	return "";
}*/
//------------------------------------------------------------------------------
//Заменить все вхождения строки find в sors на repl (wxString::Replace)
std::string replaceStrings(std::string sors,std::string find,std::string repl)
{
	if(find==repl) return sors;
	std::string rez="";
	size_t p0=0;
	size_t p1 = sors.find(find,p0);
	while(p1!=std::string::npos)
	{
		rez.append(sors,p0,p1-p0);
		rez+=repl;
		p0=p1+find.length();
		p1=sors.find(find,p0);
	}
	rez.append(sors,p0,sors.length()-p0);
	return rez;
}
//---------------------------------------------------------------------------
std::wstring replaceStrings(std::wstring sors,std::wstring find,std::wstring repl)
{
	if(find==repl) return sors;
	std::wstring rez=L"";
	size_t p0=0;
	size_t p1 = sors.find(find,p0);
	while(p1!=std::wstring::npos)
	{
		rez.append(sors,p0,p1-p0);
		rez+=repl;
		p0=p1+find.length();
		p1=sors.find(find,p0);
	}
	rez.append(sors,p0,sors.length()-p0);
	return rez;
}
//---------------------------------------------------------------------------
//Получить дату в виде ANSI строки в формате ddmmyyyy
std::string getStrDate()
{
	time_t t=time(NULL);
	tm* st=localtime(&t);

	std::string str1=IntToStdStr(st->tm_mday);
	if(str1.length()==1) str1="0"+str1;
	std::string str2=IntToStdStr(st->tm_mon+1);
	if(str2.length()==1) str2="0"+str2;
	std::string str3=IntToStdStr(st->tm_year+1900);
	if(str3.length()==1) str3="0"+str3;

	//delete st; //Ошибка памяти будет если удалю
	return str1+str2+str3;
}
//---------------------------------------------------------------------------
//Получить дату в виде Unicode строки в формате ddmmyyyy
std::wstring getWStrDate()
{
	return StringToWString(getStrDate(),std::locale("rus"));
}
//---------------------------------------------------------------------------
//Дата и время в виде строки dd.mm.yyyy hh:mm:ss 24.05.2010 15:20:26
std::string getDateTime()
{
/*
#if defined( _VC ) 
	//Для проекта с ATL библиотекой
	std::string tmp,res="";
	SYSTEMTIME st;
	GetLocalTime(&st);
	//Дата
	tmp=toStdStr(st.wDay);
	if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
	tmp=toStdStr(st.wMonth);
	if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
	res+=toStdStr(st.wYear)+" ";

	//Время
	tmp=toStdStr(st.wHour);
	if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
	tmp=toStdStr(st.wMinute);
	if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
	tmp=toStdStr(st.wSecond);
	if(tmp.length()==1) res+="0"+tmp; else res+=tmp;

	return res;
#endif
#if defined( _WX )
	//Для кросплатформенного проекта wxWidgets
	return "";
#endif
*/
	std::string tmp,res="";

	time_t t=time(NULL);
	tm* st=localtime(&t);

	//Дата
	tmp=IntToStdStr(st->tm_mday);
	if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
	tmp=IntToStdStr(st->tm_mon+1);
	if(tmp.length()==1) res+="0"+tmp+"."; else res+=tmp+".";
	res+=IntToStdStr(st->tm_year+1900)+" ";

	//Время
	tmp=IntToStdStr(st->tm_hour);
	if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
	tmp=IntToStdStr(st->tm_min);
	if(tmp.length()==1) res+="0"+tmp+":"; else res+=tmp+":";
	tmp=IntToStdStr(st->tm_sec);
	if(tmp.length()==1) res+="0"+tmp; else res+=tmp;

	//delete st; //Ошибка памяти будет если удалю
	return res;
}
//---------------------------------------------------------------------------
//Преобразовать в строку (Разделитель всегда точка)
//digits - Сколько цифр после запятой оставлять если -1 то по полной
std::string FloatToStdStr(double val, int digits)
{
	std::ostringstream oss;
	if(digits >= 0)
		oss << std::fixed << std::setprecision( digits ) << val;
	else oss << std::fixed << val;

	std::string str=oss.str();
	int pos=MaxI4(str.find('.'),str.find(',')); //Позиция запятой в строке (TODO взять разделитель из системных параметров)
	//Обрезаем строку
	if(digits>=0 && pos>=0)
	{	if(digits==0) digits=-1; //Чтоб убрать запятую

		std::string result="";
		result.append(str,0,pos+digits+1);
		return result;
	}else return str;
}
//---------------------------------------------------------------------------
template <typename T>
std::wstring toStdWStr(T val)
{
	std::ostringstream oss;
	oss << val;

	std::string str=oss.str();
	return StringToWString( str, std::locale("rus"));
}
//---------------------------------------------------------------------------
std::wstring IntToStdWStr(int val)
{
	return toStdWStr(val);
}
//---------------------------------------------------------------------------
template<typename T>
T fromString(const std::string& s)
{
	std::istringstream iss(s);
	T res;
	iss >> res;
	return res;
}
//int StdStrToInt(std::string& str);
//---------------------------------------------------------------------------
//Преобразовать строку в число
//str - Исходная строка с числом
//cutInt - вырезать из строки только цифры
int StdStrToInt(std::string& str, bool cutInt)
{
	if(cutInt)
	{
		std::string val="";
		for(unsigned int i=0;i<str.length();i++)
		{
			if((str[i]=='-' && (val.length()==0 || val[0]!='-'))  || str[i]=='0' || str[i]=='1' || str[i]=='2' || str[i]=='3' || str[i]=='4' || str[i]=='5' || str[i]=='6' || str[i]=='7' || str[i]=='8' || str[i]=='9')
				val+=str[i];
		}
		if(val=="") return 0;
		return fromString<int>(val);
	}
	if(str=="") return 0;
	return fromString<int>(str);
}
//---------------------------------------------------------------------------
//Преобразовать строку в число
//str - Исходная строка с числом
//cutInt - вырезать из строки только цифры
int StdStrToUInt(std::string& str, bool cutInt)
{
	if(cutInt)
	{
		std::string val="";
		for(unsigned int i=0;i<str.length();i++)
		{
			if(str[i]=='0' || str[i]=='1' || str[i]=='2' || str[i]=='3' || str[i]=='4' || str[i]=='5' || str[i]=='6' || str[i]=='7' || str[i]=='8' || str[i]=='9')
				val+=str[i];
		}
		if(val=="") return 0;
		return fromString<int>(val);
	}
	if(str=="") return 0;
	return fromString<int>(str);
}
//---------------------------------------------------------------------------
float StdStrToFloat(std::string& str)
{
	if(str=="") return 0;
	return fromString<float>(str);
}
//---------------------------------------------------------------------------
double StdStrToDouble(std::string& str)
{
	if(str=="") return 0;
	return fromString<double>(str);
}
//---------------------------------------------------------------------------
template<typename T>
T fromWString(const std::wstring& s)
{
	std::string str=WStringToString(s, std::locale("rus"));	

	std::istringstream iss(str);
	T res;
	iss >> res;
	return res;
}
//---------------------------------------------------------------------------
int StdWStrToInt(const std::wstring& s)
{
	return fromWString<int>(s);
}
//---------------------------------------------------------------------------
///К верхнему регистру строку
std::wstring UpperCase(const std::wstring& str)
{
	std::wstring res=L""; //TODO Надо выделить память
	for(unsigned int i=0;i<str.length();i++)
	{
		switch( str[i] )
		{
			case L'a': res+=L'A'; break;
			case L'b': res+=L'B'; break;
			case L'c': res+=L'C'; break;
			case L'd': res+=L'D'; break;
			case L'e': res+=L'E'; break;
			case L'f': res+=L'F'; break;
			case L'g': res+=L'G'; break;
			case L'h': res+=L'H'; break;
			case L'i': res+=L'I'; break;
			case L'j': res+=L'J'; break;
			case L'k': res+=L'K'; break;
			case L'l': res+=L'L'; break;
			case L'm': res+=L'M'; break;
			case L'n': res+=L'N'; break;
			case L'o': res+=L'O'; break;
			case L'p': res+=L'P'; break;
			case L'q': res+=L'Q'; break;
			case L'r': res+=L'R'; break;
			case L's': res+=L'S'; break;
			case L't': res+=L'T'; break;
			case L'u': res+=L'U'; break;
			case L'v': res+=L'V'; break;
			case L'w': res+=L'W'; break;
			case L'x': res+=L'X'; break;
			case L'y': res+=L'Y'; break;
			case L'z': res+=L'Z'; break;

			case L'а': res+=L'А'; break;
			case L'б': res+=L'Б'; break;
			case L'в': res+=L'В'; break;
			case L'г': res+=L'Г'; break;
			case L'д': res+=L'Д'; break;
			case L'е': res+=L'Е'; break;
			case L'ё': res+=L'Ё'; break;
			case L'ж': res+=L'Ж'; break;
			case L'з': res+=L'З'; break;
			case L'и': res+=L'И'; break;
			case L'к': res+=L'К'; break;
			case L'л': res+=L'Л'; break;
			case L'м': res+=L'М'; break;
			case L'н': res+=L'Н'; break;
			case L'о': res+=L'О'; break;
			case L'п': res+=L'П'; break;
			case L'р': res+=L'Р'; break;
			case L'с': res+=L'С'; break;
			case L'т': res+=L'Т'; break;
			case L'у': res+=L'У'; break;
			case L'ф': res+=L'Ф'; break;
			case L'х': res+=L'Х'; break;
			case L'ц': res+=L'Ц'; break;
			case L'ч': res+=L'Ч'; break;
			case L'ш': res+=L'Ш'; break;
			case L'щ': res+=L'Щ'; break;
			case L'ъ': res+=L'Ъ'; break;
			case L'ы': res+=L'Ы'; break;
			case L'ь': res+=L'Ь'; break;
			case L'э': res+=L'Э'; break;
			case L'ю': res+=L'Ю'; break;
			case L'я': res+=L'Я'; break;
			default:
				res+=str[i];
		}
	}
	return res;
}
//---------------------------------------------------------------------------
///Получить строку до указанного символа если символа нет то вернёт всю строку.
std::string BeforeLast(std::string str,char ch)
{
	int pos=0;
	for(uint4 i=0;i<str.length();i++)
	{
		if(str[i]==ch) pos=i;
	}
	if(pos==0) pos=str.length();

	std::string result="";
	result.append(str,0,pos);
	return result;
}
//---------------------------------------------------------------------------
///Получить строку до указанного символа если символа нет то вернёт всю строку.
std::wstring BeforeWLast(std::wstring str,wchar_t ch)
{
	int pos=0;
	for(uint4 i=0;i<str.length();i++)
	{
		if(str[i]==ch) pos=i;
	}
	if(pos==0) pos=str.length();

	std::wstring result=L"";
	result.append(str,0,pos);
	return result;
}
//---------------------------------------------------------------------------
std::string BeforeFirst(std::string str,const char ch)
{
	unsigned int pos=str.find(ch);
	std::string result="";
	result.append(str,0,pos);
	return result;
}
//---------------------------------------------------------------------------
std::wstring BeforeWFirst(std::wstring str,const wchar_t ch)
{
	unsigned int pos=str.find(ch);
	std::wstring result=L"";
	result.append(str,0,pos);
	return result;
}
//---------------------------------------------------------------------------
//Отрезать от строки до указанного символа если не найден символ отрезается вся строка
std::string CutBeforeFirst(std::string& str,const char ch)
{
	int pos=str.find(ch);
	std::string result="";
	result.append(str,0,pos);
	str.erase(0,pos+1);
	return result;
}
//---------------------------------------------------------------------------
//Отрезать от строки до указанного символа если не найден символ отрезается вся строка
std::wstring CutBeforeWFirst(std::wstring& str,const wchar_t ch)
{
	int pos=str.find(ch);
	std::wstring result=L"";
	if(pos==-1)
	{
		result.append(str);
		str.erase();
	}else
	{
		result.append(str,0,pos);
		str.erase(0,pos+1);
	}
	return result;
}
//---------------------------------------------------------------------------
std::string AfterFirst(std::string str,const char ch)
{
	unsigned int pos=str.find(ch);
	std::string result="";
	result.append(str,pos+1,str.size());
	return result;
}
//---------------------------------------------------------------------------
std::wstring AfterWFirst(std::wstring str,const wchar_t ch)
{
	unsigned int pos=str.find(ch);
	std::wstring result=L"";
	result.append(str,pos+1,str.size());
	return result;
}
//---------------------------------------------------------------------------
//Всё после заданного разделителя, если разделитель не найден то сначала строки
std::string AfterLast(std::string str,const char ch)
{
	int pos=str.find_last_of(ch)+1;
	int len=str.length()-pos;
	return str.substr(pos,len);
}
//---------------------------------------------------------------------------
std::string WStringToString(std::wstring const &wstr, std::locale const &loc, char default_char)
{
    if (wstr.empty())
        return std::string();

    std::string ret;
    ret.resize(wstr.length());

    std::use_facet<std::ctype<wchar_t> >(loc).narrow(&wstr[0], &wstr[0] + wstr.length(), '?', &ret[0]);

    return ret;
/*
	if (wstr.empty())
		return std::string();
	std::ctype<wchar_t> const &facet = std::use_facet<std::ctype<wchar_t> >(loc);
	wchar_t const *first = wstr.c_str();
	wchar_t const *last = first + wstr.size();
	std::vector<char> result(wstr.size());

	facet.narrow(first, last, default_char, &result[0]);

	return std::string(result.begin(), result.end());
*/
}
//---------------------------------------------------------------------------
//Путь к DLL специально для dll берётся её хэндл
std::wstring getAppPathW()
{
	std::wstring str;
#if defined( _VC )
	wchar_t pathBuf[MAX_PATH] = {0};
	HMODULE thisModule = 0;
	BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&__FUNCTION__, &thisModule);
	DWORD nLen = GetModuleFileName(thisModule, pathBuf, MAX_PATH);
	str=pathBuf;
	str=BeforeWLast(str,L'\\')+L'\\';
#endif
	return str;
}
//---------------------------------------------------------------------------
//Получить путь к приложению (не путать с верхней функцией)
std::string getAppPathA()
{
/*
#if defined( _VC )
	return WStringToString(getAppPathW(), std::locale("rus"));
#endif
#if defined( _BORLAND )
	return ExtractFilePath(ParamStr(0)).c_str();
#endif
#if defined( _WX )
	return "";
#endif
*/
	std::string str;
	char pathBuf[MAX_PATH] = {0};
	GetModuleFileNameA(NULL,pathBuf,MAX_PATH);
	str=pathBuf;
	str=BeforeLast(str,'\\')+'\\';
	return str;
}
//---------------------------------------------------------------------------
//Добавить 0 в начало строоки если 1 символ для даты нужно
std::string add0(std::string str)
{
	if(str.length()==1) return "0"+str;
	else return str;
}
//---------------------------------------------------------------------------
//Убрать начальные и конечные пробелы
std::string trim(const std::string & s)
{
	size_t startPos = s.find_first_not_of(" \t");
	if ( startPos == std::string::npos )
		return "";
	size_t endPos = s.find_last_not_of(" \t");
	return s.substr(startPos, endPos - startPos + 1);
}
//---------------------------------------------------------------------------
//Конвертация из UTF16LE в UTF8
std::string convUTF16ToUTF8(const std::wstring& widestring)
{
	unsigned int len8=0;
	unsigned int len16=widestring.length();
	const wchar_t* p16=widestring.data();
	for(unsigned int i=0;i<len16;i++) //Подсчитываем размер буфера
	{
		if(p16[i]<=0x7f) len8++; else
		if(p16[i]<=0x7ff) len8+=2; else
		if(p16[i]<=0xffff) len8+=3; else
		if(p16[i]<=0x10ffff) len8+=4;
	}
	unsigned char * p8=new unsigned char[len8];
	unsigned int pos=0;
	for(unsigned int i=0;i<len16;i++)
	{
		if(p16[i]<=0x7f) 
		{
			p8[pos]=(unsigned char)p16[i];
			pos++;
		}else
		if(p16[i]<=0x7ff) //110xxxxx, 10xxxxxx
		{
			p8[pos]=(p16[i]>>6 | 192) & 223;
			pos++;
			p8[pos]=(p16[i] | 128) & 191;
			pos++;
		}else
		if(p16[i]<=0xffff) //1110xxxx 10xxxxxx 10xxxxxx
		{
			p8[pos]=(p16[i]>>12 | 224) & 239;
			pos++;
			p8[pos]=(p16[i]>>6 | 128) & 191;
			pos++;
			p8[pos]=(p16[i] | 128) & 191;
			pos++;
		}else
		if(p16[i]<=0x10ffff) //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
		{
			p8[pos]=(p16[i]>>18 | 240) & 247;
			pos++;
			p8[pos]=(p16[i]>>12 | 128) & 191;
			pos++;
			p8[pos]=(p16[i]>>6 | 128) & 191;
			pos++;
			p8[pos]=(p16[i] | 128) & 191;
			pos++;
		}
	}
	std::string str;
	str.append((char*)p8,len8);
	delete[] p8;
	return str;
}
//---------------------------------------------------------------------------
//Конвертация из UTF8 в UTF16LE
std::wstring convUTF8ToUTF16(const std::string& str)
{
	unsigned int len16=0;
	unsigned int len8=str.length();
	const char* p8=str.data();

	unsigned int i=0;
	while(i<len8) //Подсчитываем сколько символов в строке
	{
		if((p8[i] & 0x80)==0) i++; else //0 в начале знач 1 символ
		if((p8[i] & 0xF0)==0xF0) i+=4; else //11110xxx
		if((p8[i] & 0xE0)==0xE0) i+=3; else //1110xxxx
		if((p8[i] & 0xC0)==0xC0) i+=2; //110xxxxx
		len16++;
	}
	wchar_t* p16=new wchar_t[len16];
	unsigned int pos=0;
	i=0;
	while(i<len8)
	{
		if((p8[i] & 0x80)==0) //0xxxxxxx (0 в начале знач 1 символ)
		{
			p16[pos]=p8[i];
			pos++; i++;
		}else
		if((p8[i] & 0xF0)==0xF0) //11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
		{
			p16[pos]=((p8[i] & 0x7) << 18) | ((p8[i] & 0x3F) << 12) | ((p8[i] & 0x3F) << 6) | (p8[i] & 0x3F);
			pos++; i+=4;
		}else
		if((p8[i] & 0xE0)==0xE0) //1110xxxx 10xxxxxx 10xxxxxx
		{
			p16[pos]=((p8[i] & 0xf) << 12) | ((p8[i] & 0x3F) << 6) | (p8[i] & 0x3F);
			pos++; i+=3;
		} else
		if((p8[i] & 0xC0)==0xC0) //110xxxxx 10xxxxxx 
		{
			p16[pos]=((p8[i] & 0x1F) << 6) | (p8[i+1] & 0x3F);
			pos++; i+=2;
		}else i++; //если дошло до сюда то ошибка
	}

	std::wstring wstr;
	wstr.append(p16,len16);
	delete[] p16;
	return wstr;
}
//******************************************************************************
/*TIniFileSTD::TIniFileSTD(std::wstring path)
{
	this->path=path;
	first=NULL;

	std::wifstream myfile(path.c_str()); //std::wifstream myfile(path.c_str());
	if (myfile.is_open())
	{
		std::wstring str;
		std::wstring section;
		while ( myfile.good() )
		{
			std::getline(myfile,str);
			if (str.find('[')!=std::wstring::npos)
			{
				section=BeforeWLast(AfterWFirst(str,'['),']');
			}
			if (str.find('=')!=std::wstring::npos)
			{
				TIniStructSTD* inistr= new TIniStructSTD;
				inistr->next=NULL;
				inistr->section=section;
				inistr->ident=BeforeWFirst(str,L'=');
				inistr->value=AfterWFirst(str,L'=');
				if (first==NULL)
				{
					first=inistr;
					last=inistr;
				}else
				{
					last->next=inistr;
					last=inistr;
				}
			}
		}
		myfile.close();
	}
}
TIniFileSTD::~TIniFileSTD()
{
}
std::string TIniFileSTD::ReadString(std::string Section,std::string Ident,std::string Default)
{
	return NULL;
}
void TIniFileSTD::WriteString(std::string Section,std::string Ident,std::string Value)
{
}*/