//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "emuledlg.h"
#include "SharedFilesWnd.h"
#include "PPgDirectories.h"
#include "otherfunctions.h"
#include "InputBox.h"
#include "SharedFileList.h"
#include "Preferences.h"
#include "HelpIDs.h"
#include "UserMsgs.h"
// NEO: MTD - [MultiTempDirectories] -- Xanatos -->
#include "DownloadQueue.h"
#include "PartFile.h"
#include "Neo\Functions.h"
// NEO: MTD END <-- Xanatos --

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


IMPLEMENT_DYNAMIC(CPPgDirectories, CPropertyPage)

BEGIN_MESSAGE_MAP(CPPgDirectories, CPropertyPage)
	ON_BN_CLICKED(IDC_SELTEMPDIR, OnBnClickedSeltempdir)
	ON_BN_CLICKED(IDC_SELINCDIR,OnBnClickedSelincdir)
	ON_EN_CHANGE(IDC_INCFILES,	OnSettingsChange)
	ON_EN_CHANGE(IDC_TEMPFILES, OnSettingsChange)
	ON_BN_CLICKED(IDC_UNCADD,	OnBnClickedAddUNC)
	ON_BN_CLICKED(IDC_UNCREM,	OnBnClickedRemUNC)
	// NEO: MTD - [MultiTempDirectories] -- Xanatos -->
	ON_BN_CLICKED(IDC_TEMPADD, OnBnClickedTempadd)
	ON_BN_CLICKED(IDC_TEMPREM, OnBnClickedTemprem) 
	// NEO: MTD END <-- Xanatos --
	ON_WM_HELPINFO()
END_MESSAGE_MAP()

CPPgDirectories::CPPgDirectories()
	: CPropertyPage(CPPgDirectories::IDD)
{
	
}

CPPgDirectories::~CPPgDirectories()
{
}

void CPPgDirectories::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SHARESELECTOR, m_ShareSelector);
	DDX_Control(pDX, IDC_UNCLIST, m_ctlUncPaths);
}

BOOL CPPgDirectories::OnInitDialog()
{
	CWaitCursor curWait; // initialization of that dialog may take a while..
	CPropertyPage::OnInitDialog();
	InitWindowStyles(this);
	//m_ShareSelector.Init(); // NEO: SSD - [ShareSubDirectories] <-- Xanatos --

	((CEdit*)GetDlgItem(IDC_INCFILES))->SetLimitText(509);
	((CEdit*)GetDlgItem(IDC_TEMPFILES))->SetLimitText(509);
	m_ctlUncPaths.InsertColumn(0, GetResString(IDS_UNCFOLDERS), LVCFMT_LEFT, 280, -1); 
	m_ctlUncPaths.SetExtendedStyle(LVS_EX_FULLROWSELECT);
	// NEO: MTD - [MultiTempDirectories] -- Xanatos -->
	m_tempfolders=(CListCtrl*)GetDlgItem(IDC_TEMPLIST);
	m_tempfolders->InsertColumn(0, GetResString(IDS_X_PW_TEMPLIST), LVCFMT_LEFT, 280, -1);
	// NEO: MTD END <-- Xanatos --

	LoadSettings();
	Localize();

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CPPgDirectories::LoadSettings(void)
{
	GetDlgItem(IDC_INCFILES)->SetWindowText(thePrefs.incomingdir);
	GetDlgItem(IDC_TEMPFILES)->SetWindowText(thePrefs.tempdir);
	m_ShareSelector.SetSharedDirectories(&thePrefs.shareddir_list, &thePrefs.sharedsubdir_list); // NEO: SSD - [ShareSubDirectories] <-- Xanatos --
	FillUncList();
	FillTempList(); // NEO: MTD - [MultiTempDirectories] <-- Xanatos --
}

void CPPgDirectories::OnBnClickedSelincdir()
{
	TCHAR buffer[MAX_PATH] = {0};
	GetDlgItemText(IDC_INCFILES, buffer, ARRSIZE(buffer));
	if(SelectDir(GetSafeHwnd(),buffer,GetResString(IDS_SELECT_INCOMINGDIR)))
		GetDlgItem(IDC_INCFILES)->SetWindowText(buffer);
}

void CPPgDirectories::OnBnClickedSeltempdir()
{
	TCHAR buffer[MAX_PATH] = {0};
	GetDlgItemText(IDC_TEMPFILES, buffer, ARRSIZE(buffer));
	if(SelectDir(GetSafeHwnd(),buffer,GetResString(IDS_SELECT_TEMPDIR)))
		GetDlgItem(IDC_TEMPFILES)->SetWindowText(buffer);
}

// NEO: SSD - [ShareSubDirectories] -- Xanatos -->
static bool FindStringNoCase(const CStringList &list, CString string) {
	if (string.Right(1) != '\\')
		string += '\\';
	for (POSITION pos = list.GetHeadPosition(); pos != NULL; )
	{
		CString str = list.GetNext(pos);
		if (str.Right(1) != '\\')
			str += '\\';
		if (str.CompareNoCase(string) == 0)
			return true;
	}
	return false;
}
// NEO: SSD END <-- Xanatos --

BOOL CPPgDirectories::OnApply()
{
	CString testtempdirchanged=thePrefs.GetTempDir();
	CString testincdirchanged=thePrefs.GetIncomingDir();

	CString strIncomingDir;
	GetDlgItemText(IDC_INCFILES, strIncomingDir);
	if (strIncomingDir.IsEmpty()){
		strIncomingDir = thePrefs.GetAppDir() + _T("incoming");
		SetDlgItemText(IDC_INCFILES, strIncomingDir);
	}
	if (thePrefs.IsInstallationDirectory(strIncomingDir)){
		AfxMessageBox(GetResString(IDS_WRN_INCFILE_RESERVED));
		return FALSE;
	}
	
	CString strTempDir;
	GetDlgItemText(IDC_TEMPFILES, strTempDir);
	if (strTempDir.IsEmpty()){
		strTempDir = thePrefs.GetAppDir() + _T("temp");
		SetDlgItemText(IDC_TEMPFILES, strTempDir);
	}
	if (thePrefs.IsInstallationDirectory(strTempDir)){
		AfxMessageBox(GetResString(IDS_WRN_TEMPFILES_RESERVED));
		return FALSE;
	}

	if (CompareDirectories(strIncomingDir, strTempDir)==0){
		AfxMessageBox(GetResString(IDS_WRN_INCTEMP_SAME));
		return FALSE;
	}

	_sntprintf(thePrefs.incomingdir, ARRSIZE(thePrefs.incomingdir), _T("%s"), strIncomingDir);
	MakeFoldername(thePrefs.incomingdir);
	if(wcslen(thePrefs.GetCategory(0)->incomingpath) > 0) // NEO: MAC - [MorphA4AFCategories] <-- Xanatos --
		_stprintf(thePrefs.GetCategory(0)->incomingpath,_T("%s"),thePrefs.incomingdir);

	_sntprintf(thePrefs.tempdir, ARRSIZE(thePrefs.tempdir), _T("%s"), strTempDir);
	MakeFoldername(thePrefs.tempdir);

	// NEO: SSD - [ShareSubDirectories] -- Xanatos -->
	m_ShareSelector.GetSharedDirectories(&thePrefs.shareddir_list, &thePrefs.sharedsubdir_list);
	for (int i = 0; i < m_ctlUncPaths.GetItemCount(); i++){
		CString unc = m_ctlUncPaths.GetItemText(i, 0);
		if (!PathFileExists(unc))	// only add directories which still exist
			continue;
		if (FindStringNoCase(thePrefs.shareddir_list, unc))	// don't double-share UNC
			continue;
		// TODO: Could be indirectly shared via subdir. We should probably check for that too.
		thePrefs.shareddir_list.AddTail(unc);
	}
	FillUncList();
	// NEO: SSD END <-- Xanatos --
	/*thePrefs.shareddir_list.RemoveAll();

	m_ShareSelector.GetSharedDirectories(&thePrefs.shareddir_list);
	for (int i = 0; i < m_ctlUncPaths.GetItemCount(); i++)
		thePrefs.shareddir_list.AddTail(m_ctlUncPaths.GetItemText(i, 0));

	// check shared directories for reserved folder names
	POSITION pos = thePrefs.shareddir_list.GetHeadPosition();
	while (pos){
		POSITION posLast = pos;
		const CString& rstrDir = thePrefs.shareddir_list.GetNext(pos);
		if (thePrefs.IsInstallationDirectory(rstrDir))
			thePrefs.shareddir_list.RemoveAt(posLast);
	}*/

	// NEO: MTD - [MultiTempDirectories] -- Xanatos -->
	thePrefs.tempdir_list.RemoveAll();

	for (int i=0;i<m_tempfolders->GetItemCount();++i){
		CString tdir;
		tdir=m_tempfolders->GetItemText(i,0);
		if (!thePrefs.IsInstallationDirectory(tdir) &&
			CompareDirectories(tdir, strIncomingDir) &&
			CompareDirectories(tdir, strTempDir))
		{
			MakeFoldername(tdir.GetBuffer());
			tdir.ReleaseBuffer();
			thePrefs.tempdir_list.AddTail(tdir);
		}
	}

	POSITION pos;
	POSITION pos2;
	CStringList folderlist;
	CString part_folder;
	CString folder;
	CPartFile* cur_file;

	folderlist.RemoveAll();
	for(pos = theApp.downloadqueue->filelist.GetHeadPosition(); pos != NULL;theApp.downloadqueue->filelist.GetNext(pos)) { 
		cur_file = theApp.downloadqueue->filelist.GetAt(pos);
		if (cur_file) {
			part_folder = cur_file->GetPath();
			if (!part_folder.IsEmpty()) {
				for (pos2 = folderlist.GetHeadPosition();pos2 != 0 && CompareDirectories(folderlist.GetAt(pos2), part_folder);folderlist.GetNext(pos2));
				if (!pos2) folderlist.AddTail(part_folder);
			}
		}
	}

	CString temp_folder;
	CString tempdir_warn;
	bool fold_missing = false;

	tempdir_warn = GetResString(IDS_X_TEMPLISTWARN) + _T("\n\n");
	for(pos = folderlist.GetHeadPosition(); pos != NULL;folderlist.GetNext(pos)) { 
		folder = folderlist.GetAt(pos);
		if (CompareDirectories(thePrefs.GetTempDir(), folder))
		{
			for (pos2 = thePrefs.tempdir_list.GetHeadPosition();pos2 != 0 && CompareDirectories(thePrefs.tempdir_list.GetAt(pos2), folder);thePrefs.tempdir_list.GetNext(pos2));
			if (!pos2)
			{
				fold_missing = true;
				tempdir_warn += folder + _T("\n");
			}
		}
	}

	if (fold_missing)
		AfxMessageBox(tempdir_warn);

#ifdef A4AF_CATS // NEO: MAC - [MorphA4AFCategories] -- Xanatos -->
	for (int cat=0; cat<thePrefs.GetCatCount();cat++){
		folder=CString(thePrefs.GetCatPath(cat));
		for (pos2 = thePrefs.tempdir_list.GetHeadPosition();pos2 != 0 && CompareDirectories(thePrefs.tempdir_list.GetAt(pos2), folder);thePrefs.tempdir_list.GetNext(pos2));
		if (!pos2)
			_sntprintf(thePrefs.GetCategory(cat)->temppath, ARRSIZE(thePrefs.GetCategory(cat)->temppath), _T(""));
	}
#endif // A4AF_CATS // NEO: MAC END <-- Xanatos --
	// NEO: MTD END <-- Xanatos --

	if (testtempdirchanged.CompareNoCase(thePrefs.GetTempDir())!=0 || m_templist_dirty) // NEO: MTD - [MultiTempDirectories] <-- Xanatos --
		// NEO: MOD -- Xanatos -->
		if (AfxMessageBox(GetResString(IDS_SETTINGCHANGED_RESTART),MB_YESNO | MB_ICONEXCLAMATION,0)==IDYES)
			theApp.emuledlg->RestartMuleApp();
		// NEO: MOD END <-- Xanatos --
	
	// on changing incoming dir, update incoming dirs of category of the same path
	if (testincdirchanged.CompareNoCase(thePrefs.GetIncomingDir())!=0) {
		CString oldpath;
		bool dontaskagain=false;
		for (int cat=1; cat<=thePrefs.GetCatCount()-1;cat++){
			oldpath=CString(thePrefs.GetCatPath(cat));
			if (oldpath.Left(testincdirchanged.GetLength()).CompareNoCase(testincdirchanged)==0) {

				if (!dontaskagain) {
					dontaskagain=true;
					if (AfxMessageBox(GetResString(IDS_UPDATECATINCOMINGDIRS),MB_YESNO)==IDNO)
						break;
				}
				_sntprintf(thePrefs.GetCategory(cat)->incomingpath, ARRSIZE(thePrefs.GetCategory(cat)->incomingpath), _T("")); // NEO: MAC - [MorphA4AFCategories] <-- Xanatos --
				//_sntprintf(thePrefs.GetCategory(cat)->incomingpath, ARRSIZE(thePrefs.GetCategory(cat)->incomingpath), _T("%s%s"), thePrefs.GetIncomingDir(), oldpath.Mid(testincdirchanged.GetLength()));
			}
		}
	}

	theApp.emuledlg->sharedfileswnd->Reload();
	
	SetModified(0);
	m_templist_dirty = false; // NEO: MTD - [MultiTempDirectories] <-- Xanatos --
	return CPropertyPage::OnApply();
}

BOOL CPPgDirectories::OnCommand(WPARAM wParam, LPARAM lParam)
{
	if (wParam == UM_ITEMSTATECHANGED)
		SetModified();	
	else if (wParam == ID_HELP)
	{
		OnHelp();
		return TRUE;
	}
	return CPropertyPage::OnCommand(wParam, lParam);
}

void CPPgDirectories::Localize(void)
{
	if(m_hWnd)
	{
		SetWindowText(GetResString(IDS_PW_DIR));

		GetDlgItem(IDC_INCOMING_FRM)->SetWindowText(GetResString(IDS_PW_INCOMING));
		GetDlgItem(IDC_TEMP_FRM)->SetWindowText(GetResString(IDS_PW_TEMP));
		GetDlgItem(IDC_SELINCDIR)->SetWindowText(GetResString(IDS_PW_BROWSE));
		GetDlgItem(IDC_SELTEMPDIR)->SetWindowText(GetResString(IDS_PW_BROWSE));
		GetDlgItem(IDC_SHARED_FRM)->SetWindowText(GetResString(IDS_PW_SHARED));
	}
}

void CPPgDirectories::FillUncList(void)
{
	m_ctlUncPaths.DeleteAllItems();

	// NEO: SSD - [ShareSubDirectories] -- Xanatos -- // X?: Why should this be removed???
	for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != 0; )
	{
		CString folder = thePrefs.shareddir_list.GetNext(pos);
		if (PathIsUNC(folder))
			m_ctlUncPaths.InsertItem(0, folder);
	}
}

// NEO: MTD - [MultiTempDirectories] -- Xanatos -->
void CPPgDirectories::FillTempList(void) {
	m_tempfolders->DeleteAllItems();

	for (POSITION pos = thePrefs.tempdir_list.GetHeadPosition();pos != 0;thePrefs.tempdir_list.GetNext(pos)){
		CString folder=thePrefs.tempdir_list.GetAt(pos);
		m_tempfolders->InsertItem(0,folder);
	}

	m_templist_dirty = false;
}
// NEO: MTD END <-- Xanatos --

void CPPgDirectories::OnBnClickedAddUNC()
{
	InputBox inputbox;
	inputbox.SetLabels(GetResString(IDS_UNCFOLDERS), GetResString(IDS_UNCFOLDERS), _T("\\\\Server\\Share"));
	if (inputbox.DoModal() != IDOK)
		return;
	CString unc=inputbox.GetInput();

	// basic unc-check 
	if (!PathIsUNC(unc)){
		AfxMessageBox(GetResString(IDS_ERR_BADUNC), MB_ICONERROR);
		return;
	}

	if (unc.Right(1) == _T("\\"))
		unc.Delete(unc.GetLength()-1, 1);

	for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition();pos != 0;){
		if (unc.CompareNoCase(thePrefs.shareddir_list.GetNext(pos))==0)
			return;
	}
	for (int posi = 0; posi < m_ctlUncPaths.GetItemCount(); posi++){
		if (unc.CompareNoCase(m_ctlUncPaths.GetItemText(posi, 0)) == 0)
			return;
	}

	m_ctlUncPaths.InsertItem(m_ctlUncPaths.GetItemCount(), unc);
	SetModified();
}

void CPPgDirectories::OnBnClickedRemUNC()
{
	int index = m_ctlUncPaths.GetSelectionMark();
	if (index == -1 || m_ctlUncPaths.GetSelectedCount() == 0)
		return;
	m_ctlUncPaths.DeleteItem(index);
	SetModified();
}

void CPPgDirectories::OnHelp()
{
	theApp.ShowHelp(eMule_FAQ_Preferences_Directories);
}

BOOL CPPgDirectories::OnHelpInfo(HELPINFO* /*pHelpInfo*/)
{
	OnHelp();
	return TRUE;
}

// NEO: MTD - [MultiTempDirectories] -- Xanatos -->
void CPPgDirectories::OnBnClickedTempadd()
{
	TCHAR buffer[MAX_PATH] = {0};
	GetDlgItemText(IDC_TEMPFILES, buffer, ARRSIZE(buffer));
	if(SelectDir(GetSafeHwnd(),buffer,GetResString(IDS_SELECT_TEMPDIR)))
	{
		CString tdir(buffer);
		CString test;
		for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition();pos != 0;thePrefs.shareddir_list.GetNext(pos)){
			test=thePrefs.shareddir_list.GetAt(pos);
			if (CompareDirectories(tdir, test)==0) return;
		}
		int posi;
		for (posi = 0; posi<m_ctlUncPaths.GetItemCount();++posi){
			test=m_ctlUncPaths.GetItemText(posi,0);
			if (CompareDirectories(tdir, test)==0) return;
		}
		for (posi = 0; posi<m_tempfolders->GetItemCount();++posi){
			test=m_tempfolders->GetItemText(posi,0);
			if (CompareDirectories(tdir, test)==0) return;
		}
		if (thePrefs.IsInstallationDirectory(tdir)) return;

		m_tempfolders->InsertItem(m_tempfolders->GetItemCount(),tdir);
		m_templist_dirty = true;
		SetModified();
	}
}

void CPPgDirectories::OnBnClickedTemprem()
{
	int index=m_tempfolders->GetSelectionMark();
	if (index==-1 || m_tempfolders->GetSelectedCount()==0 ) return;

	m_tempfolders->DeleteItem(index);
	m_templist_dirty = true;
	SetModified();
}
// NEO: MTD END <-- Xanatos --
