// MainFrm.cpp : CMainFrame 클래스의 구현
//

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

#include "MainFrm.h"

#include "RemoteView.h"
#include "RemoteTreeCtrl.h"
#include "RemoteListCtrl.h"
#include "LocalView.h"
#include "LocalTreeCtrl.h"
#include "LocalListCtrl.h"

#include "ConnectDlg.h"
#include "ConfigDlg.h"
#include "RegUtil.h"
#include "Crypt.h"

#include "Struct.h"

#include "ne_socket.h"
#include "ne_uri.h"
#include "ne_request.h"
#include "ne_xml.h"
#include "ne_string.h"
#include ".\mainfrm.h"

typedef struct COMMLIB_HANDLE {
	ne_session*  pnsess;
	ne_uri       nuri;
	string       sUserId;
	string       sPassword;
	string       sDavAuth;
	DWORD        dwError;
	string       sError;

	// 업/다운 관련
	HANDLE       hThread;
	HANDLE       hWaitEvent;
	UINT32       uJob;
	string       sJobParam;
	cl_callback  proc;
	void*        pParam;
	HANDLE       hTranFile;
	__int64		 nExFileSize;
	__int64      iTranPos;
	__int64      nFileSize;
	DWORD        dwOldTick;
	int          nTranStop;
	string       sRedirect;
	string		 sDomain2;

	set<PCLSERVICE_STRUCT>  setServiceList;
	set<PCLPATHINFO_STRUCT> setPathInfoList;
	set<PCLFILE_STRUCT>     setFileList;
} COMMLIB_STRUCT, *PCOMMLIB_STRUCT;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


CString GetErrorMessage(DWORD dwError);

bool WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite);
int GetCurrentPath(char* pszPath);

// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_CLOSE()
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_COMMAND(ID_FILE_RECONNECT, OnFileReconnect)
	ON_UPDATE_COMMAND_UI(ID_FILE_RECONNECT, OnUpdateFileReconnect)
	ON_COMMAND(ID_FILE_DISCONNECT, OnFileDisconnect)
	ON_UPDATE_COMMAND_UI(ID_FILE_DISCONNECT, OnUpdateFileDisconnect)
	ON_COMMAND(ID_FILE_UPLOAD, OnFileUpload)
	ON_UPDATE_COMMAND_UI(ID_FILE_UPLOAD, OnUpdateFileUpload)
	ON_COMMAND(ID_FILE_DOWNLOAD, OnFileDownload)
	ON_UPDATE_COMMAND_UI(ID_FILE_DOWNLOAD, OnUpdateFileDownload)
	ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
	ON_COMMAND(ID_VIEW_LTREE, OnViewLtree)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LTREE, OnUpdateViewLtree)
	ON_COMMAND(ID_VIEW_RTREE, OnViewRtree)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RTREE, OnUpdateViewRtree)
	ON_COMMAND(ID_VIEW_LSTATUS, OnViewLstatus)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LSTATUS, OnUpdateViewLstatus)
	ON_COMMAND(ID_VIEW_RSTATUS, OnViewRstatus)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RSTATUS, OnUpdateViewRstatus)
	ON_COMMAND(ID_VIEW_MID_TOOLBAR, OnViewMidToolbar)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MID_TOOLBAR, OnUpdateViewMidToolbar)
	ON_COMMAND(ID_VIEW_RLIST_TYPE1, OnViewRlistType1)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RLIST_TYPE1, OnUpdateViewRlistType1)
	ON_COMMAND(ID_VIEW_RLIST_TYPE2, OnViewRlistType2)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RLIST_TYPE2, OnUpdateViewRlistType2)
	ON_COMMAND(ID_VIEW_RLIST_TYPE3, OnViewRlistType3)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RLIST_TYPE3, OnUpdateViewRlistType3)
	ON_COMMAND(ID_VIEW_RLIST_TYPE4, OnViewRlistType4)
	ON_UPDATE_COMMAND_UI(ID_VIEW_RLIST_TYPE4, OnUpdateViewRlistType4)
	ON_COMMAND(ID_VIEW_LLIST_TYPE0, OnViewLlistType0)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LLIST_TYPE0, OnUpdateViewLlistType0)
	ON_COMMAND(ID_VIEW_LLIST_TYPE1, OnViewLlistType1)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LLIST_TYPE1, OnUpdateViewLlistType1)
	ON_COMMAND(ID_VIEW_LLIST_TYPE2, OnViewLlistType2)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LLIST_TYPE2, OnUpdateViewLlistType2)
	ON_COMMAND(ID_VIEW_LLIST_TYPE3, OnViewLlistType3)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LLIST_TYPE3, OnUpdateViewLlistType3)
	ON_COMMAND(ID_VIEW_LLIST_TYPE4, OnViewLlistType4)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LLIST_TYPE4, OnUpdateViewLlistType4)
	ON_COMMAND(ID_CFG_OVERWITE_ASK, OnCfgOverwriteAsk)
	ON_UPDATE_COMMAND_UI(ID_CFG_OVERWITE_ASK, OnUpdateCfgOverwriteAsk)
	ON_COMMAND(ID_CFG_OVERWITE1, OnCfgOverwrite1)
	ON_UPDATE_COMMAND_UI(ID_CFG_OVERWITE1, OnUpdateCfgOverwrite1)
	ON_COMMAND(ID_CFG_OVERWITE2, OnCfgOverwrite2)
	ON_UPDATE_COMMAND_UI(ID_CFG_OVERWITE2, OnUpdateCfgOverwrite2)
	ON_COMMAND(ID_CFG_OVERWITE3, OnCfgOverwrite3)
	ON_UPDATE_COMMAND_UI(ID_CFG_OVERWITE3, OnUpdateCfgOverwrite3)
	ON_COMMAND(ID_CFG_OVERWITE4, OnCfgOverwrite4)
	ON_UPDATE_COMMAND_UI(ID_CFG_OVERWITE4, OnUpdateCfgOverwrite4)
	ON_COMMAND(ID_CFG_UPDATE, OnCfgUpdate)
	ON_UPDATE_COMMAND_UI(ID_CFG_UPDATE, OnUpdateCfgUpdate)
	ON_COMMAND(ID_CFG_CONFIG, OnCfgConfig)

	ON_MESSAGE(WMU_TRANSFER_DLG_CLOSE, OnTransferDlgClose)
	ON_MESSAGE(WMU_UPDATE_CONTROL_STATUS, OnUpdateControlStatus)

	ON_XTP_CREATECONTROL()
	ON_WM_COPYDATA()
	
END_MESSAGE_MAP()


// CMainFrame 생성/소멸

CMainFrame::CMainFrame()
{
	// Load windows status...
	m_bShowTopToolBar = COptions::GetOptionVal(OPTION_SHOWTOPTOOLBAR);
	m_bShowMidToolBar = COptions::GetOptionVal(OPTION_SHOWMIDTOOLBAR);

	m_bShowRemoteTree = COptions::GetOptionVal(OPTION_SHOWREMOTETREE);
	m_bShowLocalTree  = COptions::GetOptionVal(OPTION_SHOWLOCALTREE);

	m_nRemoteListType = COptions::GetOptionVal(OPTION_REMOTELISTSTYLE);
	m_nLocalListType  = COptions::GetOptionVal(OPTION_LOCALLISTSTYLE);

	m_bShowRemoteStatus = COptions::GetOptionVal(OPTION_SHOWREMOTESTATUS);
	m_bShowLocalStatus  = COptions::GetOptionVal(OPTION_SHOWLOCALSTATUS);

	m_fl = FL_LOCAL;

	// Initialize...
	m_cbs             = CBS_NONE;
	m_bDragFromRemote = false;
	m_htiDragTarget   = NULL;

	m_bInitialzed = false;

	m_bSizing = false;

	m_passwordErrCnt = 0;
}

CMainFrame::~CMainFrame()
{
}


BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
	switch (pMsg->message) {
	case WM_KEYDOWN:
		if (pMsg->wParam == VK_TAB) {
			CWnd *pwndFocused = GetFocus();

			// 정방향
			if (!(GetKeyState(VK_SHIFT) & 128))
				return TRUE;
			// 역방향
			else
				return TRUE;
		}
		break;
	}

	return CFrameWnd::PreTranslateMessage(pMsg);
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if (!CFrameWnd::PreCreateWindow(cs))
		return FALSE;


	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);

	return TRUE;
}

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
	NONCLIENTMETRICS nc;
    ZeroMemory(&nc, sizeof(nc));
    nc.cbSize = sizeof(nc);

    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &nc, 0);
    m_font.CreateFontIndirect(&nc.lfMenuFont);
    SetFont(&m_font);

	if (!m_splitter.CreateStatic(this, 2, 1)) {
		TRACE0("Failed to create splitter window\n");
		return FALSE;
	}

	if (!m_splitter.CreateView(0, 0, RUNTIME_CLASS(CRemoteView), CSize(0, 0), pContext)) {
		TRACE0("Failed to create CView1\n");
		return FALSE;
	}

	if (!m_splitter.CreateView(1, 0, RUNTIME_CLASS(CLocalView), CSize(0, 0), pContext)) {
		TRACE0("Failed to create CView2\n");
		return FALSE;
	}

	m_splitter.SetSplitterStyle(XT_SPLIT_NOFULLDRAG | XT_SPLIT_NOBORDER);

	m_pRemoteView = (CRemoteView*)m_splitter.GetPane(0, 0);
	m_pLocalView  = (CLocalView*)m_splitter.GetPane(1, 0);

	return TRUE;
}


// CMainFrame 진단

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG


// CMainFrame 메시지 처리기

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!InitCommandBars())
		return -1;

	CXTPCommandBars* pCommandBars = GetCommandBars();

	CXTPMenuBar* pMenuBar = pCommandBars->SetMenu(_T("Menu Bar"), IDR_MAINFRAME);
	if (!pMenuBar) {
		TRACE0("Failed to create menubar\n");
		return -1;
	}

#ifdef _OPENDISK
	CXTPControls* pControls = NULL;
	pControls = pMenuBar->GetControls();
	pControls->FindControl(xtpControlButton, ID_HELP_HOMEPAGE, FALSE, TRUE)->SetCaption("Opendisk Console 홈페이지(&G)");
	pControls->FindControl(xtpControlButton, ID_APP_ABOUT, FALSE, TRUE)->SetCaption("Opendisk Console 정보(&A)");
#endif

	CXTPToolBar* pToolBar = (CXTPToolBar *)pCommandBars->Add(_T("Tool Bar"), xtpBarTop);
	if (!pToolBar || !pToolBar->LoadToolBar(IDR_MAINFRAME)) {
		TRACE0("Failed to create toolbar\n");
		return -1;
	}

	UINT nCommands[] = {ID_FILE_RECONNECT, ID_FILE_DISCONNECT, ID_VIEW_REFRESH, ID_VIEW_RTREE, ID_VIEW_LTREE, ID_CFG_CONFIG};

	CXTPPaintManager* pPaintManager = new CXTPNativeXPTheme();

	XTP_COMMANDBARS_ICONSINFO* pIconinfo = pPaintManager->GetIconsInfo();
	pIconinfo->bUseDisabledIcons = TRUE;
	pIconinfo->bUseFadedIcons    = TRUE;
	pIconinfo->bIconsWithShadow  = FALSE;

	XTPPaintManager()->SetCustomTheme(pPaintManager);
	XTPImageManager()->SetIcons(IDB_TOOLBAR, nCommands, sizeof(nCommands) / sizeof(UINT), CSize(24, 24));
	XTPImageManager()->SetIcons(IDB_MENUBAR, nCommands, sizeof(nCommands) / sizeof(UINT), CSize(16, 16));

	pCommandBars->GetCommandBarsOptions()->szLargeIcons = CSize(24, 24);
	pCommandBars->GetCommandBarsOptions()->bLargeIcons  = TRUE;

	pCommandBars->GetCommandBarsOptions()->bShowExpandButtonAlways = FALSE;

	RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);

	GetCommandBars()->RedrawCommandBars();

	SetIcon(::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)), FALSE);

	RestorePlacement();

	LPITEMIDLIST piil;
	SHFILEINFO   shfi;

	SHGetSpecialFolderLocation(m_hWnd, CSIDL_DRIVES, &piil);
	SHGetFileInfo((LPCTSTR)piil, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);
	m_iComputerIcon = shfi.iIcon;
	CoTaskMemFree(piil);

	SHGetSpecialFolderLocation(m_hWnd, CSIDL_NETWORK, &piil);
	SHGetFileInfo((LPCTSTR)piil, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);
	m_iNetworkIcon = shfi.iIcon;
	CoTaskMemFree(piil);

	int  cDrive = 'C';
	char szDrive[MAX_PATH];
	while (TRUE) {
		sprintf(szDrive, "%c:\\", cDrive);
		if (!SHGetFileInfo(szDrive, 0, &shfi, sizeof(shfi), SHGFI_ICON | SHGFI_SMALLICON)) {
			cDrive++;
			continue;
		}

		m_iDriveIcon = shfi.iIcon;
		break;
	}

	SHGetFileInfo("", FILE_ATTRIBUTE_DIRECTORY, &shfi, sizeof(shfi), SHGFI_ICON | SHGFI_SMALLICON);
	m_iFolderIcon = shfi.iIcon;

	m_bmFolder.LoadBitmap(IDB_M_FOLDER);
	m_bmCopy.LoadBitmap(IDB_M_COPY);
	m_bmCut.LoadBitmap(IDB_M_CUT);
	m_bmPaste.LoadBitmap(IDB_M_PASTE);

	SetWindowText(APP_TITLE);

	PostMessage(WMU_UPDATE_CONTROL_STATUS);

	ShowWindow(SW_SHOW);
	SetForegroundWindow();

	m_pwndRemote = &m_pRemoteView->m_tree;
	m_pwndLocal  = &m_pLocalView->m_tree;

	ShowLoginDialog();

	return 0;
}

void CMainFrame::OnClose()
{
	CString sPos;

	WINDOWPLACEMENT wp;
	GetWindowPlacement(&wp);

	int nStatus = 0;
	if (wp.showCmd == SW_MAXIMIZE || wp.showCmd == SW_SHOWMAXIMIZED)
		nStatus = 1;

	sPos.Format(_T("%d %d %d %d %d"), nStatus, wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);

	COptions::SetOption(OPTION_WINDOWSPOS, sPos);

	// Splitter 위치 저장
	int nCurRowSize, nMinRowSize;
	m_splitter.GetRowInfo(0, nCurRowSize, nMinRowSize);
	sPos.Format("%d", nCurRowSize);
	COptions::SetOption(OPTION_SPLITTERSIZE, sPos);

	CFrameWnd::OnClose();
}

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
//	m_bSizing = true;

	CFrameWnd::OnSize(nType, cx, cy);

//	m_bSizing = false;
}

BOOL CMainFrame::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}

void CMainFrame::OnFileReconnect()
{
	if (AfxMessageBox("다시 접속 하시겠습니까?", MB_YESNO | MB_ICONQUESTION) != IDYES)
		return;

	Disconnect();
	Connect();
}

void CMainFrame::OnUpdateFileReconnect(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_mapHcl.GetCount() > 0);
}

void CMainFrame::OnFileDisconnect()
{
	if (AfxMessageBox("접속을 끊으시겠습니까?", MB_YESNO | MB_ICONQUESTION) != IDYES)
		return;

	Disconnect();
	ShowLoginDialog();
}

void CMainFrame::OnUpdateFileDisconnect(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_mapHcl.GetCount() > 0);
}

void CMainFrame::OnFileUpload()
{
	Upload();
}

void CMainFrame::OnUpdateFileUpload(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_pLocalView->m_btnUpload.IsWindowEnabled());
}

void CMainFrame::OnFileDownload()
{
	Download();
}

void CMainFrame::OnUpdateFileDownload(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(m_pLocalView->m_btnDownload.IsWindowEnabled());
}

void CMainFrame::OnViewMidToolbar()
{
	m_bShowMidToolBar = !m_bShowMidToolBar;
	m_pLocalView->RedrawControlEx();
}

void CMainFrame::OnUpdateViewMidToolbar(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_bShowMidToolBar);
}

void CMainFrame::OnViewRtree()
{
	m_bShowRemoteTree = !m_bShowRemoteTree;
	m_pRemoteView->RedrawControl();
}

void CMainFrame::OnUpdateViewRtree(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_bShowRemoteTree);
}

void CMainFrame::OnViewLtree()
{
	m_bShowLocalTree = !m_bShowLocalTree;
	m_pLocalView->RedrawControlEx();
}

void CMainFrame::OnUpdateViewLtree(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_bShowLocalTree);
}

void CMainFrame::OnViewRefresh()
{
	BeginWaitMessage();

	m_pLocalView->RefreshItem();
	m_pRemoteView->RefreshItem();

	EndWaitMessage();
}

void CMainFrame::OnViewRstatus()
{
	m_bShowRemoteStatus = !m_bShowRemoteStatus;
	m_pRemoteView->RedrawControl();
}

void CMainFrame::OnUpdateViewRstatus(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_bShowRemoteStatus);
}

void CMainFrame::OnViewLstatus()
{
	m_bShowLocalStatus = !m_bShowLocalStatus;
	m_pLocalView->RedrawControlEx();
}

void CMainFrame::OnUpdateViewLstatus(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_bShowLocalStatus);
}

void CMainFrame::OnViewRlistType1()
{
	m_nRemoteListType = 1;
	m_pRemoteView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewRlistType1(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nRemoteListType == 1);
}

void CMainFrame::OnViewRlistType2()
{
	m_nRemoteListType = 2;
	m_pRemoteView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewRlistType2(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nRemoteListType == 2);
}

void CMainFrame::OnViewRlistType3()
{
	m_nRemoteListType = 3;
	m_pRemoteView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewRlistType3(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nRemoteListType == 3);
}

void CMainFrame::OnViewRlistType4()
{
	m_nRemoteListType = 4;
	m_pRemoteView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewRlistType4(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nRemoteListType == 4);
}

void CMainFrame::OnViewLlistType0()
{
	m_nLocalListType = 0;
	m_pLocalView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewLlistType0(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nLocalListType == 0);
}

void CMainFrame::OnViewLlistType1()
{
	m_nLocalListType = 1;
	m_pLocalView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewLlistType1(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nLocalListType == 1);
}

void CMainFrame::OnViewLlistType2()
{
	m_nLocalListType = 2;
	m_pLocalView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewLlistType2(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nLocalListType == 2);
}

void CMainFrame::OnViewLlistType3()
{
	m_nLocalListType = 3;
	m_pLocalView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewLlistType3(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nLocalListType == 3);
}

void CMainFrame::OnViewLlistType4()
{
	m_nLocalListType = 4;
	m_pLocalView->ApplyListStyle();
}

void CMainFrame::OnUpdateViewLlistType4(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_nLocalListType == 4);
}

#define FILEEXISTS_ASK       0
#define FILEEXISTS_OVERWRITE 1
#define FILEEXISTS_RESUME    2
#define FILEEXISTS_RENAME    3
#define FILEEXISTS_SKIP      4
#define FILEEXISTS_UPDATE    5

void CMainFrame::OnCfgOverwriteAsk()
{
	COptions::SetOption(OPTION_WRITEPOLICY, FILEEXISTS_ASK);
}

void CMainFrame::OnUpdateCfgOverwriteAsk(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(COptions::GetOptionVal(OPTION_WRITEPOLICY) == FILEEXISTS_ASK);
}

void CMainFrame::OnCfgOverwrite1()
{
	COptions::SetOption(OPTION_WRITEPOLICY, FILEEXISTS_OVERWRITE);
}

void CMainFrame::OnUpdateCfgOverwrite1(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(COptions::GetOptionVal(OPTION_WRITEPOLICY) == FILEEXISTS_OVERWRITE);
}

void CMainFrame::OnCfgOverwrite2()
{
	COptions::SetOption(OPTION_WRITEPOLICY, FILEEXISTS_RESUME);
}

void CMainFrame::OnUpdateCfgOverwrite2(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(COptions::GetOptionVal(OPTION_WRITEPOLICY) == FILEEXISTS_RESUME);
}

void CMainFrame::OnCfgOverwrite3()
{
	COptions::SetOption(OPTION_WRITEPOLICY, FILEEXISTS_RENAME);
}

void CMainFrame::OnUpdateCfgOverwrite3(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(COptions::GetOptionVal(OPTION_WRITEPOLICY) == FILEEXISTS_RENAME);
}

void CMainFrame::OnCfgOverwrite4()
{
	COptions::SetOption(OPTION_WRITEPOLICY, FILEEXISTS_SKIP);
}

void CMainFrame::OnUpdateCfgOverwrite4(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(COptions::GetOptionVal(OPTION_WRITEPOLICY) == FILEEXISTS_SKIP);
}

void CMainFrame::OnCfgUpdate()
{
	COptions::SetOption(OPTION_WRITEPOLICY, FILEEXISTS_UPDATE);
}

void CMainFrame::OnUpdateCfgUpdate(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(COptions::GetOptionVal(OPTION_WRITEPOLICY) == FILEEXISTS_UPDATE);
}	

void CMainFrame::OnCfgConfig()
{
	CConfigDlg dlg;
	dlg.DoModal();
}

LRESULT CMainFrame::OnUpdateControlStatus(WPARAM wParam, LPARAM lParam)
{
	CRemoteTreeCtrl *prtree = m_pRemoteView->GetTreeCtrl();
	CRemoteListCtrl *prlist = m_pRemoteView->GetListCtrl();

	// 새폴더, 삭제 버튼
	if (m_fl == FL_REMOTE) {
		if (prtree->GetSelectedItem() == prtree->GetRootItem()) {
			m_pLocalView->m_btnNewFolder.EnableWindow(FALSE);
			m_pLocalView->m_btnDelete.EnableWindow(FALSE);
		}
		else {
			m_pLocalView->m_btnNewFolder.EnableWindow(TRUE);
			m_pLocalView->m_btnDelete.EnableWindow(m_pRemoteView->m_nSelectedCount > 0);
		}
	}
	else {
		if (m_pLocalView->GetSelectedPath() == "") {
			m_pLocalView->m_btnNewFolder.EnableWindow(FALSE);
			m_pLocalView->m_btnDelete.EnableWindow(FALSE);
		}
		else {
			m_pLocalView->m_btnNewFolder.EnableWindow(TRUE);
			m_pLocalView->m_btnDelete.EnableWindow(m_pLocalView->m_nSelectedCount > 0 && m_pLocalView->m_nSelectedSecialObj == 0);
		}
	}

	// 올리기 버튼
	if (prtree->GetSelectedItem() == prtree->GetRootItem()) {
		m_pLocalView->m_btnUpload.EnableWindow(FALSE);
	}
	else {
		if (m_pwndLocal == &m_pLocalView->m_tree)
			m_pLocalView->m_btnUpload.EnableWindow(m_pLocalView->GetSelectedPath() != "");
		else
			m_pLocalView->m_btnUpload.EnableWindow(m_pLocalView->m_nSelectedCount > 0 && m_pLocalView->m_nSelectedSecialObj == 0);
	}

	// 내리기 버튼
	if (m_pLocalView->GetSelectedPath() == "" || prtree->GetSelectedItem() == prtree->GetRootItem()) {
		m_pLocalView->m_btnDownload.EnableWindow(FALSE);
	}
	else {
		if (m_pwndRemote == &m_pRemoteView->m_tree)
			m_pLocalView->m_btnDownload.EnableWindow(((PRTREEITEM_STRUCT)m_pRemoteView->m_tree.GetItemData(m_pRemoteView->m_tree.GetSelectedItem()))->nClass == TNS_FOLDER);
		else
			m_pLocalView->m_btnDownload.EnableWindow(m_pRemoteView->m_nSelectedCount > 0);
	}

	return S_OK;
}

LRESULT CMainFrame::OnTransferDlgClose(WPARAM wParam, LPARAM lParam)
{
	if (wParam == NULL)
		return S_OK;

	UpdateVolumeInfo((HTREEITEM)wParam);
	m_pRemoteView->RefreshItem();

	return S_OK;
}

int CMainFrame::OnCreateControl(LPCREATECONTROLSTRUCT lpCreateControl)
{
	switch (lpCreateControl->nID) {
//	case IDR_POP_LLIST:
//		lpCreateControl->controlType = xtpControlSplitButtonPopup;
//		return TRUE;
	case ID_INFORMATIONSTR:
		lpCreateControl->buttonStyle = xtpButtonCaption;
		return TRUE;
	case ID_INFORMATION:
		{
			CXTPToolBar* ptb = DYNAMIC_DOWNCAST(CXTPToolBar, lpCreateControl->pCommandBar);
			if (!ptb)
				return FALSE;

			CXTPControlComboBox* pComboUrl = (CXTPControlComboBox*)CXTPControlComboBox::CreateObject();
			pComboUrl->AddString(_T("[알림]테스트1"));
			pComboUrl->AddString(_T("[안내]테스트2"));
			pComboUrl->AddString(_T("[이벤트]테스트2"));
			pComboUrl->SetWidth(300);
			pComboUrl->SetDropDownWidth(300);
			pComboUrl->SetDropDownListStyle(FALSE);
			pComboUrl->SetFlags(xtpFlagManualUpdate);
			pComboUrl->SetCurSel(0);

			lpCreateControl->pControl = pComboUrl;
			return TRUE;
		}
		return TRUE;
	case ID_VIEW_REFRESH:
	case ID_VIEW_RTREE:
	case ID_VIEW_LTREE:
	case ID_CFG_CONFIG:
	case ID_VIEW_ALL:
		lpCreateControl->buttonStyle = xtpButtonIconAndCaption;
		return TRUE;
	}

	return FALSE;
}

BOOL CMainFrame::RestorePlacement()
{
	int  nStatus, nRowSize;
	RECT rc;

	CString sPos = COptions::GetOption(OPTION_WINDOWSPOS);
	int     nPos;

	nPos = sPos.Find(" ");
	if (nPos == -1) {
		CenterWindow();
		goto RECALC_SPLITTER_SIZE;
	}
	nStatus = _ttoi(sPos.Left(nPos));
	sPos = sPos.Mid(nPos + 1);

	nPos = sPos.Find(" ");
	if (nPos == -1) {
		CenterWindow();
		goto RECALC_SPLITTER_SIZE;
	}
	rc.left = _ttoi(sPos.Left(nPos));
	sPos = sPos.Mid(nPos + 1);

	nPos = sPos.Find(" ");
	if (nPos == -1) {
		CenterWindow();
		goto RECALC_SPLITTER_SIZE;
	}
	rc.top = _ttoi(sPos.Left(nPos));
	sPos = sPos.Mid(nPos + 1);

	nPos = sPos.Find(" ");
	if (nPos == -1) {
		CenterWindow();
		goto RECALC_SPLITTER_SIZE;
	}
	rc.right = _ttoi(sPos.Left(nPos));
	sPos = sPos.Mid(nPos + 1);

	if (sPos == "") {
		CenterWindow();
		goto RECALC_SPLITTER_SIZE;
	}
	rc.bottom = _ttoi(sPos);

	WINDOWPLACEMENT wp;
	wp.length = sizeof(wp);

	wp.flags = 0;
	wp.rcNormalPosition = rc;

	wp.showCmd = (nStatus == 1) ? SW_MAXIMIZE : SW_RESTORE;

	if (!SetWindowPlacement(&wp))
		return FALSE;

RECALC_SPLITTER_SIZE:
	sPos = COptions::GetOption(OPTION_SPLITTERSIZE);
	if (sPos != "")
		nRowSize = atol(sPos);
	else {
		GetClientRect(&rc);
		nRowSize = ((rc.bottom - rc.top) >> 1) - 30;
	}

	m_splitter.SetRowInfo(0, nRowSize, 0);

	m_splitter.RecalcLayout();

	return TRUE;
}

void CMainFrame::RemoveDragSource(HTREEITEM hti, LPCTSTR pszPath)
{
	if (m_htiDragTarget != hti)
		return;

	for (int i = 0; i < m_saDragSource.GetCount(); i++) {
		if (m_saDragSource[i] == pszPath) {
			m_saDragSource.RemoveAt(i);
			return;
		}
	}
}

void CMainFrame::ShowLoginDialog()
{
	CString sUserId, sPassword;

	BOOL bAutoConnect = COptions::GetOptionVal(OPTION_AUTOCONNECT);
	if (m_bInitialzed || !bAutoConnect) {
		CConnectDlg dlg;

		dlg.m_bAutoConnect  = bAutoConnect;
		dlg.m_bSavePassword = COptions::GetOptionVal(OPTION_SAVEPASSWORD);
		dlg.m_sUserId       = COptions::GetOption(OPTION_USERID);
		dlg.m_sPassword     = dlg.m_bSavePassword ? CCrypt::Decrypt(CCrypt::Decrypt(COptions::GetOption(OPTION_PASSWORD))) : "";

 		if (dlg.DoModal() != IDOK) {
 			PostMessage(WM_CLOSE);
 			return;
 		}

		m_sUserId   = dlg.m_sUserId;
		m_sPassword = dlg.m_sPassword;

		dlg.m_sPassword = CCrypt::Encrypt(CCrypt::Encrypt(dlg.m_sPassword));

		COptions::SetOption(OPTION_AUTOCONNECT,  dlg.m_bAutoConnect);
		COptions::SetOption(OPTION_SAVEPASSWORD, dlg.m_bSavePassword);
		COptions::SetOption(OPTION_USERID,       dlg.m_sUserId);
		COptions::SetOption(OPTION_PASSWORD,     dlg.m_bAutoConnect || dlg.m_bSavePassword ? dlg.m_sPassword : "");
	}
	else {
		m_sUserId   = COptions::GetOption(OPTION_USERID);
		m_sPassword = CCrypt::Decrypt(CCrypt::Decrypt(COptions::GetOption(OPTION_PASSWORD)));
	}

	m_bInitialzed = true;

	Connect();
}

void CMainFrame::Connect()
{
	if (m_mapHcl.GetCount() > 0) {
		if (AfxMessageBox("기존 접속을 끊으시겠습니까?", MB_YESNO | MB_ICONQUESTION) != IDYES)
			return;

		Disconnect();
	}

	char szUrl[MAX_PATH];
	char szPath[MAX_PATH];
	GetCurrentPath(szPath);
	
	strcat(szPath,"\\");
	strcat(szPath,INI_FILENAME);

//	AfxMessageBox(szPath);
	GetPrivateProfileString("CONNECT", "URL", "", szUrl, MAX_PATH, szPath);


#ifdef _OLD
	HCOMMLIB hcl = cl_init(szUrl, m_sUserId, m_sPassword, GetProxyHost(), GetProxyPort());
#else
	HCOMMLIB hcl = cl_init(szUrl, "", m_sUserId, m_sPassword, GetProxyHost(), GetProxyPort());
#endif
	if (!hcl) {
		AfxMessageBox(GetErrorMessage(GetLastError()), MB_ICONERROR);
		return;
	}

	m_mapHcl.SetAt(NULL, hcl);
	m_pRemoteView->PostMessage(WMU_SHOW_VOLUMELIST, NULL, (LPARAM)TRUE);


}

void CMainFrame::Disconnect()
{
	m_pRemoteView->ClearAllData();

	HTREEITEM hti;
	HCOMMLIB  hcl;
	for (POSITION pos = m_mapHcl.GetStartPosition(); pos != NULL; ) {
		m_mapHcl.GetNextAssoc(pos, (LPVOID&)hti, (LPVOID&)hcl);
		cl_free(hcl);
	}

	m_mapHcl.RemoveAll();
}

bool CMainFrame::ContNextOnError(LPCSTR pszErrMSg)
{
	CString sMsg;
	sMsg.Format("에러가 발생했습니다.\n%s\n\n계속 하시겠습니까?", pszErrMSg);

	return AfxMessageBox(sMsg, MB_YESNO | MB_ICONERROR) == IDYES;
}

int CMainFrame::ConfirmExists(LPCSTR pszName)
{
	CString sMsg;
	sMsg.Format("'%s' 파일이 이미 존재 합니다.\n 덮어 쓰시겠습니까?", pszName);

	return AfxMessageBox(sMsg, MB_YESNOCANCEL | MB_ICONQUESTION);
}

bool CMainFrame::MakeRemoteFolder(HTREEITEM hti, CString& sFolder)
{
	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[hti];
	ASSERT(hcl);

	if (!cl_make_directory(hcl, sFolder)) {
		AfxMessageBox(cl_get_error_message(hcl), MB_ICONERROR);
		return false;
	}

	opt_file_log(sFolder , "" , 'A' , 'D');

	return true;
}

bool CMainFrame::Move1RemoteObject(HTREEITEM hti, CString& sSrcPath, CString& sDstPath)
{
	BeginWaitCursor();

	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[hti];
	ASSERT(hcl);

	if (!cl_move(hcl, sSrcPath, sDstPath, TRUE)) {
		AfxMessageBox(cl_get_error_message(hcl), MB_ICONERROR);
		return false;
	}

	opt_file_log(sSrcPath , sDstPath , 'M' , '-');

	RemoveDragSource(hti, sSrcPath);

	UpdateVolumeInfo(hti);

	EndWaitCursor();

	return true;
}

bool CMainFrame::Delete1RemoteObject(HTREEITEM hti, CString& sPath)
{
	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[hti];
	ASSERT(hcl);

	if (!cl_delete(hcl, sPath)) {
		AfxMessageBox(cl_get_error_message(hcl), MB_ICONERROR);
		return false;
	}


	opt_file_log(sPath , "" , 'D' , 'D');

	RemoveDragSource(hti, sPath);

	UpdateVolumeInfo(hti);

	return true;
}

void CMainFrame::CopyRemoteObject(HTREEITEM hti, CStringArray& saSrcPath, CString& sDstPath, CStringArray& saSucceed)
{
	saSucceed.RemoveAll();

	BeginWaitCursor();

	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[hti];
	ASSERT(hcl);

	bool bBreak = false;
	for (int i = 0; i < saSrcPath.GetCount() && !bBreak; i++) {
		CString sTargetPath = sDstPath + saSrcPath[i].Mid(saSrcPath[i].ReverseFind('/'));
		if (saSrcPath[i] == sTargetPath) {
			PRTREEITEM_STRUCT prti = (PRTREEITEM_STRUCT)m_pRemoteView->m_tree.GetItemData(m_pRemoteView->m_tree.GetItem(hti, sDstPath));

			CString sName = sTargetPath.Mid(sTargetPath.ReverseFind('/') + 1);
			CString sExt  = "";

			int iPos = sName.ReverseFind('.');
			if (iPos >= 0) {
				sExt  = sName.Mid(iPos);
				sName = sName.Left(iPos);
			}

			bool bFound = true;
			for (int j = 1; bFound; j++) {
				sTargetPath.Format("%s(%d)%s", sName, j, sExt);

				bFound = false;
				for (int k = 0; k < prti->paObject.GetCount(); k++) {
					if (((PRLISTITEM_STRUCT)prti->paObject[k])->sName == sTargetPath) {
						bFound = true;
						break;
					}
				}
			}

			sTargetPath = sDstPath + "/" + sTargetPath;
			if (cl_copy(hcl, saSrcPath[i], sTargetPath, FALSE))
			{
				saSucceed.Add(saSrcPath[i]);
				opt_file_log(saSrcPath[i] , sTargetPath , 'C' , '-');
			}
				
			else
				bBreak = !ContNextOnError(cl_get_error_message(hcl));
		}
		else {
			PCLFILE_STRUCT pclfl = cl_get_file_list(hcl, sTargetPath, 0, NULL);
			if (pclfl) {
				cl_free_file_list(hcl, pclfl);

				int nAnswer = ConfirmExists(sTargetPath.Mid(sTargetPath.ReverseFind('/') + 1));
				if (nAnswer == IDCANCEL)
					bBreak = true;
				else if (nAnswer == IDNO)
					continue;
			}
			cl_free_file_list(hcl, pclfl);

			if (!bBreak) {
				if (cl_copy(hcl, saSrcPath[i], sTargetPath, TRUE))
				{
					saSucceed.Add(saSrcPath[i]);

					opt_file_log(saSrcPath[i] , sTargetPath , 'C' , '-');
				}
				else
					bBreak = !ContNextOnError(cl_get_error_message(hcl));
			}
		}
	}

	if (saSucceed.GetCount() > 0)
		UpdateVolumeInfo(hti);

	EndWaitCursor();
}

void CMainFrame::MoveRemoteObject(HTREEITEM hti, CStringArray& saSrcPath, CString& sDstPath, CStringArray& saSucceed)
{
	saSucceed.RemoveAll();

	BeginWaitCursor();

	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[hti];
	ASSERT(hcl);

	bool bBreak = false;
	CStringArray  strSrc;

	strSrc.Copy(saSrcPath);

	for (int i = 0; i < strSrc.GetCount()&& !bBreak; i++)
	{
		CString sTargetPath = sDstPath + strSrc[i].Mid(strSrc[i].ReverseFind('/'));
		if (strSrc[i] == sTargetPath)
			continue;
		else 
		{
			PCLFILE_STRUCT pclfl = cl_get_file_list(hcl, sTargetPath, 0, NULL);
			if (pclfl)
			{
				cl_free_file_list(hcl, pclfl);

				int nAnswer = ConfirmExists(sTargetPath.Mid(sTargetPath.ReverseFind('/') + 1));
				if (nAnswer == IDCANCEL)
					bBreak = true;
				else if (nAnswer == IDNO)
					continue;
			}
			cl_free_file_list(hcl, pclfl);

			if (!bBreak)
			{
				if (cl_move(hcl, strSrc[i], sTargetPath, TRUE))
				{

					opt_file_log(strSrc[i] , sTargetPath , 'M' , '-');

					saSucceed.Add(strSrc[i]);
					RemoveDragSource(hti, strSrc[i]);
				}
				else
					bBreak = !ContNextOnError(cl_get_error_message(hcl));
			}
		}
	}

	if (saSucceed.GetCount() > 0)
		UpdateVolumeInfo(hti);
	
	strSrc.RemoveAll();
	EndWaitCursor();
}

void CMainFrame::DeleteRemoteObject(HTREEITEM hti, CStringArray& saPath, char* bFolder , CStringArray& saSucceed)
{
	saSucceed.RemoveAll();

	BeginWaitCursor();

	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[hti];
	ASSERT(hcl);

	bool bBreak = false;
	for (int i = 0; i < saPath.GetCount() && !bBreak; i++) {
		if (cl_delete(hcl, saPath[i])) {
			saSucceed.Add(saPath[i]);
			RemoveDragSource(hti, saPath[i]);

			opt_file_log(saPath[i] , "" , 'D' , *bFolder);
			bFolder++;
		}
		else
			bBreak = !ContNextOnError(cl_get_error_message(hcl));
	}

	if (saSucceed.GetCount() > 0)
		UpdateVolumeInfo(hti);



	EndWaitCursor();
}

bool CMainFrame::Upload(bool bUseSelected)
{
	CString szTransGuid;
	CRemoteTreeCtrl* ptree = m_pRemoteView->GetTreeCtrl();

	HTREEITEM         htiVolume  = bUseSelected ? ptree->GetVolumeItem(ptree->GetSelectedItem()) :m_htiDragTarget;
	PRTREEITEM_STRUCT prtiVolume = (PRTREEITEM_STRUCT)ptree->GetItemData(htiVolume);
	HCOMMLIB          hcl        = (HCOMMLIB)m_mapHcl[htiVolume];

	BeginWaitCursor();

	if (bUseSelected) {
		m_saDragSource.RemoveAll();
		if (!m_pLocalView->GetSelectedObject(m_saDragSource))
			return false;

		m_sDragTarget = m_pRemoteView->m_tree.GetPath();
//		if (m_sDragTarget == "")
//			return false;
	}

	// 변수 초기화
	HANDLE hReadPipe  = NULL;
	HANDLE hWritePipe = NULL;
	CString	strTemp;

	PROCESS_INFORMATION pi;
	STARTUPINFO         si;
	ZeroMemory(&pi, sizeof(pi));
	ZeroMemory(&si, sizeof(si));

	// 파이프 생성
	SECURITY_ATTRIBUTES sa;

	sa.nLength              = sizeof(SECURITY_ATTRIBUTES); 
	sa.bInheritHandle       = TRUE; 
	sa.lpSecurityDescriptor = NULL; 

	if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
		EndWaitCursor();
		AfxMessageBox(GetErrorMessage(GetLastError()), MB_ICONERROR);
		return false;
	}

	bool bResult = false;

	LPSTR pszFileList = NULL;

	SetHandleInformation(hWritePipe, HANDLE_FLAG_INHERIT, 0);

	// 전송 프로그램 실행
	char szCmdLine[MAX_PATH];
#ifdef _DEBUG
	sprintf(szCmdLine, "SPCTran.exe %s", EXECUTE_PARAM);
#else
	sprintf(szCmdLine, "SPCTran.exe %s", EXECUTE_PARAM);
#endif

	si.cb = sizeof(si);
	si.hStdError  = hWritePipe;
	si.hStdOutput = hWritePipe;
	si.hStdInput  = hReadPipe;
	si.dwFlags   |= STARTF_USESTDHANDLES;

	if (!CreateProcess(NULL,
		szCmdLine, // command line
		NULL,      // process security attributes
		NULL,      // primary thread security attributes 
		TRUE,      // handles are inherited 
		0,         // creation flags 
		NULL,      // use parent's environment 
		NULL,      // use parent's current directory 
		&si,       // STARTUPINFO pointer 
		&pi))      // receives PROCESS_INFORMATION
		goto EXIT_FUNCTION;

	HCOMMLIB  t_hcl       = (HCOMMLIB)m_mapHcl[htiVolume];
	PCOMMLIB_STRUCT t_pcl = (PCOMMLIB_STRUCT)t_hcl;
	
	// 전송 정보 보내기...
	GetNewGUID(szTransGuid);

	TRANPARAM_STRUCT tp;
	tp.hwnd          = GetSafeHwnd();	
	tp.pParam        = htiVolume;
	tp.nAction       = TPA_UPLOAD;
	strcpy(tp.szHost,     prtiVolume->saAttr[1] + "/dav");
	memcpy(tp.szTransGuid, szTransGuid.GetString() , 32);

	strTemp.Format("XXX SP-Console : %s\n",tp.szHost);
	OutputDebugString(strTemp);

	strcpy(tp.szDstPath,  m_sDragTarget + "/");
	strcpy(tp.szUserId,   ptree->GetItemText(htiVolume));
	strcat(tp.szUserId,   "@");
	strcat(tp.szUserId,   m_sUserId);
	strcpy(tp.szPassword, m_sPassword);
	strcpy(tp.szProxyHost, GetProxyHost());
	strcpy(tp.szRCTSAddress , (t_pcl->sDomain2).c_str());

	tp.nProxyPort    = GetProxyPort();
	tp.nFreeBytes    = _atoi64(prtiVolume->saAttr[2]) - _atoi64(prtiVolume->saAttr[3]);

	tp.nFileListSize = 0;
	for (int i = 0; i < m_saDragSource.GetCount(); i++)
		tp.nFileListSize += m_saDragSource[i].GetLength() + 1;

	pszFileList = new char[tp.nFileListSize];
	if (!pszFileList)
		goto EXIT_FUNCTION;


	for (int i = 0, p = 0; i < m_saDragSource.GetCount(); i++) {
		strcpy(&pszFileList[p], m_saDragSource[i]);
		p += m_saDragSource[i].GetLength() + 1;
	}
	
	strncpy(tp.name_01 ,COptions::GetOption(OPTION_NAME_01) , 64) ;
	strncpy(tp.name_02 ,COptions::GetOption(OPTION_NAME_02) , 64) ;
	strncpy(tp.name_03 ,COptions::GetOption(OPTION_NAME_03) , 64) ;

	strncpy(tp.phone_01 ,COptions::GetOption(OPTION_PHONE_01) , 64) ;
	strncpy(tp.phone_02 ,COptions::GetOption(OPTION_PHONE_02) , 64) ;
	strncpy(tp.phone_03 ,COptions::GetOption(OPTION_PHONE_03) , 64) ;

	strncpy(tp.mail_01 ,COptions::GetOption(OPTION_MAIL_01) , 64) ;
	strncpy(tp.mail_02 ,COptions::GetOption(OPTION_MAIL_02) , 64) ;
	strncpy(tp.mail_03 ,COptions::GetOption(OPTION_MAIL_03) , 64) ;

    tp.nWritePolicy = COptions::GetOptionVal(OPTION_WRITEPOLICY);

	tp.bLogDir = COptions::GetOptionVal(OPTION_LOG_DIR);
	tp.bLogUpload = COptions::GetOptionVal(OPTION_LOG_UPLOAD);

	if (!WriteFile(hWritePipe, (LPVOID)&tp, sizeof(tp)))
		goto EXIT_FUNCTION;

	if (!WriteFile(hWritePipe, (LPVOID)pszFileList, tp.nFileListSize))
		goto EXIT_FUNCTION;

	bResult = true;

EXIT_FUNCTION:
	if (!bResult)
		AfxMessageBox(GetErrorMessage(GetLastError()), MB_ICONERROR);

	EndWaitCursor();

	if (pszFileList)
		delete []pszFileList;

	if (hReadPipe)
		CloseHandle(hReadPipe);

	if (hWritePipe)
		CloseHandle(hWritePipe);

	if (pi.hProcess)
		CloseHandle(pi.hProcess);

	if (pi.hThread)
		CloseHandle(pi.hThread);

	EndWaitCursor();

	return bResult;
}

bool CMainFrame::Download(bool bUseSelected)
{
	CString s;

	CRemoteTreeCtrl* ptree = m_pRemoteView->GetTreeCtrl();

	HTREEITEM         htiVolume  = bUseSelected ? ptree->GetVolumeItem(ptree->GetSelectedItem()) : m_htiDragTarget;
	PRTREEITEM_STRUCT prtiVolume = (PRTREEITEM_STRUCT)ptree->GetItemData(htiVolume);
	HCOMMLIB          hcl        = (HCOMMLIB)m_mapHcl[htiVolume];

	BeginWaitCursor();

	if (bUseSelected) {
		m_saDragSource.RemoveAll();
		if (!m_pRemoteView->GetSelectedObject(m_saDragSource))
			return false;

		m_sDragTarget = m_pLocalView->GetSelectedPath();
		if (m_sDragTarget == "")
			return false;
	}

	// 변수 초기화
	HANDLE hReadPipe  = NULL;
	HANDLE hWritePipe = NULL;

	PROCESS_INFORMATION pi;
	STARTUPINFO         si;
	ZeroMemory(&pi, sizeof(pi));
	ZeroMemory(&si, sizeof(si));

	// 파이프 생성
	SECURITY_ATTRIBUTES sa;

	sa.nLength              = sizeof(SECURITY_ATTRIBUTES); 
	sa.bInheritHandle       = TRUE; 
	sa.lpSecurityDescriptor = NULL; 

	if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
		EndWaitCursor();
		AfxMessageBox(GetErrorMessage(GetLastError()), MB_ICONERROR);
		return false;
	}

	bool bResult = false;

	LPSTR pszFileList = NULL;

	SetHandleInformation(hWritePipe, HANDLE_FLAG_INHERIT, 0);

	// 전송 프로그램 실행
	char szCmdLine[MAX_PATH];

	sprintf(szCmdLine, "SPCTran.exe %s", EXECUTE_PARAM);

	si.cb = sizeof(si);
	si.hStdError  = hWritePipe;
	si.hStdOutput = hWritePipe;
	si.hStdInput  = hReadPipe;
	si.dwFlags   |= STARTF_USESTDHANDLES;

	if (!CreateProcess(NULL,
		szCmdLine, // command line
		NULL,      // process security attributes
		NULL,      // primary thread security attributes 
		TRUE,      // handles are inherited 
		0,         // creation flags 
		NULL,      // use parent's environment 
		NULL,      // use parent's current directory 
		&si,       // STARTUPINFO pointer 
		&pi))      // receives PROCESS_INFORMATION
		goto EXIT_FUNCTION;

	// 전송 정보 보내기...
	TRANPARAM_STRUCT tp;
	tp.hwnd          = GetSafeHwnd();
	tp.pParam        = NULL;
	tp.nAction       = TPA_DOWNLOAD;
	strcpy(tp.szHost,     prtiVolume->saAttr[1] + "/dav");
	strcpy(tp.szDstPath,  m_sDragTarget + "\\");
	strcpy(tp.szUserId,   ptree->GetItemText(htiVolume));
	strcat(tp.szUserId,   "@");
	strcat(tp.szUserId,   m_sUserId);
	strcpy(tp.szPassword, m_sPassword);
	strcpy(tp.szProxyHost, GetProxyHost());
	tp.nProxyPort    = GetProxyPort();
	tp.nFreeBytes    = -1;

	tp.nFileListSize = 0;
	for (int i = 0; i < m_saDragSource.GetCount(); i++)
		tp.nFileListSize += m_saDragSource[i].GetLength() + 1;

	pszFileList = new char[tp.nFileListSize];
	if (!pszFileList)
		goto EXIT_FUNCTION;

	for (int i = 0, p = 0; i < m_saDragSource.GetCount(); i++) {
		strcpy(&pszFileList[p], m_saDragSource[i]);
		p += m_saDragSource[i].GetLength() + 1;
	}

	if (!WriteFile(hWritePipe, (LPVOID)&tp, sizeof(tp)))
		goto EXIT_FUNCTION;

	if (!WriteFile(hWritePipe, (LPVOID)pszFileList, tp.nFileListSize))
		goto EXIT_FUNCTION;

	bResult = true;

EXIT_FUNCTION:
	if (!bResult)
		AfxMessageBox(GetErrorMessage(GetLastError()), MB_ICONERROR);

	EndWaitCursor();

	if (pszFileList)
		delete []pszFileList;

	if (hReadPipe)
		CloseHandle(hReadPipe);

	if (hWritePipe)
		CloseHandle(hWritePipe);

	if (pi.hProcess)
		CloseHandle(pi.hProcess);

	if (pi.hThread)
		CloseHandle(pi.hThread);

	EndWaitCursor();

	return bResult;
}

void CMainFrame::SaveUrl()
{
	CRemoteTreeCtrl *ptree = m_pRemoteView->GetTreeCtrl();
	CRemoteListCtrl *plist = m_pRemoteView->GetListCtrl();

	HTREEITEM htiSelected = ptree->GetSelectedItem();
	HTREEITEM htiVolume   = ptree->GetVolumeItem(htiSelected);

	HCOMMLIB hcl = (HCOMMLIB)m_mapHcl[htiVolume];
	ASSERT(hcl);

	CFileDialog dlg(FALSE, ".txt", ptree->GetItemText(htiVolume) + ".txt", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "텍스트 파일 (*.txt)|*.txt|");
	dlg.m_pOFN->lpstrTitle = "URL 저장 파일명 선택";

	if (dlg.DoModal() != IDOK)
		return;

	CString sFileName = dlg.GetPathName();

	CStdioFile     file;
	CFileException fe;
	if (!file.Open(sFileName, CFile::modeCreate | CFile::modeWrite, &fe)) {
		char szError[MAX_PATH];
		fe.GetErrorMessage(szError, sizeof(szError));
		CString sError;
		sError.Format("파일을 만들 수 없습니다.\n%s", szError);
		AfxMessageBox(sError, MB_ICONERROR);
		return;
	}

	BOOL bSubSearch = COptions::GetOptionVal(OPTION_SEARCHSUBURL);

	CString sSTag, sETag;
	switch (COptions::GetOptionVal(OPTION_URLTAGTYPE)) {
	case 1:
		sSTag = "<img src=\"";
		sETag = "\">";
		break;
	case 2:
		sSTag = "<a href=\"";
		sETag = "\">";
		break;
	case 3:
		sSTag = COptions::GetOption(OPTION_URLSTAG);
		sETag = COptions::GetOption(OPTION_URLETAG);
		break;
	}

	CString sBasePath = ptree->GetPath(htiSelected) + "/";
	CString sURL;
#ifdef _DEBUG
	sURL = "http://" + ((PRTREEITEM_STRUCT)ptree->GetItemData(htiVolume))->saAttr[1];
#else
	sURL = "http://" + ptree->GetItemText(htiVolume) + ".ktsh.co.kr";
#endif

	BeginWaitCursor();

	POSITION pos = plist->GetFirstSelectedItemPosition();
	while (pos) {
		int iItem = plist->GetNextSelectedItem(pos);

		PRLISTITEM_STRUCT prli = (PRLISTITEM_STRUCT)plist->GetItemData(iItem);
		CString sURI = sURL + sBasePath + prli->sName;

		if (prli->bFolder) {
			if (!bSubSearch)
				continue;

			UINT nFileCount;
			PCLFILE_STRUCT pclfl = cl_get_file_list(hcl, sBasePath + prli->sName, 2, &nFileCount);
			if (!pclfl)
				continue;

			for (UINT i = 1; i < nFileCount; i++) {
				if (pclfl[i].attr & CLFILEATTR_FOLDER)
					continue;

				SaveFileUrl(sURL + pclfl[i].path, file, sSTag, sETag);
			}
			cl_free_file_list(hcl, pclfl);
		} // is folder?
		else {
			SaveFileUrl(sURI, file, sSTag, sETag);
		} // is not folder?
	}

	file.Close();

	EndWaitCursor();

	AfxMessageBox("저장 했습니다.");
}

void CMainFrame::SaveFileUrl(CString sURI, CStdioFile& file, CString sStag, CString sEtag)
{
	CString sText;

	sText  = sStag;
	sText += sURI;
	sText += sEtag + "\n";

	file.WriteString(sText);
}

void CMainFrame::GetFolderInfo(HTREEITEM hti,LPRFOLDERINFO_STRUCT pfolderinfo)
{
	PCLFILE_STRUCT pclf;
	UINT nFileCount;

	CRemoteTreeCtrl* ptree = m_pRemoteView->GetTreeCtrl();

	CString   sName;
	sName = ptree->GetPath(hti);

	HTREEITEM htiVolume = ptree->GetVolumeItem(hti);
	HCOMMLIB  hcl       = (HCOMMLIB)m_mapHcl[htiVolume];
	CString   sId       = ptree->GetItemText(htiVolume);
	
	pclf = cl_get_file_list(hcl,sName,2,&nFileCount);

	for (UINT i = 1; i < nFileCount; i++)
	{
		if (pclf[i].attr & CLFILEATTR_FOLDER)
			pfolderinfo->nCountFolder++;
		else
			pfolderinfo->nCountFile++;
		pfolderinfo->nSize += pclf[i].size;
	}
	
	pfolderinfo->strName = sName;
	cl_free_file_list(hcl,pclf);
}

void CMainFrame::UpdateVolumeInfo(HTREEITEM hti)
{
	CRemoteTreeCtrl* ptree = m_pRemoteView->GetTreeCtrl();

	if (hti == ptree->GetRootItem())
		return;

	BeginWaitCursor();

	HTREEITEM htiVolume = ptree->GetVolumeItem(hti);
	HCOMMLIB  hcl       = (HCOMMLIB)m_mapHcl[htiVolume];
	CString   sId       = ptree->GetItemText(htiVolume);

	PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;

	__int64 nTotalBytes, nUsedBytes;
	if (cl_get_service_info(hcl, sId, &nTotalBytes, &nUsedBytes)) {
		if (nUsedBytes > nTotalBytes)
			nUsedBytes = nTotalBytes;

		CString sTotalBytes, sUsedBytes;
		sTotalBytes.Format("%I64d", nTotalBytes);
		sUsedBytes.Format("%I64d",  nUsedBytes);

		PRTREEITEM_STRUCT prti = (PRTREEITEM_STRUCT)ptree->GetItemData(htiVolume);
		prti->saAttr[2] = sTotalBytes;
		prti->saAttr[3] = sUsedBytes;

		prti = (PRTREEITEM_STRUCT)ptree->GetItemData(ptree->GetRootItem());
		for (int i = 0; i < prti->paObject.GetCount(); i++) {
			PRLISTITEM_STRUCT prli = (PRLISTITEM_STRUCT)prti->paObject[i];
			if (prli->sName == sId) {
				prli->nSize = nTotalBytes;
				prli->saAttr[1].Format("%I64d", nTotalBytes);
				break;
			}
		}
	}

	EndWaitCursor();
}

void CMainFrame::BeginWaitMessage(CCmdTarget *pct)
{
	BeginWaitCursor();
//	m_pwmdlg->ShowWindow(SW_SHOW);
}

void CMainFrame::EndWaitMessage(CCmdTarget *pct)
{
//	m_pwmdlg->ShowWindow(SW_HIDE);
	EndWaitCursor();
}

void CMainFrame::SetFocus(CWnd* pwnd)
{
	if (pwnd == m_pRemoteView || pwnd == &m_pRemoteView->m_capTitle || pwnd == &m_pRemoteView->m_cboAddr
		|| pwnd == &m_pRemoteView->m_tree || pwnd == &m_pRemoteView->m_list) {
		m_fl = FL_REMOTE;
		if (pwnd == &m_pRemoteView->m_tree || pwnd == &m_pRemoteView->m_list)
			m_pwndRemote = pwnd;
	}
	else {
		m_fl = FL_LOCAL;
		if (pwnd == &m_pLocalView->m_tree || pwnd == &m_pLocalView->m_list)
			m_pwndLocal = pwnd;
	}

	m_pRemoteView->RedrawFocus();
	m_pLocalView->RedrawFocus();

	PostMessage(WMU_UPDATE_CONTROL_STATUS);
}

CString CMainFrame::GetProxyHost()
{
	CString sHost = "";

	if (!COptions::GetOptionVal(OPTION_USEIEPROXY))
		sHost = COptions::GetOption(OPTION_PROXYHOST);
	else {
		CRegUtil ru;
		if (ru.OpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")) {
			if (ru.GetNumValue("ProxyEnable") == 1) {
				sHost = ru.GetStrValue("ProxyServer");
				int iPos = sHost.Find("://");
				if (iPos >= 0)
					sHost = sHost.Mid(iPos + 3);
				iPos = sHost.Find(':');
				if (iPos >= 0)
					sHost = sHost.Left(iPos);
			}
			else
				sHost = "";

			ru.CloseKey();
		}
	}


	return sHost;
}

int CMainFrame::GetProxyPort()
{
	int nPort = 0;

	if (!COptions::GetOptionVal(OPTION_USEIEPROXY))
		nPort = atoi(COptions::GetOption(OPTION_PROXYPORT));
	else {
		CRegUtil ru;
		if (ru.OpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")) {
			if (ru.GetNumValue("ProxyEnable") == 1) {
				CString sHost = ru.GetStrValue("ProxyServer");
				int iPos = sHost.Find("://");
				if (iPos >= 0)
					sHost = sHost.Mid(iPos + 3);
				iPos = sHost.Find(':');
				if (iPos >= 0)
					nPort = atoi(sHost.Mid(iPos + 1));
				else
					nPort = 80;
			}

			ru.CloseKey();
		}
	}


	return nPort;
}

void CMainFrame::opt_file_log(CString s_file , CString t_file , char action , char file_flag)
{
	CRemoteTreeCtrl* ptree = m_pRemoteView->GetTreeCtrl();

	//HTREEITEM         htiVolume  = bUseSelected ? ptree->GetVolumeItem(ptree->GetSelectedItem()) :m_htiDragTarget;
	HTREEITEM         htiVolume  = ptree->GetVolumeItem(ptree->GetSelectedItem());
	PRTREEITEM_STRUCT prtiVolume = (PRTREEITEM_STRUCT)ptree->GetItemData(htiVolume);
	HCOMMLIB          hcl        = (HCOMMLIB)m_mapHcl[htiVolume];

	m_webutil.kp_init(ptree->GetItemText(htiVolume) ,m_sUserId ,m_sPassword );
	
	PTF_LOG_STURCT ptflog = new TF_LOG_STURCT;
	strcpy(ptflog->sp_user_id , m_sUserId.GetString()  );
	strcpy(ptflog->vol_name , ptree->GetItemText(htiVolume).GetString());
	strcpy(ptflog->s_file , s_file.GetString());
	strcpy(ptflog->t_file , t_file.GetString());
	ptflog->action =  action;
	ptflog->file_flag = file_flag;
	
	m_webutil.kp_file_opt_log(ptflog);

	delete ptflog;

}

BOOL CMainFrame::OnCopyData(CWnd* pWnd , COPYDATASTRUCT* pCodyDataStruct)
{
	

	switch(pCodyDataStruct->dwData)
	{
	case 1000:
		PTADDINFO pTransAddInfo;
		
		pTransAddInfo = (PTADDINFO)pCodyDataStruct->lpData;
		if (pTransAddInfo!=NULL)
		{
			this->opt_file_log(pTransAddInfo->szFileName , "" ,'D' , pTransAddInfo->bFolder);
		}

	break;

	case 2000:

		char file_name[2048];
		CString mail1 = COptions::GetOption(OPTION_MAIL_01);
		CString mail2 = COptions::GetOption(OPTION_MAIL_02);
		CString mail3 = COptions::GetOption(OPTION_MAIL_03);
		
		strncpy(file_name , (char*)pCodyDataStruct->lpData , 2048-1);

		m_webutil.kp_send_mail(mail1 , mail2 , mail3 , file_name);
		
	break;
	}

	return CWnd::OnCopyData(pWnd , pCodyDataStruct);

}


BOOL CMainFrame::GetNewGUID(CString& strGUID)
{
	GUID  gUID;
	char szGUID[50];
	WCHAR wszCLSID[50];
	BOOL bResult = FALSE;
	HRESULT hResult =  CoCreateGuid(&gUID);
	if( S_OK == hResult )
	{
		memset(szGUID, 0x00, 50);
		int nLen = StringFromGUID2(gUID, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0])); 
		int result_idx=0;
		for( int nIndex = 0 ; nIndex < nLen ; nIndex++ )
		{
			if ((char)wszCLSID[nIndex]!='-' && (char)wszCLSID[nIndex]!='{' && (char)wszCLSID[nIndex]!='}'){
				szGUID[result_idx] = (char)wszCLSID[nIndex];
			}
			else{
				result_idx--;
			}
			result_idx++;
		}

		strGUID.Format("%s", szGUID);
	}

	return bResult;
}

