#pragma once

#include "stdafx.h"

using namespace std;

struct upper {
  int operator() ( int c )  
  {
      return toupper ( static_cast<unsigned char> ( c ) );
  }
  
};

struct lower {
  int operator() ( int c )  
  {
      return tolower ( static_cast<unsigned char> ( c ) );
  }
  
};

void wait ( int XSecondX )
{
  clock_t endwait = clock () + XSecondX * (CLOCKS_PER_SEC / 100) ;
  while (clock() < endwait) {};
}

template <typename T>
char* Int2Char(T arg)
{
    stringstream buffer;
    buffer << arg; // send the type to the ostringstream
    return buffer.str(); // capture the string
}

template <typename T>
std::wstring int2wstr(T arg)
{
    wstringstream buffer;
    buffer << arg; // send the type to the ostringstream
    return buffer.str(); // capture the string
}

template <typename T>
unsigned int wstr2int(T arg)
{
   wstringstream buffer;
   buffer << arg;
   unsigned int t;
   buffer >> t;
   return t;
}

template <typename T>
std::string Int2Str(T arg)
{
    stringstream buffer;
    buffer << arg; // send the type to the ostringstream
    return buffer.str(); // capture the string
}

template <typename T>
unsigned int Str2Int(T arg)
{
   stringstream buffer;
   buffer << arg;
   unsigned int t;
   buffer >> t;
   return t;
}

template <typename T>
std::string IntToHex(T arg)
{
    stringstream buffer;
    buffer << hex << arg; // send the type to the ostringstream
    return buffer.str(); // capture the string
}

template <typename T>
int HexToInt(T arg)
{
   int num;
   std::istringstream i(arg);
   i >> std::hex >> num;
   return num;
}

template <typename T>
string IntStrToHexStr(T arg)
{
   int inum = Str2Int(arg);
	stringstream buffer;
	buffer << hex << inum; 
	return buffer.str(); 
}

template <typename T>
float Str2Float(T arg)
{
   stringstream buffer;
   buffer << arg;
   float t;
   buffer >> t;
   return t;
}

template <typename T>
char Str2Char(T arg)
{
   std::istringstream is(arg);
   char t;
   is >> t;
   return t;
}

template <typename T>
string HexStrToIntStr(T arg)
{
   int inum = HexToInt(arg);
	string str = Int2Str(inum);
	return str; 
}

wchar_t* CharArray2wchar_t(char* cstr)
{
	//if (debugging == 1) Debug << L"CharArray2wchar_t fired" << '\n';
	size_t origsize = strlen(cstr) + 1;
	const size_t newsize = 250;
	size_t convertedChars = 0;
	wchar_t wcstr[newsize];
	mbstowcs_s(&convertedChars, wcstr, origsize, cstr, _TRUNCATE);
	//if (debugging == 1) Debug << L"CharArray2wchar_t completed" << '\n';
	return copywchar_t(wcstr);
}

char* wchar_t2CharArray(wchar_t* wcstr)
{
	//if (debugging == 1) Debug << L"wchar_t2CharArray fired" << '\n';
	size_t origsize = wcslen(wcstr) + 1;
	const size_t newsize = 250;
	size_t convertedChars = 0;
	char cstr[newsize];
	wcstombs_s(&convertedChars, cstr, origsize, wcstr, _TRUNCATE);
	//if (debugging == 1) Debug << L"wchar_t2CharArray completed" << '\n';
	return CopyCharArray(cstr);
}

wchar_t* cwchar_t2wchar_t(const wchar_t* cwcstr)
{  
	wchar_t* wcstr = const_cast<wchar_t*>(cwcstr);
	return wcstr;
}

std::wstring str2wstr(const std::string& str)
{
   wstring temp_one;
   string temp(str.begin(), str.end());
   temp_one.assign(str.begin(), str.end());
   return temp_one; 
}

std::string wstr2str(wstring str)
{
   string str1(str.begin(), str.end());
   str1.assign(str.begin(), str.end());
   return str1;
}

wstring wchar_t2wstr(wchar_t * wcstr)
{
    wstring wstr = L"";
	wstr.append(wcstr);
	return wstr;
}

wchar_t* wstr2wchar_t(wstring wstr)
{
   wchar_t* wcstr=new wchar_t[wstr.size()+1];
   wcstr[wstr.size()]=0;
   wmemcpy(wcstr,wstr.c_str(),wstr.size());
   return wcstr;
}

string CharArray2Str(char * a)
{
   std::string d = "";
	d.append(a);
	return d;
}

char* Str2CharArray(string s)
{
   //std::string s
   char *a=new char[s.size()+1];
   a[s.size()]=0;
   memcpy(a,s.c_str(),s.size());
   return a;
}

char* Int2CharArray(int x)
{
	std::string s = Int2Str(x);
   char* a = Str2CharArray(s);
	return a;
}

char* Double2CharArray(double x)
{
	std::string s = Int2Str(x);
   char* a = Str2CharArray(s);
	return a;
}

int CharArray2Int(char* c)
{
	string s = CharArray2Str(c);
	int i = Str2Int(s);
	return i;
}

double CharArray2Double(char* c)
{
	double i = CharArray2Int(c);
   //double i = Str2Int(s);
	return i;
}

string cpystr(string str) 
{
	size_t len;
	char buffer[250];
	len=str._Copy_s(buffer,str.length(),str.length());
	buffer[len]='\0';
	return buffer;
}

wstring cpywstr(wstring wstr) 
{
	size_t len;
	wchar_t buffer[250];
	len=wstr._Copy_s(buffer,wstr.length(),wstr.length());
	buffer[len]='\0';
	return buffer;
}

char* CopyCharArray(const char* orig)
{
	char* cstr=new char[strlen(orig) +1];
	cstr[strlen(orig)]=0;
	memcpy(cstr,orig,strlen(orig));
	return cstr;
}

wchar_t* copywchar_t(wchar_t* wcstr)
{
	//if (debugging == 1) Debug << L" copywchar_t fired wcstr " << wcstr << L" wcslen(wcstr) " << wcslen(wcstr) << '\n';
	wchar_t* wcstr1=new wchar_t[wcslen(wcstr) +1];
	wcstr1[wcslen(wcstr)]=0;
	wmemcpy(wcstr1,wcstr,wcslen(wcstr));
	//if (debugging == 1) Debug << L" copywchar_t completed wcstr " << wcstr1 << L" wcslen(wcstr1) " << wcslen(wcstr1) << '\n';
	return wcstr1;
}

size_t CI_Compare(string a,string b)
{
	std::transform(a.begin(),a.end(),a.begin(),upper());
	std::transform(b.begin(),b.end(),b.begin(),upper());
	size_t loc1 = a.find(b);
	if(loc1!=string::npos) {
		return loc1;
	}
	size_t loc2 = b.find(a);
	if(loc2!=string::npos) {
		return loc2;
	}
	return string::npos;
}

size_t CI_CompareW(wstring Ext,wstring InputFile)
{ 
	size_t loc = InputFile.find_last_of('.');
	if(loc!=string::npos) {
		wstring wstr = InputFile.substr(loc); 
		//if (debugging == 1) Debug << L" Ext check -> " << Ext << " | " << InputFile << " " << '\n';
		if (Ext.compare(wstr) == 0)
		{
		   //if (debugging == 1) Debug << L" Passed ext check " << Ext << " | " << InputFile << " " << '\n';
           return 2;
		}
	}
	return string::npos;
}

string ExtractDirectory(string str) 
{
	size_t pos2 = str.find_last_of("\\");
	if(pos2!=string::npos) {
		str.erase(pos2 + 1);
	}
	return str;
}

string ExtractFileName(string str) 
{
	size_t loc = str.find_last_of("\\" );
	if (loc!=string::npos) {
	   str.erase(0,loc + 1);
   }
   return str;
}

bool FileExists(string str) 
{ 
  struct stat stFileInfo; 
  bool blnReturn; 
  int intStat; 
  intStat = stat(str.c_str(),&stFileInfo); 
  if(intStat == 0) { 
    blnReturn = true; 
  } else { 
    blnReturn = false; 
  } 
   
  return(blnReturn); 
}

int wstr2int(std::wstring& wstr)
{
	string str = wstr2str(wstr);
	int x = Str2Int(str);

	return x; 
}

std::wstring int2wstr(int orig)
{
	string str = Int2Str(orig);
	wstring wstr = str2wstr(str);

	return wstr; 
}

wstring WExtractDirectory(wstring wstr) 
{
	size_t pos2 = wstr.find_last_of(L"\\");
	if(pos2!=string::npos) {
		wstr.erase(pos2 + 1);
	}
	return wstr;
}

wstring WExtractFileName(wstring wstr) 
{
	size_t loc = wstr.find_last_of( L"\\" );
	if (loc!=string::npos) {
	   wstr.erase(0,loc + 1);
   }
   return wstr;
}

