/*
http://aaa.com
using System;
*/

/* 
  $Id: Util.h 30 2009-11-29 23:38:12Z krkim $ $Revision: 30 $
  $HeadURL: http://krkim-laptop/svn/DuruEdit/Src/DEApp/Util.h
*/
#include "stdafx.h"
#include "CFGFIND.h"


CFGFIND::CFGFIND()
{
	m_nMax[FFT_FINDTO] = 20;
	m_nMax[FFT_REPLACETO] = 20;
	m_nMax[FFT_FOLDER] = 20;
	m_nMax[FFT_TYPE] = 20;
	//파일찾기 플래그
	m_dwFindMask = AE_FIND_WRAP|AE_FIND_RECURSIVE | AE_FIND_INCLHIDN |AE_FIND_SHOWRESULT;
	m_dwShowOptionMask = 0xFFFF;
	m_nInitFindTo = 0x01|0x02;//0x01 = 검색어 채우기,0x02 = 블럭선택으로,0x02가 아니면 문자열뒤에 캐럿이동
	m_bSoundFailed = 1;
	lstrcpy(m_szKey,REG_DURUEDIT_IDE"\\FileFind");

	m_docwhere = DW_CURDOC;
	m_bShowFastFinder = 0;
}

CFGFIND::~CFGFIND()
{
	RemoveAll(FFT_FINDTO);
	RemoveAll(FFT_REPLACETO);
	RemoveAll(FFT_FOLDER);
	RemoveAll(FFT_TYPE);
}

void CFGFIND::Init()
{
	AddElement(FFT_TYPE,_T("*.*"));
	AddElement(FFT_TYPE,_T("*.vb;*.resx;*.xsd;*.wsdl;*.xaml;*.xml;*.htm;*.html;*.css"));
	AddElement(FFT_TYPE,_T("*.cs;*.resx;*.xsd;*.wsdl;*.xml;*.htm;*.html;*.css"));
	AddElement(FFT_TYPE,_T("*.htm;*.html;*.xml;*.php;*.asp;*.shtml;*.css"));
	AddElement(FFT_TYPE,_T("*.sql;*.ec;*.pc;*.udl;*.trc;*.cat;*.dsn;*.hdr;*.dump"));
	AddElement(FFT_TYPE,_T("*.c;*.cpp;*.cxx;*.cc;*.h;*.hpp;*.hxx;*.hh;*.inl;*.rc*;*.resx;*.idl;*.asm;*.inc"));
	AddElement(FFT_TYPE,_T("*.txt;*.ini;*.log;*.cap;*.csv"));

	CHAR path[MAX_PATH+2] = {0,};
	SHGetSpecialFolderPath(NULL,path,CSIDL_PERSONAL,FALSE);

	AddElement(FFT_FOLDER,_T(path));
	AddElement(FFT_FOLDER,_T("D:\\"));
	AddElement(FFT_FOLDER,_T("C:\\"));
	
}

void CFGFIND::RemoveAll(CFGFINDTYPE nType)
{
	for(int i = m_FileFindData[nType].size() - 1 ; i >= 0 ; i--){
		CFGFINDINFO *lpFI = m_FileFindData[nType][i];
		delete [] lpFI->szElement;
		delete lpFI;
	}
	m_FileFindData[nType].clear();
}

void CFGFIND::AddElement(CFGFINDTYPE nType,LPTSTR szElement)
{
	int len,i = 0;
	len = lstrlen(szElement);
	CFGFINDDATA::iterator it;
	for(it = m_FileFindData[nType].begin(); it != m_FileFindData[nType].end() ; it++,i++){
		CFGFINDINFO *lpFI = *it;
		//대소문자를 구분하여 기존에 같은것이 있으면 제거하고 새롭게 top위치에 등록한다. - case sensitive
		//인덱스가 0 이 최신것
		if((szElement && !lstrcmp(lpFI->szElement,szElement))
			|| (!szElement[0] && !*lpFI->szElement)){//found, delete it and re add tail for loadtime highest priority
			if(i == 0)
				return;//맨앞부분(최근)과 같으면 그냥 리턴
			delete [] lpFI->szElement;
			delete lpFI;
			m_FileFindData[nType].erase(it);
			break;
		}
	}
	
	CFGFINDINFO *lpFI = new CFGFINDINFO;
	lpFI->szElement = new TCHAR[len + 1];
	memset(lpFI->szElement,0,len + 1);
	lstrcpy(lpFI->szElement,szElement);
	m_FileFindData[nType].insert(m_FileFindData[nType].begin(),lpFI);

	int n = (int) m_FileFindData[nType].size();
	if(n > m_nMax[nType]){
		i = n - 1;
		while(i >= m_nMax[nType]){
			CFGFINDINFO *lpFI = m_FileFindData[nType][i];
			delete [] lpFI->szElement;
			delete lpFI;
			m_FileFindData[nType].erase(m_FileFindData[nType].begin() + i);
			i--;
		}
	}
}

CFGFINDINFO *CFGFIND::GetElementEx(CFGFINDTYPE nType,int nIndex)
{
	int n = (int) m_FileFindData[nType].size();
	if (nIndex >= n)
		return NULL;
	CFGFINDINFO *lpFI = m_FileFindData[nType][nIndex];
	return lpFI;
}

LPTSTR CFGFIND::GetElement(CFGFINDTYPE nType,int nIndex)
{
	CFGFINDINFO *lpFI = GetElementEx(nType,nIndex);
	if(lpFI) return lpFI->szElement;
	return NULL;
}

void CFGFIND::Load()
{
	CHAR lpBuff[MAX_PATH + 1];
	CHAR szValName[30];

	m_dwFindMask = REGU::LoadNumber(SHCU,m_szKey,"FindMask",m_dwFindMask);
	m_dwShowOptionMask = REGU::LoadNumber(SHCU,m_szKey,"ShowOption",m_dwShowOptionMask);//검색창의 4가지 페이지 종류
	m_nInitFindTo = REGU::LoadNumber(SHCU,m_szKey,"InitFindTo",m_nInitFindTo);
	m_bSoundFailed = REGU::LoadNumber(SHCU,m_szKey,"SoundOnFailed",m_bSoundFailed);
	m_docwhere = (DOCWHERE)REGU::LoadNumber(SHCU,m_szKey,"DocWhere",m_docwhere);;
	m_bShowFastFinder = REGU::LoadNumber(SHCU,m_szKey,"ShowFastFinder",m_bShowFastFinder);;

	REGU::LoadString(SHCU,m_szKey,"FFWindowPosition","-1,-1,-1,-1",lpBuff,MAX_PATH);
	char * dupl = strdup(lpBuff);
	char * token1 = strtok(dupl, ",");
	char * token2 = strtok(NULL, ",");
	char * token3 = strtok(NULL, ",");
	char * token4 = strtok(NULL, ",");
	if(token1) m_rcFFWindow.left = atoi(token1);
	if(token2) m_rcFFWindow.top = atoi(token2);
	if(token3) m_rcFFWindow.right = atoi(token3);
	if(token4) m_rcFFWindow.bottom = atoi(token4);
	free(dupl);
	for(int n = 0 ; n < 4 ; n ++){
		for(int i = 0;i < m_nMax[n];i++){
			if(n == FFT_FINDTO)
				wsprintf(szValName,"Find-%02d",i + 1);
			else if(n == FFT_REPLACETO)
				wsprintf(szValName,"Replace-%02d",i + 1);
			else if(n == FFT_FOLDER)
				wsprintf(szValName,"Where-%02d",i + 1);
			else if(n == FFT_TYPE)
				wsprintf(szValName,"FileType-%02d",i + 1);
			lpBuff[0] = NULL;
			REGU::LoadString(SHCU,m_szKey,szValName,"",lpBuff,MAX_PATH);
			if(lpBuff[0] == 0)
				break;
			
			CFGFINDINFO *lpFI = new CFGFINDINFO;
			lpFI->szElement = new TCHAR[lstrlen(lpBuff) + 1];
			lstrcpy(lpFI->szElement,lpBuff);
			m_FileFindData[n].push_back(lpFI);
		}
	}
}

void CFGFIND::Save()
{
	CFGFINDDATA::iterator it;
	CHAR szValName[30];
	CHAR szValue[128];

	REGU::RemoveKey(SHCU,m_szKey);
	REGU::SaveNumber(SHCU,m_szKey,"FindMask",m_dwFindMask);
	REGU::SaveNumber(SHCU,m_szKey,"ShowOption",m_dwShowOptionMask);
	REGU::SaveNumber(SHCU,m_szKey,"InitFindTo",m_nInitFindTo);
	REGU::SaveNumber(SHCU,m_szKey,"SoundOnFailed",m_bSoundFailed);
	REGU::SaveNumber(SHCU,m_szKey,"DocWhere",m_docwhere);
	REGU::SaveNumber(SHCU,m_szKey,"ShowFastFinder",m_bShowFastFinder);

	sprintf(szValue,"%d,%d,%d,%d",m_rcFFWindow.left,m_rcFFWindow.top,m_rcFFWindow.right,m_rcFFWindow.bottom);
	REGU::SaveString(SHCU,m_szKey,"FFWindowPosition",szValue);
	for(int n = 0 ; n < 4 ; n ++){
		int i = 0;
		for(it = m_FileFindData[n].begin(); it != m_FileFindData[n].end() ; it++,i++){//뒤에서 부터 저장
			CFGFINDINFO *lpFI = *it;
			if(n == FFT_FINDTO)
				wsprintf(szValName,"Find-%02d",i + 1);
			else if(n == FFT_REPLACETO)
				wsprintf(szValName,"Replace-%02d",i + 1);
			else if(n == FFT_FOLDER)
				wsprintf(szValName,"Where-%02d",i + 1);
			else if(n == FFT_TYPE)
				wsprintf(szValName,"FileType-%02d",i + 1);
			REGU::SaveString(SHCU,m_szKey,szValName,lpFI->szElement);
		}
	}
}

void CFGFIND::SerializeTo(HWND hComboBox,CFGFINDTYPE nType,BOOL bResetContent)
{
	CFGFINDDATA::iterator it;
	if(bResetContent)
		SendMessage(hComboBox,CB_RESETCONTENT,0,0);
	for(it = m_FileFindData[nType].begin(); it != m_FileFindData[nType].end() ; it++){
		CFGFINDINFO *lpFI = *it;
		if(lpFI->szElement){
			COMBOBOX_ADDSTRING_UNIQUE(hComboBox,lpFI->szElement)
		}
	}
	SendMessage(hComboBox,CB_SETCURSEL,0,0);
}

BOOL CFGFIND::GetDocWhereText(DOCWHERE docwhere,LPTSTR lpDocName,int maxlen)
{
	int i = 0,idx = docwhere - DW_CURDOC;
	TCHAR text[256];
	LoadString(KFCGetResourceInstance(),IDS_FIND_DOCLIST,text,sizeof(text));
	lpDocName[0] = NULL;
    TCHAR *p;
    //char * fmtDup = strdup(text);
    p = strtok(text, ";");
	while(p){
		if(i++ == idx)
			break;
		p = strtok(NULL, ";");
	}	
	if(p){
		lstrcpyn(lpDocName,p,maxlen);
		return TRUE;
	}
	return FALSE;
}

DOCWHERE CFGFIND::GetDocWhere(LPTSTR szWhere)
{
	TCHAR docwhere[80];
	for(int i = (int)DW_CURDOC; i < (int)DW_NOTDOC;i++){
		DOCWHERE T = (DOCWHERE)i;
		if(GetDocWhereText(T,docwhere,sizeof(docwhere))){
			if(!lstrcmpi(docwhere,szWhere))
				return (DOCWHERE) T;
		}
	}
	return DW_NOTDOC;
}
//bFile : 파일에서 찾기/바꾸기 등은 선택영역 불가하다
void CFGFIND::SerializeDocWhere(HWND hComboBox,BOOL bFile,BOOL bResetContent)
{
	CFGFINDDATA::iterator it;
	if(bResetContent)
		SendMessage(hComboBox,CB_RESETCONTENT,0,0);
	TCHAR docwhere[80];
	
	for(int i = (int)DW_CURDOC;i++){
		DOCWHERE T = (DOCWHERE)i;
		if(bFile && T == DW_SELDOC)
			continue;
		if(GetDocWhereText(T,docwhere,sizeof(docwhere))){
			COMBOBOX_ADDSTRING_UNIQUE(hComboBox,docwhere)
		}
		else
			break;
	}
	ComboBox_SetCurSel(hComboBox,m_docwhere);
}