

/*!
@auther d金魚 http://www3.to/shisui/
@note

参考サイト,文献
<ul>
<li>
葉迩 倭
氏の
<a href="http://www.twin-tail.jp/">
TWINTAIL LOVERS
</a>のLuna

</ul>
*/


#ifndef _dkutilFunction02__
#define _dkutilFunction02__

//#include "../common/common_allinclude.h"
//#include "dkutilLog.h"
//#include "../wrapper/dkutilDataWrapper.h"
#include "dkutilFunction01.h"
#include "dkutilString.h"
//#include "dkutilMap.h"


namespace dkutil{

inline GUID &CreateGUID(){
	static GUID guid={0};//ここ、staticにしてないと他の関数に迷惑がかかります^^;
	::CoCreateGuid(&guid);
	return guid;
}
inline size_t GUIDStringBuffSize(){
	return strlen(ULONG_MAX_STR) + //ulong member
	( strlen(USHRT_MAX_STR) * 2 ) + //ushort member
	( strlen(UCHAR_MAX_STR) * 8 ) + 1;//uchar member
}
inline int GUIDToCharArray(GUID &guid,char *buff,size_t buffsize){
	/* GUID member
	unsigned long        Data1; 
  unsigned short       Data2; 
  unsigned short       Data3; 
  unsigned char        Data4[8]; 
	 = buffsize is ULONG_MAX + ( USHRT_MAX * 2 ) UCHAR_MAX * 8 ??
	*/
	size_t size = GUIDStringBuffSize();
	//NULL文字も考慮して > である！
	if(size > buffsize){	return -1;}
	
	_snprintf(buff,buffsize,"%u%u%u%u%u%u%u%u%u%u%u",//"%d%d%d%d%d%d%d%d%d%d%d%d",
		guid.Data1,guid.Data2,guid.Data3,
		guid.Data4[0],guid.Data4[1],guid.Data4[2],
		guid.Data4[3],guid.Data4[4],
		guid.Data4[5],guid.Data4[6],guid.Data4[7]
		);
	return 0;
}
inline int GUIDToString(std::string &get_my_string,GUID &guid=CreateGUID())
{
	size_t size = GUIDStringBuffSize();
	char *ptr = (char *)::malloc(size);
	if(!ptr) return -1;
	::memset(ptr,0,size);
	int result = -1;
	if(0 != GUIDToCharArray(guid,ptr,size))
		goto END;
	get_my_string = ptr;
	result = 0;
END:
	if(ptr){::free(ptr);ptr=NULL;}
	return result;
}
/*
///なんかVC6にはバグがあるらしいのでファンクターで^^;
template<typename T>
class IntegerToCharPtr{
	char m_buff[20 + 1];
	IntegerToCharPtr(){
		::memset(m_buff,0,sizeof(m_buff));
	}
	size_t size(){return 20 + 1;}
	inline char *IntegerToCharPtr(T t){
		//18446744073709551615 = 20桁
		_snprintf(m_buff,size(),"%s",t);
		return m_buff;
	}
	char *operator()(T t){
		return IntegerToCharPtr(t);
	}
};
inline int CharArrayToGUIDString(char *ptr,size_t permit_size,std::string &str){
	size_t size = strlen("{D9AD457A-007F-4DB6-8B06-CAACC44933A3}") + 1;
	if(size > permit_size) return -1;
	str = {
	return 0;
}
*/
///注意：バッファに出力系の関数にこれで得たポインタを使わないでください。
inline char *StringToCharPtr(const std::string &str){
	return const_cast<char *>(str.c_str());
}
inline const char *StringToConstCharPtr(const std::string &str){
	return str.c_str();
}

///_CrtSetDbgFlagのラッパー
///USE_DKINGYO_MEMORYLEAK_CHECKが有効になっていないとなにもしません。
///@return 以前の _crtDbgFlag の状態を返します。無効な時は　-1
inline int MemoryLeakCheckAfterSoftwareEnded(){
#if defined(USE_DKINGYO_MEMORYLEAK_CHECK) && defined(_MSC_VER)
	return _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#else
	return -1;
#endif
}

inline bool OpenExplorer(char *pURL){
	size_t size = strlen(pURL) + MAX_PATH + 1;
	char *tmp = (char *)malloc(size);
	if(!tmp) return false;

	_snprintf(tmp,size,"Explorer /root,%s",pURL);
	int r = ::WinExec(tmp,SW_SHOWDEFAULT);
	if(tmp){::free(tmp);tmp=NULL;}
	return (r != 0);
}

inline int CurrentDirectoryPlusFileName(char *buff,size_t buffsize,char *filename)
{
	if(buffsize < MAX_PATH) return -1;
	::memset(buff,0,buffsize);
	GetCurrentDirectory(buffsize,buff);
	{
		char *sp = 	strtail(buff);
		/*
		buff = 0
		buffsize = 1
		sp = 2
		0-----ここらへんは文字で埋まっていると思って＾＾------2--空領域---1
		0x00                                                            MAX_PATH

		なので、buff + buffsize == &buff[buffsize]
		sp = buff + sp == &buff[sp]
		buffsize - sp == 空領域
		*/
		//NULL文字　考慮　で <=
		if((size_t)((buff + buffsize) - (sp)) <= strlen(filename) + 1)
		{
			return -1;
		}
		//つける。
		sp[0] = '\\';
		//あとは文字列追加
		strncat(&sp[1],filename,(buff + buffsize) - (sp));
	}
	return 0;
}


#if 0
///カンきり^^;
template<class UTIL=DKConfigUtility>
class Opener_base{
public:
	struct FileType{
		FileType(char *gfilter,char *gtitle,char *gdefext){
			NULL_CHAR_ARRAY(filter);
			NULL_CHAR_ARRAY(title);
			NULL_CHAR_ARRAY(defext);
			dkstrcpy(filter,sizeof(filter),gfilter,strlen(gfilter));
			dkstrcpy(title,sizeof(title),gtitle,strlen(gtitle));
			dkstrcpy(defext,sizeof(defext),defext,strlen(defext));
		}
		char filter[512];
		char title[512];
		char defext[512];
	};

	enum{
		idALLFILE,
		idPNG,
		idBMP,
		idJPEG,
		idWAVE,
		idMIDI,
		idMP3,
		idOGG,
		idTXT,
		idHTML,
	};
	typedef map_ex<int,FileType> MAP_TYPE;
private:
	
	static MAP_TYPE mmap;
	static bool isOnce;
	UTIL mutil;
	void MappingFileExtention(){
		//スレッドロック
		if(isOnce==false){
			DKUTIL_MULTITHREAD_SYNDROME_LOCK(mutil);
			
			if(isOnce==false){

				int id = idALLFILE;
				mmap.SetData(id,
					FileType("All files(*.*)\0*.*\0\0","All File Select","All Files"));
				id=idPNG;
				mmap.SetData(id,
					FileType("png(*.png)\0*.png\0\0","Png File Select","Png File"));
				id=  idBMP;
				mmap.SetData(id,
					FileType("bmp(*.bmp)\0*.bmp\0\0","Bitmap File Select","BMP File"));
				id = idJPEG;
				mmap.SetData(id,
					FileType("jpg(*.jpg*.jpeg)\0*.jpg;*.jpeg\0\0","JPEG File Select","Jpeg File"));
				id = idTXT;
				mmap.SetData(id,
					FileType("txt(*.txt)\0*.txt\0\0","Text File Select","Text File"));
				isOnce=true;
			}
			//ロック解除
			DKUTIL_MULTITHREAD_SYNDROME_UNLOCK(mutil);
		}
	}
public:
	explicit Opener_base(){MappingFileExtention();}
	inline bool Open(char *filename,size_t id=idALLFILE,HWND hwnd=NULL)const
	{
		//MappingFileExtention();
		MAP_TYPE::const_iterator it = mmap.find(id);
		if(it == mmap.end())
			return false;
		const FileType &f = it->second;
		//char path[MAX_PATH]="";
		//dOpenFileDialog(filename,path,filter,defext,hwnd);
		if(false == FileOpenDialog(filename,f.title,f.filter,f.defext,hwnd))
			return false;
		return true;
	}
	inline bool operator ()(char *filename,size_t id=idALLFILE,HWND hwnd=NULL)const{
		return Open(filename,id,hwnd);
	}
	/*inline bool operator ()(char *filename)const{
		return Open(filename,idALLFILE,NULL);
	}*/
	

};

//static 宣言
template<class UTIL>
Opener_base<UTIL>::MAP_TYPE Opener_base<UTIL>::mmap;

template<class UTIL>
bool Opener_base<UTIL>::isOnce=false;

typedef Opener_base<> Opener; 


#endif
#if 0
class FlagManager{
BOOST_PROTECTED:
	char *m_mem;
public:
	FlagManager(UINT num){
		m_mem=NULL;
		Init(num);
	}
	virtual ~FlagManager(){
		End();
	}
	int Init(UINT num){
		size_t size = (num / 8) + 1;
		m_mem=(char *)malloc(size);
		if(!m_mem){return -1;}
		return 0;
	}
	int End(){
		if(m_mem){::free(m_mem);m_mem=NULL;}
	}
	int SetFlag(UINT n,bool flag){
		if(n < 8)
			m_mem &
	bool GetFlag(UINT n)
	UINT PermitSize()
	bool isOK(){return (m_mem != NULL);}
};
#endif



inline int dMessageBox(char *title,int flag,char *str,...){
	char s[1024];
	SET_VA_LIST(s,1024,str);
 	return MessageBox(NULL,s,title,flag);
}

inline bool DataCompar(char *data1,size_t size1,char *data2,size_t size2)
{
	if(size1 != size2){
		return false;
	}
	for(size_t i = 0;i<size1;i++){
		if(data1[i] != data2[i]){
			return false;
		}
	}
	return true;
}

/*
class To{
	inline const char *operator()(int in,int system,char *buff,size_t buffsize)
	{
	}
}
	*/	


/*
///XXXって何よ^^;;;;;;;
template<class T>
inline bool isStringXXX(char *str,T func,size_t len = strlen(str))
{
	for(int i=0;i<len;i++){
		if(!func(str[i])) return false;
	}
	return true;
}

inline bool isStringDigit(char *str,size_t len = strlen(str)){
	return isStringXXX(str,isDigit,len);
}

inline bool isStringAlpha(char *s,size_t len = strlen(str)){
	return isStringXXX(str,isAlpha,len);
}
*/	






///配列を貸してくれるクラス スレッドセーフじゃないので削除。
/*
template<typename SIZE>
class DirBuffer{
	static char WindowsDir[SIZE];
public:
	DirBuffer(){Reset();}
	void Reset(){::memset(WindowsDir,0,sizeof(WindowsDir));}
	size_t Size(){return SIZE;}
	char *GetBuff(){return WindowsDir;}
};*/


//extern void ChangeNewLineCode_AutoToWindows(const char *text,char *buff,size_t size);



extern void TestFunction02();

}

#endif
