// SPConsole.cpp : 응용 프로그램에 대한 클래스 동작을 정의합니다.
//

#include "stdafx.h"
#include "ConsoleApp.h"
#include "MainFrm.h"

#include "CustomControlSite.h"
//#include "Options.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CSPConsoleApp

BEGIN_MESSAGE_MAP(CSPConsoleApp, CWinApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
END_MESSAGE_MAP()


// CSPConsoleApp 생성

CSPConsoleApp::CSPConsoleApp()
{
	m_pimpldisp = NULL;
}

CSPConsoleApp::~CSPConsoleApp()
{
	if (m_pimpldisp)
		delete m_pimpldisp;
}


// 유일한 CSPConsoleApp 개체입니다.

CSPConsoleApp theApp;

// CSPConsoleApp 초기화

BOOL CSPConsoleApp::InitInstance()
{
	// 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
	// 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControls()가 필요합니다. 
	// InitCommonControls()를 사용하지 않으면 창을 만들 수 없습니다.
	InitCommonControls();

	CWinApp::InitInstance();

	// OLE 라이브러리를 초기화합니다.
	if (!AfxOleInit()) {
		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}
	AfxEnableControlContainer();

	CCustomOccManager *poccmgr = new CCustomOccManager;
	m_pimpldisp = new CImpIDispatch;
	AfxEnableControlContainer(poccmgr);

	CString strCmd = m_lpCmdLine;

	if (strCmd.IsEmpty())
	{
		char szPath[MAX_PATH]={0};
		GetCurrentPath(szPath);
		CString	strPath;
		
		strPath.Format("%s\\SP-Updater.exe",szPath);
#ifndef _DEBUG
		ShellExecute(NULL,"open",strPath,NULL,NULL,SW_SHOW);
		return FALSE;
#endif
	}

	HANDLE hMutex;
	do
	{
		hMutex = ::CreateMutex(NULL, TRUE, _T("SP-UpdaterXXXXXXXXXXXXXXX"));
	}while(GetLastError() == ERROR_ALREADY_EXISTS);

	CloseHandle(hMutex);

	// 업데이터 업데이트 - 업데이터에 의해 실행되는 경우 뿐이다.
	if (strCmd == "1")
	{
		char szPath[MAX_PATH]={0};
		GetCurrentPath(szPath);
		CString	strSrcPath;
		CString	strDesPath;
		strSrcPath.Format("%s\\update\\SP-Updater.exe",szPath);
		strDesPath.Format("%s\\SP-Updater.exe",szPath);

		if(CopyFile(strSrcPath,strDesPath,FALSE))
			DeleteFile(strSrcPath);
	}

	char szPath[MAX_PATH]={0};
	GetCurrentPath(szPath);
	CString strPath;
	strPath.Format(_T("%s\\%s"),szPath,CFG_FILENAME);
	COptions::Init(strPath);

	CMainFrame* pFrame = new CMainFrame;
	if (!pFrame)
		return FALSE;

	m_pMainWnd = pFrame;
	if (pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW, NULL, NULL)) {
		pFrame->ShowWindow(SW_SHOW);
		pFrame->UpdateWindow();
	}

#ifdef _DEBUG
	AfxCheckMemory();
#endif

	return TRUE;
}


// CSPConsoleApp 메시지 처리기



// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// 대화 상자 데이터
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원

// 구현
protected:
	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL OnInitDialog();
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// 대화 상자를 실행하기 위한 응용 프로그램 명령입니다.
void CSPConsoleApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}


// CSPConsoleApp 메시지 처리기



// 사용자 정의 함수
CString GetErrorMessage(DWORD dwError)
{
	CString sError;
	LPVOID lpBuffer;

	if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpBuffer, 0, NULL))
		sError = "알 수 없는 오류입니다.";
	else
		sError = (LPCTSTR)lpBuffer;
 
	LocalFree(lpBuffer);

	return sError;
}

BOOL DeleteDirectory(CString sDirectory)
{
/*
	// no UI
	if (sDirectory.Right(1) != _T("\\"))
		sDirectory += _T("\\");

	sDirectory += _T("*");

	CFileFind finder;

	BOOL bFound = finder.FindFile(sDirectory);
	while (bFound) {
		bFound = finder.FindNextFile();

		if (finder.IsDots())
			continue;

		if (finder.IsDirectory()) {
			if (!DeleteDirectory(finder.GetFilePath()))
				return false;
		}
		else {
			if (!DeleteFile(finder.GetFilePath()))
				return false;
		}
	}
	finder.Close();

	sDirectory = sDirectory.Left(sDirectory.ReverseFind('\\'));
	RemoveDirectory(sDirectory);

	return true;
*/
	// UI
	if (sDirectory.Right(1) == _T("\\"))
		sDirectory.Delete(sDirectory.GetLength());

	char szPath[MAX_PATH];

	ZeroMemory(szPath, sizeof(szPath));
	CopyMemory(szPath, sDirectory, sDirectory.GetLength());

	SHFILEOPSTRUCT shfo = {0};
	shfo.hwnd                  = NULL;
	shfo.wFunc                 = FO_DELETE;
	shfo.pFrom                 = szPath;
	shfo.pTo                   = NULL;
	shfo.fFlags                = FOF_NOCONFIRMATION | FOF_NOERRORUI;
	shfo.fAnyOperationsAborted = false;
	shfo.hNameMappings         = NULL;
	shfo.lpszProgressTitle     = NULL;

	return SHFileOperation(&shfo) == 0;
}

int KrCompare(LPCTSTR pszText1, LPCTSTR pszText2)
{
	int nLen = (int)strlen(pszText1);

	PBYTE pbyText1 = (PBYTE)pszText1;
	PBYTE pbyText2 = (PBYTE)pszText2;

	BOOL bText1Alpha, bText2Alpha;
	for (int i = 0; i < nLen; i++) {
		if (pbyText2[i] == NULL)
			return 1;

		if (pbyText1[i] == pbyText2[i])
			continue;

		bText1Alpha = isalpha(pbyText1[i]);
		bText2Alpha = isalpha(pbyText2[i]);

		if (!bText1Alpha && bText2Alpha)
			return -1;

		if (bText1Alpha && !bText2Alpha)
			return 1;

		if (pbyText1[i] < pbyText2[i])
			return -1;

		if (pbyText1[i] > pbyText2[i])
			return 1;
	}

	if (pbyText2[nLen] != NULL)
		return -1;

	return 0;
}

CString NumericFormat(__int64 nNumeric)
{
    CString sNumeric;
    sNumeric.Format("%I64d", nNumeric);

	int nStartPos = sNumeric.GetLength();
	for (int i = nStartPos, j = 0; i > 0; i--, j++) {
		if (i != nStartPos && (j % 3) == 0)
		sNumeric.Insert(i, ',');
	}

	return sNumeric;
}

CString NumericFormatWithPoint(long double nNumeric)
{
    CString sNumeric;
    sNumeric.Format("%.2f", nNumeric);

	int nStartPos = sNumeric.Find('.');
	for (int i = nStartPos, j = 0; i > 0; i--, j++) {
		if (i != nStartPos && (j % 3) == 0)
		sNumeric.Insert(i, ',');
	}

	return sNumeric;
}

CString BYTE2KMBYTE(__int64 nBytes, int nFlag, bool bShowDecimalPoint)
{
	CString sValue;

	char* szUnit[] = {"Bytes", "KB", "MB", "GB", "TB", "PT"};

	if (nFlag == 0) {
		for (nFlag = 5; nFlag > 0; nFlag--)
			if (((UINT64)nBytes >> (nFlag * 10)) >= 1)
				break;
	}

	double nPow = pow(1024.0, (double)nFlag);
	if (bShowDecimalPoint && nFlag > 0)
		sValue = NumericFormatWithPoint((long double)nBytes / nPow) + szUnit[nFlag];
	else
		sValue = NumericFormat((__int64)ceil((long double)nBytes / nPow)) + szUnit[nFlag];

	return sValue;
}

CString GetValidFileName(LPCTSTR pszFileName)
{
	CString sFileName = pszFileName;

	if (sFileName.Find('/') >= 0 || sFileName.Find('\\') >= 0 || sFileName.Find(':') >= 0
		|| sFileName.Find('*') >= 0 || sFileName.Find('?') >= 0 || sFileName.Find('"') >= 0
		|| sFileName.Find('<') >= 0 || sFileName.Find('>') >= 0 || sFileName.Find('|') >= 0) {
		AfxMessageBox("파일명에 다음과 같은 문자가 올 수 없습니다:\n/ \\ : * ? \" < > |", MB_ICONEXCLAMATION);
		return "";
	}
	sFileName.Trim();

	return sFileName;
}

bool IsPathItself(CString sSrcPath, CString sDstPath)
{
	int nSrcLen = sSrcPath.GetLength();
	if (nSrcLen > sDstPath.GetLength())
		return false;

	int iPos = sDstPath.Find(nSrcLen, '/');
	if (iPos > 0)
		sDstPath = sDstPath.Left(iPos);

	return sSrcPath == sDstPath;
}

bool WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite)
{
	DWORD dwWritten;
	while (nNumberOfBytesToWrite > 0) {
		if (!WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &dwWritten, NULL))
			return false;

		nNumberOfBytesToWrite -= dwWritten;
	}

	return true;
}

int GetCurrentPath(char* pszPath)
{
	char	szPath[MAX_PATH*2]={0};
	char* pData;

	GetModuleFileName(NULL,szPath,MAX_PATH);

	pData = strrchr(szPath,'\\');

	__w64 int len = pData-szPath;
	strncpy(pszPath,szPath,len);
	pszPath[len] = 0; //cause wcsncpy does not appent null character
	return (int)len;
}


BOOL CAboutDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  여기에 추가 초기화 작업을 추가합니다.
#ifdef _OPENDISK
	SetWindowText("Opendisk Console 정보");
	GetDlgItem(IDC_STATIC_ABOUT)->SetWindowText("Opendisk Console V1.0.1.0");
#else
	SetWindowText("SP-Console 정보");
	GetDlgItem(IDC_STATIC_ABOUT)->SetWindowText("ICS SP-Console V1.0.1.0");
#endif

	return TRUE;  // return TRUE unless you set the focus to a control
	// 예외: OCX 속성 페이지는 FALSE를 반환해야 합니다.
}
