//this file is part of eMule
//Copyright (C)2002-2005 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 "SearchDlg.h"
#include "TransferWnd.h"
#include "OtherFunctions.h"
#include "ClientList.h"
#include "UploadQueue.h"
#include "DownloadQueue.h"
#include "emuledlg.h"
#include "MenuCmds.h"
#include "PartFile.h"
#include "CatDialog.h"
#include "InputBox.h"
#include "UserMsgs.h"
#include "SharedFileList.h"
#include "DropDownButton.h"
//#include "ToolTipCtrlX.h" //==> NextEMF New Tooltips [Rayita]
#include "SharedFilesWnd.h"
#include "UpDownClient.h"

#include "Log.h"
#include "MuleListCtrl.h" //==> NextEMF New Tooltips [Rayita]
#include "NextEMF\RollUpCtrl\AddBuddy.h" //==> dlarge RollUps

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

//==> dlarge RollUps
#define TRANS_ROLLUP				120
#define TRANS_DOWNLOADLIST			121
#define TRANS_DOWNLOADCLIENTLIST	        122

#define TRANS_UPLOADLIST			123
#define TRANS_QUEUELIST				124
#define TRANS_CLIENTLIST			125

#define TRANS_TABWINDOW				126
#define TRANS_DOWNLOADTABS			127

#define TRANS_DUMMY				128
#define TRANS_DUMMY2				129
//<== dlarge RollUps


//==> dlarge RollUps
class CDummyForTabs : public CWnd
{
public:
	CDummyForTabs(){ m_pChild = NULL; }

	void SetChild(CWnd* pChild){ m_pChild = pChild;	}

	CWnd* GetChild(){ return m_pChild; }

	virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
	{
		
		NMHDR* pNMHDR = (NMHDR*)lParam;
		switch(pNMHDR->code)
		{
		case LVN_ITEMACTIVATE:
		case LVN_COLUMNCLICK:
		case NM_CLICK:
		case NM_DBLCLK:
			break;
		default:
			*pResult = GetParent()->GetParent()->SendMessage(WM_NOTIFY, wParam, lParam);
			return TRUE;
		}
		
		return CWnd::OnNotify(wParam, lParam, pResult);
	}	
	afx_msg void OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
	{
		
		if(m_pChild)
		{
			CRect r;
			GetClientRect(&r);
			r -= CSize(2,2);
			m_pChild->SetWindowPos(NULL, 0,0, r.Width(), r.Height(), SWP_NOMOVE|SWP_NOZORDER);
		}		
	}
	DECLARE_DYNCREATE(CDummyForTabs)
	DECLARE_MESSAGE_MAP()

private:
	CWnd* m_pChild;
};
//<== dlarge RollUps

// CTransferWnd dialog

//==> dlarge RollUps
IMPLEMENT_DYNAMIC(CDummyForTabs, CWnd)

BEGIN_MESSAGE_MAP(CDummyForTabs, CWnd)
	ON_WM_SIZE()
END_MESSAGE_MAP()
//<== dlarge RollUps

IMPLEMENT_DYNAMIC(CTransferWnd, CDialog)

BEGIN_MESSAGE_MAP(CTransferWnd, CResizableDialog)
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_SYSCOLORCHANGE()
	ON_NOTIFY(LVN_KEYDOWN, IDC_DOWNLOADLIST, OnLvnKeydownDownloadlist)
	ON_WM_ERASEBKGND() //==> dlarge RollUps

//==> NextEMF New Tooltips [Rayita]
	ON_NOTIFY_EX_RANGE(UDM_TOOLTIP_DISPLAY, 0, 0xFFFF, OnToolTipNotify) // added by rayita [Improved Tooltips]
//<== NextEMF New Tooltips [Rayita]
END_MESSAGE_MAP()

CTransferWnd::CTransferWnd(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CTransferWnd::IDD, pParent)
{
//==> dlarge RollUps
	icon_download = NULL;
	m_pwndDummyForDownloadList = NULL;
	m_pLastMousePoint.x = 0;
	m_pLastMousePoint.y = 0;
	m_iOldToolTipItemDownload = -1;
	m_iOldToolTipItemUpload = -1;
	m_iOldToolTipItemQueue = -1;
	m_iOldToolTipItemClients = -1;	
	m_nLastCatTT = -1;
//<== dlarge RollUps

//==> NextEMF New Tooltips [Rayita]
	lists_list[UPLOAD_WND] = &uploadlistctrl;
	lists_list[QUEUE_WND] = &queuelistctrl;
	lists_list[KNOWN_WND] = &clientlistctrl;
	lists_list[TRANSF_WND] = &downloadclientsctrl;
	lists_list[UPDOWN_WND] = &downloadlistctrl;
	lists_list[DOWNLOAD_WND] = &downloadlistctrl;
//<== NextEMF New Tooltips [Rayita]
}

CTransferWnd::~CTransferWnd()
{
//==> dlarge RollUps
	if (icon_download)
		VERIFY( DestroyIcon(icon_download) );

	SaveRollupItemHeights();
//<== dlarge RollUps
}

BOOL CTransferWnd::OnInitDialog()
{
	CResizableDialog::OnInitDialog();
	InitWindowStyles(this);

//==> dlarge RollUps
	CRect rRollupArea;

	GetClientRect(&rRollupArea);
	rRollupArea.DeflateRect(0,0);

	m_ctlRollup.Create(NULL, NULL, WS_CHILD|WS_VISIBLE/*|WS_CLIPCHILDREN*/, rRollupArea, this, TRANS_ROLLUP);

	//
	//	Create the Download-list control
	//
	CWnd *pParent = &m_ctlRollup;
	CRect rItem = CRect(0,0,0,0);
	DWORD dwListStyle	= WS_CHILD|WS_BORDER|WS_TABSTOP|LVS_REPORT|LVS_ALIGNLEFT|LVS_OWNERDRAWFIXED|LVS_SINGLESEL;
	DWORD dwTabStyle	= WS_CHILD|WS_VISIBLE|TCS_HOTTRACK|TCS_SINGLELINE|TCS_TOOLTIPS;

	m_pwndDummyForDownloadList = new CDummyForTabs();
	m_pwndDummyForDownloadList->Create(AfxRegisterWndClass(0), _T(""), WS_CHILD|WS_VISIBLE, rItem, pParent, TRANS_DUMMY);

	downloadlistctrl.Create(WS_VISIBLE | dwListStyle, rItem, m_pwndDummyForDownloadList, TRANS_DOWNLOADLIST);

	downloadclientsctrl.Create(WS_VISIBLE | dwListStyle, rItem, pParent, TRANS_DOWNLOADCLIENTLIST);

	uploadlistctrl.Create(WS_VISIBLE | dwListStyle, rItem, pParent, TRANS_UPLOADLIST);
	queuelistctrl.Create(/*WS_VISIBLE |*/ dwListStyle, rItem, pParent, TRANS_QUEUELIST);
	clientlistctrl.Create(/*WS_VISIBLE |*/ dwListStyle, rItem, pParent, TRANS_CLIENTLIST);

	m_dlTab.Create(dwTabStyle, CRect(0,0,0,20), pParent, TRANS_DOWNLOADTABS);
	m_dlTab.ModifyStyle(WS_CLIPSIBLINGS, 0);

	m_pwndDummyForDownloadList->SetChild(&downloadlistctrl);

	AddBuddy(m_pwndDummyForDownloadList->m_hWnd, m_dlTab.m_hWnd, BDS_TOP);

//==> GlobalSources in RollUps
	CDownloadQueue::SDownloadStats myStats;
	theApp.downloadqueue->GetDownloadSourcesStats(myStats);
//<== GlobalSources in RollUps

//==> GlobalSources in RollUps
	theApp.downloadqueue->FileStatsCount();
//<== GlobalSources in RollUps

	CString strDownloads;
	strDownloads.Format(GetResString(IDS_RUP_DOWNINFO),
		theApp.downloadqueue->GetFileCount()-1,
		theApp.downloadqueue->GetDownloadingFileCount()-1,
		theApp.downloadqueue->GetTransferingCount(),
		theApp.downloadqueue->GetStoppedCount(),

//==> GlobalSources in RollUps
		myStats.a[0],
//<== GlobalSources in RollUps
		static_cast<double>(theApp.downloadqueue->GetDatarate()/1024.0));
	
	CString strUploads;
		strUploads.Format(GetResString(IDS_RUP_UPINFO),
			theApp.uploadqueue->GetWaitingUserCount(),
			theApp.uploadqueue->GetUploadQueueLength(),  
			theApp.clientlist->GetBannedCount(),
			static_cast<double>(theApp.uploadqueue->GetDatarate())/1024.0);

	CString strDownloadClients;
	strDownloadClients.Format(GetResString(IDS_RUP_EXTINFO),
		downloadclientsctrl.GetItemCount(),
		static_cast<double>(theApp.downloadqueue->GetDatarate()) / 1024.0
		);

	m_ctlRollup.InsertItem(GetResString(IDS_RUP_DOWNLOADS), strDownloads, m_pwndDummyForDownloadList, 0, TRUE);
	m_ctlRollup.InsertItem(GetResString(IDS_RUP_UPLOADS), strUploads, &uploadlistctrl, 1, TRUE);
	m_ctlRollup.InsertItem(GetResString(IDS_RUP_EXT), strDownloadClients, &downloadclientsctrl, 2, TRUE);

	//AddAnchor(IDC_DLTAB,CSize(50,0) ,TOP_RIGHT);
	AddAnchor(m_ctlRollup.m_hWnd, TOP_LEFT, BOTTOM_RIGHT);
	InitRollupItemHeights();
//<== dlarge RollUps

	uploadlistctrl.Init();
	downloadlistctrl.Init();
	queuelistctrl.Init();
	clientlistctrl.Init();
	downloadclientsctrl.Init();
//==> dlarge RollUps
	uploadlistctrl.SetOwner(this);
	downloadlistctrl.SetOwner(this);
	queuelistctrl.SetOwner(this);
	clientlistctrl.SetOwner(this);
	downloadclientsctrl.SetOwner(this);

	m_dlTab.SetOwner(this);

	m_nActiveDownWnd	= DPW_DOWNLOADLIST;
	m_nActiveUpWnd		= MPW_UPLOADLIST;
	m_nActiveExtWnd		= EPW_LIST1;
//<== dlarge RollUps

	SetAllIcons(); //==> NextEMF New Tooltips [Rayita]

	//cats
	rightclickindex=-1;

	downloadlistactive=true;
	m_bIsDragging=false;

	// show & cat-tabs
	m_dlTab.ModifyStyle(0,TCS_OWNERDRAWFIXED);
	thePrefs.GetCategory(0)->strTitle = GetCatTitle(thePrefs.GetCategory(0)->filter);
	thePrefs.GetCategory(0)->strIncomingPath = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR);
	thePrefs.GetCategory(0)->care4all = true;

	for (int ix=0;ix<thePrefs.GetCatCount();ix++)
		m_dlTab.InsertItem(ix,thePrefs.GetCategory(ix)->strTitle);

//==> NextEMF New Tooltips [Rayita]
	// download tabs tooltips
	m_tabtip.Create(this, TTS_NOPREFIX);
	m_tabtip.SetDirection(CPPToolTip::PPTOOLTIP_RIGHT_BOTTOM);

	m_tabtip.AddTool(&m_dlTab, _T(""));

	// listctrls tooltips
	m_ttip.Create(this);
	m_ttip.AddTool(&downloadlistctrl, _T(""));
	m_ttip.AddTool(&uploadlistctrl, _T(""));
	m_ttip.AddTool(&queuelistctrl, _T(""));
	m_ttip.AddTool(&clientlistctrl, _T(""));
	m_ttip.AddTool(&downloadclientsctrl, _T(""));

	for(int i = 0; i < ARRSIZE(m_iOldToolTipItem); i++)
		m_iOldToolTipItem[i] = -1;

	SetTTDelay();
//<== NextEMF New Tooltips [Rayita]

//	VerifyCatTabSize(); //==> dlarge RollUps
    Localize();

	return true;
}

//==> dlarge RollUps
void CTransferWnd::ShowQueueCount(uint32 /*number*/)
{
/*
	TCHAR buffer[100];
	_sntprintf(buffer, _countof(buffer), _T("%u (%u ") + GetResString(IDS_BANNED).MakeLower() + _T(")"), number, theApp.clientlist->GetBannedCount());
	buffer[_countof(buffer) - 1] = _T('\0');
	GetDlgItem(IDC_QUEUECOUNT)->SetWindowText(buffer);
*/
}
//<== dlarge RollUps

void CTransferWnd::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
}

BOOL CTransferWnd::PreTranslateMessage(MSG* pMsg)
{
//==> NextEMF New Tooltips [Rayita]
	m_ttip.RelayEvent(pMsg);
	m_tabtip.RelayEvent(pMsg);
	//m_othertips.RelayEvent(pMsg);
	m_btttp.RelayEvent(pMsg);
//<== NextEMF New Tooltips [Rayita]
	if (pMsg->message == WM_KEYDOWN)
	{
		// Don't handle Ctrl+Tab in this window. It will be handled by main window.
		if (pMsg->wParam == VK_TAB && GetAsyncKeyState(VK_CONTROL) < 0)
			return FALSE;
	}
	else if (pMsg->message == WM_LBUTTONDBLCLK)
		{
		if (pMsg->hwnd == m_dlTab.m_hWnd)
		{
			OnDblclickDltab();
			return TRUE;
		}
	}
	else if (pMsg->message == WM_MOUSEMOVE)
	{
		POINT point;
			::GetCursorPos(&point);
		if (point.x != m_pLastMousePoint.x || point.y != m_pLastMousePoint.y)
			{
				m_pLastMousePoint = point;
			// handle tooltip updating, when mouse is moved from one item to another
//==> NextEMF New Tooltips [Rayita]
				UpdateToolTips(); 
				UpdateTabToolTips(); 
/*
			CPoint pt(point);
			m_nDropIndex = GetTabUnderMouse(&pt);
			if (m_nDropIndex != m_nLastCatTT)
			{
				m_nLastCatTT = m_nDropIndex;
				if (m_nDropIndex != -1)
					UpdateTabToolTips(m_nDropIndex);
			}
*/
//<== NextEMF New Tooltips [Rayita]
		}
	}
	else if (!thePrefs.GetStraightWindowStyles() && pMsg->message == WM_MBUTTONUP) 
	{
//==> dlarge RollUps
		int iSel = GetItemUnderMouse(&downloadlistctrl);

		if (iSel != -1)
		{
			downloadlistctrl.ShowSelectedFileDetails();
		}
		else
		{
			switch (m_nActiveUpWnd)
			{
				case MPW_UPLOADQUEUELIST:
			{
					queuelistctrl.ShowSelectedUserDetails();
					break;
				}
				case MPW_UPLOADLIST:
				{
					uploadlistctrl.ShowSelectedUserDetails();
					break;
				}
				case MPW_UPLOADCLIENTLIST:
				{
					clientlistctrl.ShowSelectedUserDetails();
					break;
			}
			}
		}
		return TRUE;
	}

	if(pMsg->message == USRMSG_SWITCHUPLOADLIST)
		SwitchUploadList();

	if(pMsg->message == USRMSG_SWITCHEXTLIST)
		SwitchExtList();

	return CResizableDialog::PreTranslateMessage(pMsg);
}
//<== dlarge RollUps

int CTransferWnd::GetItemUnderMouse(CListCtrl* ctrl)
{
	CPoint pt;
	::GetCursorPos(&pt);
	ctrl->ScreenToClient(&pt);
	LVHITTESTINFO hit, subhit;
	hit.pt = pt;
	subhit.pt = pt;
	ctrl->SubItemHitTest(&subhit);
	int sel = ctrl->HitTest(&hit);
	if (sel != LB_ERR && (hit.flags & LVHT_ONITEM))
	{
		if (subhit.iSubItem == 0)
			return sel;
	}
	return LB_ERR;
}

//==> dlarge RollUps
void CTransferWnd::SwitchUploadList()
{
	switch (m_nActiveUpWnd)
	{

		case MPW_UPLOADLIST:
		{
			m_nActiveUpWnd = MPW_UPLOADQUEUELIST;
			m_ctlRollup.SetText(1, GetResString(IDS_ONQUEUE), true);
			uploadlistctrl.ShowWindow(SW_HIDE);
			clientlistctrl.ShowWindow(SW_HIDE);
			m_ctlRollup.SetItemClient(1, &queuelistctrl);
			m_ctlRollup.Invalidate();
			//UpdateQueueFilter();
			break;
		}

		case MPW_UPLOADQUEUELIST:
		{
			m_nActiveUpWnd = MPW_UPLOADCLIENTLIST;
			CString buffer;
			buffer.Format(_T(" (%i)"), clientlistctrl.GetItemCount());
			m_ctlRollup.SetText(1, GetResString(IDS_CLIENTLIST)+buffer, true);
			uploadlistctrl.ShowWindow(SW_HIDE);
			queuelistctrl.ShowWindow(SW_HIDE);
			m_ctlRollup.SetItemClient(1, &clientlistctrl);
			m_ctlRollup.Invalidate();
			break;
		}

		case MPW_UPLOADCLIENTLIST:
		{
			m_nActiveUpWnd = MPW_UPLOADLIST;
			m_ctlRollup.SetText(1, GetResString(IDS_RUP_UPLOADS), true);
			queuelistctrl.ShowWindow(SW_HIDE);
			clientlistctrl.ShowWindow(SW_HIDE);
			m_ctlRollup.SetItemClient(1, &uploadlistctrl);
			m_ctlRollup.Invalidate();
			break;
		}
		default:
			break;
	}
}

void CTransferWnd::SwitchExtList()
{
	switch (m_nActiveExtWnd)
	{
		case EPW_LIST1:
	{

			break;
}
		case EPW_LIST2:
{

			break;
}

		default:
			break;
	}
}
//<== dlarge RollUps

void CTransferWnd::OnSysColorChange()
{
	CResizableDialog::OnSysColorChange();
}

//==> NextEMF New Tooltips [Rayita]
void CTransferWnd::SetAllIcons()
{
	m_ImageList.DeleteImageList();
	m_ImageList.Create(32,32,theApp.m_iDfltImageListColorFlags|ILC_MASK,0,1);
	m_ImageList.SetBkColor(CLR_NONE);

	m_ImageList.Add(CTempIconLoader(_T("SrcDownloading")));
	m_ImageList.Add(CTempIconLoader(_T("SrcOnQueue")));
	m_ImageList.Add(CTempIconLoader(_T("SrcConnecting")));
	m_ImageList.Add(CTempIconLoader(_T("SrcNNPQF")));
	m_ImageList.Add(CTempIconLoader(_T("SrcUnknown")));
	m_ImageList.Add(CTempIconLoader(_T("ClientCompatible")));//5
	m_ImageList.Add(CTempIconLoader(_T("Friend")));//6
	m_ImageList.Add(CTempIconLoader(_T("ClientEDonkey")));//7
	m_ImageList.Add(CTempIconLoader(_T("ClientMLDonkey")));//8
	m_ImageList.Add(CTempIconLoader(_T("ClientEDonkeyHybrid")));//9
	m_ImageList.Add(CTempIconLoader(_T("ClientShareaza")));//10
	m_ImageList.Add(CTempIconLoader(_T("ClientAMule")));//11
	m_ImageList.Add(CTempIconLoader(_T("ClientLPhant")));//12
	m_ImageList.Add(CTempIconLoader(_T("Server")));//13
}
//<== NextEMF New Tooltips [Rayita]

void CTransferWnd::Localize()
{
	uploadlistctrl.Localize();
	queuelistctrl.Localize();
	downloadlistctrl.Localize();
	clientlistctrl.Localize();
	downloadclientsctrl.Localize();
}

void CTransferWnd::OnHoverUploadList(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
	downloadlistactive = false;
	*pResult = 0;
}

void CTransferWnd::OnHoverDownloadList(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
	downloadlistactive = true;
	*pResult = 0;
}

void CTransferWnd::OnTcnSelchangeDltab(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
	downloadlistctrl.ChangeCategory(m_dlTab.GetCurSel());
	*pResult = 0;
}

// Ornis' download categories
void CTransferWnd::OnNMRclickDltab(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
	POINT point;
	::GetCursorPos(&point);
	CPoint pt(point);
	rightclickindex = GetTabUnderMouse(&pt);
	if (rightclickindex == -1)
		return;

//>>> shadow2004::XPMenu [TPT]
	CMenuXP* Menu = new CMenuXP;
	Menu->CreatePopupMenu();
	Menu->ApplyPrefs(true, rightclickindex ? (GetResString(IDS_CAT)+_T(" (")+thePrefs.GetCategory(rightclickindex)->strTitle+L")") : (GetResString(IDS_CAT)), L"IDR_MENU2_BACK");

	CMenuXP* PrioMenu = new CMenuXP;
	PrioMenu->CreatePopupMenu();
	PrioMenu->ApplyPrefs(false, NULL, NULL);

    Category_Struct* category_Struct = thePrefs.GetCategory(rightclickindex);

	PrioMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_PRIOLOW,GetResString(IDS_PRIOLOW)));
	PrioMenu->CheckMenuItem(MP_PRIOLOW, category_Struct && category_Struct->prio == PR_LOW ? MF_CHECKED : MF_UNCHECKED);
	PrioMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_PRIONORMAL,GetResString(IDS_PRIONORMAL)));
	PrioMenu->CheckMenuItem(MP_PRIONORMAL, category_Struct && category_Struct->prio != PR_LOW && category_Struct->prio != PR_HIGH ? MF_CHECKED : MF_UNCHECKED);
	PrioMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_PRIOHIGH, GetResString(IDS_PRIOHIGH)));
	PrioMenu->CheckMenuItem(MP_PRIOHIGH, category_Struct && category_Struct->prio == PR_HIGH ? MF_CHECKED : MF_UNCHECKED);

	CMenuXP* CatMenu = new CMenuXP;
	CatMenu->CreatePopupMenu();
	CatMenu->ApplyPrefs(false, L"", L"IDR_MENU2_BACK");

	m_isetcatmenu = rightclickindex;
	UINT flag = (!thePrefs.GetCategory(rightclickindex)->care4all && rightclickindex) ? MF_GRAYED : MF_STRING;

	CatMenu->AppendODMenu(flag, new CMenuXPText(MP_CAT_SET0+1, GetResString(IDS_ALLOTHERS)));

	if (rightclickindex) {
		if (thePrefs.IsExtControlsEnabled())
			CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+18, GetResString(IDS_REGEXPRESSION)));

		flag=MF_STRING;
		if (thePrefs.GetCategory(rightclickindex)->care4all)
			flag=flag|MF_CHECKED | MF_BYCOMMAND;
		if (thePrefs.IsExtControlsEnabled() )
			CatMenu->AppendODMenu(flag, new CMenuXPText(MP_CAT_SET0+17,GetResString(IDS_CARE4ALL)));
	}

	CatMenu->AppendSeparator();
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+2,GetResString(IDS_STATUS_NOTCOMPLETED)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+3,GetResString(IDS_DL_TRANSFCOMPL)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+4,GetResString(IDS_WAITING)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+5,GetResString(IDS_DOWNLOADING)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+6,GetResString(IDS_ERRORLIKE)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+7,GetResString(IDS_PAUSED)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+8,GetResString(IDS_SEENCOMPL)));
	CatMenu->AppendSeparator();
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+10,GetResString(IDS_VIDEO)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+11,GetResString(IDS_AUDIO)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+12,GetResString(IDS_SEARCH_ARC)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+13,GetResString(IDS_SEARCH_CDIMG)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+14,GetResString(IDS_SEARCH_DOC)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+15,GetResString(IDS_SEARCH_PICS)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+16,GetResString(IDS_SEARCH_PRG)));
	CatMenu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_SET0+20,GetResString(IDS_SEARCH_EMULECOLLECTION)));

	if (thePrefs.IsExtControlsEnabled()) {
		CatMenu->AppendSeparator();
		CatMenu->AppendODMenu( thePrefs.GetCatFilter(rightclickindex)>0?MF_STRING:MF_GRAYED, new CMenuXPText(MP_CAT_SET0+19, GetResString(IDS_NEGATEFILTER)));
		if ( thePrefs.GetCatFilterNeg(rightclickindex))
			CatMenu->CheckMenuItem( MP_CAT_SET0+19 ,MF_CHECKED | MF_BYCOMMAND);
	}
	
	CatMenu->CheckMenuItem( MP_CAT_SET0+thePrefs.GetCatFilter(rightclickindex) ,MF_CHECKED | MF_BYCOMMAND);

	Menu->AppendODPopup(MF_STRING | MF_POPUP, CatMenu, new CMenuXPText(0, GetResString(IDS_CHANGECATVIEW), theApp.LoadIcon(_T("SEARCHPARAMS"), 16, 16)));
	Menu->AppendSeparator();
	Menu->AppendODPopup(MF_STRING | MF_POPUP, PrioMenu, new CMenuXPText(0, GetResString(IDS_PRIORITY), theApp.LoadIcon(_T("FILEPRIORITY"), 16, 16)));
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CANCEL,GetResString(IDS_MAIN_BTN_CANCEL), theApp.LoadIcon(_T("DELETE"), 16, 16)));
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_STOP, GetResString(IDS_DL_STOP), theApp.LoadIcon(_T("STOP"), 16, 16)));
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_PAUSE, GetResString(IDS_DL_PAUSE), theApp.LoadIcon(_T("PAUSE"), 16, 16)));
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_RESUME, GetResString(IDS_DL_RESUME), theApp.LoadIcon(_T("RESUME"), 16, 16)));
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_RESUMENEXT, GetResString(IDS_DL_RESUMENEXT), theApp.LoadIcon(_T("RESUME"), 16, 16)));
    if(rightclickindex != 0 && thePrefs.IsExtControlsEnabled()) {
        Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_DOWNLOAD_ALPHABETICAL, GetResString(IDS_DOWNLOAD_ALPHABETICAL)));	
		Menu->CheckMenuItem(MP_DOWNLOAD_ALPHABETICAL, category_Struct && category_Struct->downloadInAlphabeticalOrder ? MF_CHECKED : MF_UNCHECKED);
    }
	Menu->AppendSeparator();
	
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_HM_OPENINC, GetResString(IDS_OPENINC), theApp.LoadIcon(_T("FOLDERS"), 16, 16)));

	flag=(rightclickindex==0) ? MF_GRAYED:MF_STRING;
	Menu->AppendSeparator();
	Menu->AppendODMenu(MF_STRING, new CMenuXPText(MP_CAT_ADD,GetResString(IDS_CAT_ADD)));
	Menu->AppendODMenu(flag, new CMenuXPText(MP_CAT_EDIT,GetResString(IDS_CAT_EDIT)));
	Menu->AppendODMenu(flag, new CMenuXPText(MP_CAT_REMOVE, GetResString(IDS_CAT_REMOVE)));

	Menu->TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this);

	delete PrioMenu;
	delete CatMenu;
	delete Menu;
//<<< shadow2004::XPMenu [TPT]

	*pResult = 0;
}

void CTransferWnd::OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)
{
    int iSel = downloadlistctrl.GetSelectionMark();
	if (iSel==-1) return;
	if (((CtrlItem_Struct*)downloadlistctrl.GetItemData(iSel))->type != FILE_TYPE) return;
	
	m_bIsDragging = true;

	POINT pt;
	::GetCursorPos(&pt);

	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	m_nDragIndex = pNMLV->iItem;
	m_pDragImage = downloadlistctrl.CreateDragImage( downloadlistctrl.GetSelectionMark() ,&pt);
    m_pDragImage->BeginDrag( 0, CPoint(0,0) );
    m_pDragImage->DragEnter( GetDesktopWindow(), pNMLV->ptAction );
    SetCapture();
	m_nDropIndex = -1;

	*pResult = 0;
}

void CTransferWnd::OnMouseMove(UINT nFlags, CPoint point)
{
	if( !(nFlags & MK_LBUTTON) ) m_bIsDragging = false;

	if (m_bIsDragging){
		CPoint pt(point);           //get our current mouse coordinates
		ClientToScreen(&pt);        //convert to screen coordinates

		m_nDropIndex=GetTabUnderMouse(&pt);

		if (m_nDropIndex>0 && thePrefs.GetCategory(m_nDropIndex)->care4all)	// not droppable
			m_dlTab.SetCurSel(-1);
		else
		m_dlTab.SetCurSel(m_nDropIndex);

		m_dlTab.Invalidate();
		
		::GetCursorPos(&pt);
		pt.y-=10;
		m_pDragImage->DragMove(pt); //move the drag image to those coordinates
	}
}

void CTransferWnd::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)
{
	if (m_bIsDragging)
	{
		ReleaseCapture ();
		m_bIsDragging = false;
		m_pDragImage->DragLeave (GetDesktopWindow ());
		m_pDragImage->EndDrag ();
		delete m_pDragImage;
		
		if (m_nDropIndex > -1 && (downloadlistctrl.curTab==0 ||
				(downloadlistctrl.curTab > 0 && (UINT)m_nDropIndex != downloadlistctrl.curTab) )) {

			CPartFile* file;

			// for multiselections
			CTypedPtrList <CPtrList,CPartFile*> selectedList; 
			POSITION pos = downloadlistctrl.GetFirstSelectedItemPosition();
			while(pos != NULL) 
			{ 
				int index = downloadlistctrl.GetNextSelectedItem(pos);
				if(index > -1 && (((CtrlItem_Struct*)downloadlistctrl.GetItemData(index))->type == FILE_TYPE))
					selectedList.AddTail( (CPartFile*)((CtrlItem_Struct*)downloadlistctrl.GetItemData(index))->value );
			}

			while (!selectedList.IsEmpty())
			{
				file = selectedList.GetHead();
				selectedList.RemoveHead();
				file->SetCategory(m_nDropIndex);
			}


			m_dlTab.SetCurSel(downloadlistctrl.curTab);
			//if (m_dlTab.GetCurSel()>0 || (thePrefs.GetAllcatType()==1 && m_dlTab.GetCurSel()==0) )
			downloadlistctrl.UpdateCurrentCategoryView();

			UpdateCatTabTitles();

		} else m_dlTab.SetCurSel(downloadlistctrl.curTab);
		downloadlistctrl.Invalidate();
	}
}

BOOL CTransferWnd::OnCommand(WPARAM wParam, LPARAM /*lParam*/)
{
	// category filter menuitems
	if (wParam>=MP_CAT_SET0 && wParam<=MP_CAT_SET0+99)
	{
		if (wParam==MP_CAT_SET0+17)
		{
			thePrefs.GetCategory(m_isetcatmenu)->care4all=!thePrefs.GetCategory(m_isetcatmenu)->care4all;
		}
		else if (wParam==MP_CAT_SET0+19) // negate
		{
			thePrefs.SetCatFilterNeg(m_isetcatmenu, (!thePrefs.GetCatFilterNeg(m_isetcatmenu)));
		}
		else // set the view filter
		{
			if (wParam-MP_CAT_SET0<1)	// dont negate all filter
				thePrefs.SetCatFilterNeg(m_isetcatmenu, false);
			thePrefs.SetCatFilter(m_isetcatmenu,wParam-MP_CAT_SET0);
			m_nLastCatTT=-1;
		}

		// set to regexp but none is set for that category?
		if (wParam==MP_CAT_SET0+18 && thePrefs.GetCategory(m_isetcatmenu)->regexp.IsEmpty())
		{
			m_nLastCatTT=-1;
			CCatDialog dialog(rightclickindex);
			dialog.DoModal();

			// still no regexp?
			if (thePrefs.GetCategory(m_isetcatmenu)->regexp.IsEmpty())
				thePrefs.SetCatFilter(m_isetcatmenu,0);
		}

		downloadlistctrl.UpdateCurrentCategoryView();
		EditCatTabLabel(m_isetcatmenu);
		thePrefs.SaveCats();
		return TRUE;
	}
	
	switch (wParam)
	{ 

//==> dlarge RollUps
		case USRMSG_SWITCHUPLOADLIST:
			{
				SwitchUploadList();
				break;
			}

		case USRMSG_SWITCHEXTLIST:
			{
				SwitchExtList();
				break;
			}
//<== dlarge RollUps

		case MP_CAT_ADD: {
			m_nLastCatTT=-1;
			int newindex=AddCategory(_T("?"),thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR),_T(""),_T(""),false);
			CCatDialog dialog(newindex);
			if (dialog.DoModal() == IDOK)
			{
				theApp.emuledlg->searchwnd->UpdateCatTabs();
				m_dlTab.InsertItem(newindex,thePrefs.GetCategory(newindex)->strTitle);
				m_dlTab.SetTabTextColor(newindex, thePrefs.GetCatColor(newindex) );
				EditCatTabLabel(newindex);
				thePrefs.SaveCats();
//				VerifyCatTabSize(); //==> dlarge RollUps
				if (CompareDirectories(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), thePrefs.GetCatPath(newindex)))
					theApp.emuledlg->sharedfileswnd->Reload();
			}
			else
				thePrefs.RemoveCat(newindex);
			break;
		}
		case MP_CAT_EDIT: {
			m_nLastCatTT=-1;
			CString oldincpath=thePrefs.GetCatPath(rightclickindex);
			CCatDialog dialog(rightclickindex);
			if (dialog.DoModal() == IDOK)
			{
				EditCatTabLabel(rightclickindex, thePrefs.GetCategory(rightclickindex)->strTitle);
				m_dlTab.SetTabTextColor(rightclickindex, thePrefs.GetCatColor(rightclickindex) );
				theApp.emuledlg->searchwnd->UpdateCatTabs();
				theApp.emuledlg->transferwnd->downloadlistctrl.UpdateCurrentCategoryView();
				thePrefs.SaveCats();
				if (CompareDirectories(oldincpath, thePrefs.GetCatPath(rightclickindex)))
					theApp.emuledlg->sharedfileswnd->Reload();
			}
			break;
		}
		case MP_CAT_REMOVE: {
			m_nLastCatTT=-1;
			bool toreload=( _tcsicmp(thePrefs.GetCatPath(rightclickindex), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR))!=0);
			theApp.downloadqueue->ResetCatParts(rightclickindex);
			thePrefs.RemoveCat(rightclickindex);
			m_dlTab.DeleteItem(rightclickindex);
			m_dlTab.SetCurSel(0);
			downloadlistctrl.ChangeCategory(0);
			thePrefs.SaveCats();
			if (thePrefs.GetCatCount()==1) 
				thePrefs.GetCategory(0)->filter=0;
			theApp.emuledlg->searchwnd->UpdateCatTabs();
//			VerifyCatTabSize(); //==> dlarge RollUps
			if (toreload)
				theApp.emuledlg->sharedfileswnd->Reload();
			break;
		}

		case MP_PRIOLOW:
            thePrefs.GetCategory(rightclickindex)->prio = PR_LOW;
			thePrefs.SaveCats();
			break;
		case MP_PRIONORMAL:
            thePrefs.GetCategory(rightclickindex)->prio = PR_NORMAL;
			thePrefs.SaveCats();
			break;
		case MP_PRIOHIGH:
            thePrefs.GetCategory(rightclickindex)->prio = PR_HIGH;
			thePrefs.SaveCats();
			break;

		case MP_PAUSE:
			theApp.downloadqueue->SetCatStatus(rightclickindex,MP_PAUSE);
			break;
		case MP_STOP:
			theApp.downloadqueue->SetCatStatus(rightclickindex,MP_STOP);
			break;
		case MP_CANCEL:
			if (AfxMessageBox(GetResString(IDS_Q_CANCELDL),MB_ICONQUESTION|MB_YESNO) == IDYES)
				theApp.downloadqueue->SetCatStatus(rightclickindex,MP_CANCEL);
			break;
		case MP_RESUME:
			theApp.downloadqueue->SetCatStatus(rightclickindex,MP_RESUME);
			break;
		case MP_RESUMENEXT:
			theApp.downloadqueue->StartNextFile(rightclickindex,false);
			break;

		case MP_DOWNLOAD_ALPHABETICAL: {
            bool newSetting = !thePrefs.GetCategory(rightclickindex)->downloadInAlphabeticalOrder;
            thePrefs.GetCategory(rightclickindex)->downloadInAlphabeticalOrder = newSetting;
			thePrefs.SaveCats();
            if(newSetting) {
                // any auto prio files will be set to normal now.
                theApp.downloadqueue->RemoveAutoPrioInCat(rightclickindex, PR_NORMAL);
            }
            break;
		}

		case IDC_UPLOAD_ICO:
			SwitchUploadList();
			break;

		case MP_HM_OPENINC:
			ShellExecute(NULL, _T("open"), thePrefs.GetCategory(m_isetcatmenu)->strIncomingPath,NULL, NULL, SW_SHOW);
			break;

	}
	return TRUE;
}

void CTransferWnd::UpdateCatTabTitles(bool force)
{
	CPoint pt;
	::GetCursorPos(&pt);
	if (!force && GetTabUnderMouse(&pt)!=-1)		// avoid cat tooltip jumping
		return;

	for (int i = 0; i < m_dlTab.GetItemCount(); i++){
		EditCatTabLabel(i,/*(i==0)? GetCatTitle( thePrefs.GetCategory(0)->filter ):*/thePrefs.GetCategory(i)->strTitle);
		m_dlTab.SetTabTextColor(i, thePrefs.GetCatColor(i) );
	}
}

void CTransferWnd::EditCatTabLabel(int i)
{
	EditCatTabLabel(i,/*(i==0)? GetCatTitle( thePrefs.GetAllcatType() ):*/thePrefs.GetCategory(i)->strTitle);
}

void CTransferWnd::EditCatTabLabel(int index,CString newlabel)
{
	TCITEM tabitem;
	tabitem.mask = TCIF_PARAM;
	m_dlTab.GetItem(index,&tabitem);
	tabitem.mask = TCIF_TEXT;

	newlabel.Replace(_T("&"),_T("&&"));

	if (!index)
		newlabel.Empty();

	if (!index || (index && thePrefs.GetCatFilter(index)>0)) {

		if (index)
			newlabel.Append(_T(" (")) ;
		
		if (thePrefs.GetCatFilterNeg(index))
			newlabel.Append(_T("!"));			
 
		if (thePrefs.GetCatFilter(index)==18)
			newlabel.Append( _T("\"") + thePrefs.GetCategory(index)->regexp + _T("\"") );
		else
        	newlabel.Append( GetCatTitle(thePrefs.GetCatFilter(index)));

		if (index)
			newlabel.Append( _T(")") );
	}

	int count,dwl;
	if (thePrefs.ShowCatTabInfos()) {
		CPartFile* cur_file;
		count=dwl=0;
		for (int i=0;i<theApp.downloadqueue->GetFileCount();i++) {
			cur_file=theApp.downloadqueue->GetFileByIndex(i);
			if (cur_file==0) continue;
			if (cur_file->CheckShowItemInGivenCat(index)) {
				if (cur_file->GetTransferringSrcCount()>0) ++dwl;
			}
		}
		CString title=newlabel;
		theApp.emuledlg->transferwnd->downloadlistctrl.GetCompleteDownloads(index, count);
		newlabel.Format(_T("%s %i/%i"),title,dwl,count);
	}

	tabitem.pszText = newlabel.LockBuffer();
	m_dlTab.SetItem(index,&tabitem);
	newlabel.UnlockBuffer();

//      VerifyCatTabSize(); //==> dlarge RollUps
}

int CTransferWnd::AddCategory(CString newtitle,CString newincoming,CString newcomment, CString newautocat, bool addTab)
{
	Category_Struct* newcat=new Category_Struct;
	newcat->strTitle = newtitle;
	newcat->prio=PR_NORMAL;
	newcat->strIncomingPath = newincoming;
	newcat->strComment = newcomment;
	newcat->regexp.Empty();
	newcat->ac_regexpeval=false;
	newcat->autocat=newautocat;
        newcat->downloadInAlphabeticalOrder = FALSE;
	newcat->filter=0;
	newcat->filterNeg=false;
	newcat->care4all=false;
	newcat->color= (DWORD)-1;

	int index=thePrefs.AddCat(newcat);
	if (addTab) m_dlTab.InsertItem(index,newtitle);
//	VerifyCatTabSize(); //==> dlarge RollUps
	
	return index;
}

int CTransferWnd::GetTabUnderMouse(CPoint* point)
{
	TCHITTESTINFO hitinfo;
	CRect rect;
	m_dlTab.GetWindowRect(&rect);
	point->Offset(0-rect.left,0-rect.top);
	hitinfo.pt = *point;

	if( m_dlTab.GetItemRect( 0, &rect ) )
		if (hitinfo.pt.y< rect.top+30 && hitinfo.pt.y >rect.top-30)
			hitinfo.pt.y = rect.top;

	// Find the destination tab...
	unsigned int nTab = m_dlTab.HitTest( &hitinfo );

	if( hitinfo.flags != TCHT_NOWHERE )
		return nTab;
	else
		return -1;
}

void CTransferWnd::OnLvnKeydownDownloadlist(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
	int iItem = downloadlistctrl.GetSelectionMark();
	if (iItem != -1)
	{
		bool bAltKey = GetAsyncKeyState(VK_MENU) < 0;
		int iAction = EXPAND_COLLAPSE;
		if (pLVKeyDow->wVKey==VK_ADD || (bAltKey && pLVKeyDow->wVKey==VK_RIGHT))
			iAction = EXPAND_ONLY;
		else if (pLVKeyDow->wVKey==VK_SUBTRACT || (bAltKey && pLVKeyDow->wVKey==VK_LEFT))
			iAction = COLLAPSE_ONLY;
		if (iAction < EXPAND_COLLAPSE)
			downloadlistctrl.ExpandCollapseItem(iItem, iAction, true);
	}
	*pResult = 0;
}

//==> NextEMF New Tooltips [Rayita]
void CTransferWnd::UpdateTabToolTips(int /*tab*/)
{
/*
	if (tab == -1)
	{
		for (int i = 0; i < m_tooltipCats->GetToolCount(); i++)
			m_tooltipCats->DelTool(&m_dlTab, i + 1);

		for (int i = 0; i < m_dlTab.GetItemCount(); i++)
		{
			CRect r;
			m_dlTab.GetItemRect(i, &r);
			VERIFY( m_tooltipCats->AddTool(&m_dlTab, GetTabStatistic(i), &r, i + 1) );
		}
	}
	else
	{
		CRect r;
		m_dlTab.GetItemRect(tab, &r);
		m_tooltipCats->DelTool(&m_dlTab, tab + 1);
		VERIFY( m_tooltipCats->AddTool(&m_dlTab, GetTabStatistic(tab), &r, tab + 1) );
	}
}

void CTransferWnd::SetToolTipsDelay(DWORD dwDelay)
{
	m_tooltipCats->SetDelayTime(TTDT_INITIAL, dwDelay);

	CToolTipCtrl* tooltip = downloadlistctrl.GetToolTips();
	if (tooltip)
		tooltip->SetDelayTime(TTDT_INITIAL, dwDelay);

	tooltip = uploadlistctrl.GetToolTips();
	if (tooltip)
		tooltip->SetDelayTime(TTDT_INITIAL, dwDelay);
}

CString CTransferWnd::GetTabStatistic(int tab)
{
	uint16 count, dwl, err, paus;
	count = dwl = err = paus = 0;
	float speed = 0;
	uint64 size = 0;
	uint64 trsize = 0;
	uint64 disksize = 0;
	for (int i = 0; i < theApp.downloadqueue->GetFileCount(); i++)
	{
		const CPartFile* cur_file = theApp.downloadqueue->GetFileByIndex(i);
		if (cur_file == 0)
			continue;
		if (cur_file->CheckShowItemInGivenCat(tab))
		{
			count++;
			if (cur_file->GetTransferringSrcCount() > 0)
				dwl++;
			speed += cur_file->GetDatarate() / 1024.0F;
			size += (uint64)cur_file->GetFileSize();
			trsize += (uint64)cur_file->GetCompletedSize();
			if (!cur_file->IsAllocating())
				disksize += (uint64)cur_file->GetRealFileSize();
			if (cur_file->GetStatus() == PS_ERROR)
				err++;
			if (cur_file->GetStatus() == PS_PAUSED)
				paus++;
		}
	}

	int total;
	int compl = theApp.emuledlg->transferwnd->downloadlistctrl.GetCompleteDownloads(tab, total);

    CString prio;
    switch (thePrefs.GetCategory(tab)->prio)
	{
        case PR_LOW:
            prio = GetResString(IDS_PRIOLOW);
            break;
        case PR_HIGH:
            prio = GetResString(IDS_PRIOHIGH);
            break;
        default:
            prio = GetResString(IDS_PRIONORMAL);
            break;
    }

	CString title;
	title.Format(_T("%s: %i\n\n%s: %i\n%s: %i\n%s: %i\n%s: %i\n\n%s: %s\n\n%s: %.1f %s\n%s: %s/%s\n%s%s"),
		GetResString(IDS_FILES), count + compl,
		GetResString(IDS_DOWNLOADING), dwl,
		GetResString(IDS_PAUSED), paus,
		GetResString(IDS_ERRORLIKE), err,
		GetResString(IDS_DL_TRANSFCOMPL), compl,
        GetResString(IDS_PRIORITY), prio,
		GetResString(IDS_DL_SPEED), speed, GetResString(IDS_KBYTESPERSEC),
		GetResString(IDS_DL_SIZE), CastItoXBytes(trsize, false, false), CastItoXBytes(size, false, false),
		GetResString(IDS_ONDISK), CastItoXBytes(disksize, false, false));
	title += TOOLTIP_AUTOFORMAT_SUFFIX_CH;
	return title;
*/
}
//<== NextEMF New Tooltips [Rayita]

void CTransferWnd::OnDblclickDltab()
{
	POINT point;
	::GetCursorPos(&point);
	CPoint pt(point);
	int tab = GetTabUnderMouse(&pt);
	if (tab < 1)
		return;
	rightclickindex = tab;
	OnCommand(MP_CAT_EDIT, 0);
}

void CTransferWnd::OnTabMovement(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/)
{
	UINT from=m_dlTab.GetLastMovementSource();
	UINT to=m_dlTab.GetLastMovementDestionation();

	if (from==0 || to==0 || from==to-1) return;

	// do the reorder
	
	// rearrange the cat-map
	if (!thePrefs.MoveCat(from,to)) return;

	// update partfile-stored assignment
	theApp.downloadqueue->MoveCat((uint8)from,(uint8)to);

	// move category of completed files
	downloadlistctrl.MoveCompletedfilesCat((uint8)from,(uint8)to);

	// of the tabcontrol itself
	m_dlTab.ReorderTab(from,to);

	UpdateCatTabTitles();
	theApp.emuledlg->searchwnd->UpdateCatTabs();

	if (to>from) --to;
	m_dlTab.SetCurSel(to);
	downloadlistctrl.ChangeCategory(to);
}

//==> dlarge RollUps
/*
void CTransferWnd::VerifyCatTabSize()
{
	if (m_dwShowListIDC != IDC_DOWNLOADLIST && m_dwShowListIDC != IDC_UPLOADLIST + IDC_DOWNLOADLIST)
		return;

	int size = 0;
	for (int i = 0; i < m_dlTab.GetItemCount(); i++)
	{
		CRect rect;
		m_dlTab.GetItemRect(i, &rect);
		size += rect.Width();
	}
	size += 4;

	int right;
	WINDOWPLACEMENT wp;
	downloadlistctrl.GetWindowPlacement(&wp);
	right = wp.rcNormalPosition.right;
	m_dlTab.GetWindowPlacement(&wp);
	if (wp.rcNormalPosition.right < 0)
		return;
	wp.rcNormalPosition.right = right;

	int left = wp.rcNormalPosition.right - size;
	CRect rcBtnWnd1;
	m_btnWnd1->GetWindowRect(rcBtnWnd1);
	ScreenToClient(rcBtnWnd1);
	if (left < rcBtnWnd1.right + 10)
		left = rcBtnWnd1.right + 10;
	wp.rcNormalPosition.left = left;

	RemoveAnchor(m_dlTab);
	m_dlTab.SetWindowPlacement(&wp);
	AddAnchor(m_dlTab, TOP_RIGHT);
}
*/
//<== dlarge RollUps

CString CTransferWnd::GetCatTitle(int catid)
{
	switch (catid) {
		case 0 : return GetResString(IDS_ALL);
		case 1 : return GetResString(IDS_ALLOTHERS);
		case 2 : return GetResString(IDS_STATUS_NOTCOMPLETED);
		case 3 : return GetResString(IDS_DL_TRANSFCOMPL);
		case 4 : return GetResString(IDS_WAITING);
		case 5 : return GetResString(IDS_DOWNLOADING);
		case 6 : return GetResString(IDS_ERRORLIKE);
		case 7 : return GetResString(IDS_PAUSED);
		case 8 : return GetResString(IDS_SEENCOMPL);
		case 10 : return GetResString(IDS_VIDEO);
		case 11 : return GetResString(IDS_AUDIO);
		case 12 : return GetResString(IDS_SEARCH_ARC);
		case 13 : return GetResString(IDS_SEARCH_CDIMG);
		case 14 : return GetResString(IDS_SEARCH_DOC);
		case 15 : return GetResString(IDS_SEARCH_PICS);
		case 16 : return GetResString(IDS_SEARCH_PRG);
//		case 18 : return GetResString(IDS_REGEXPRESSION);
	}
	return _T("?");
}

//==> dlarge RollUps
void CTransferWnd::InitRollupItemHeights()
{	
	static const double s_afDefItemHeights[3][8] =
	{
		{ 0, 100, 0, 70, 0, 70, 0, 50 },
		{ 0, 0, 100, 30, 0, 0, 70, 25 },
		{ 0, 0, 0, 0, 100, 30, 30, 25 }
	};

	double fItemHeights[3][8];
	double (*pafItemHeights)[8];
			
	FILE *f;
	CString fullpath;
	fullpath.Format(_T("%sgui.dat"), thePrefs.GetMuleDirectory(EMULE_CONFIGDIR));

	//	Try to open the GUI settings save file
#ifdef _UNICODE
	f = _tfopen(fullpath, _T("r"));
#else
	f = _tfopen(fullpath, _T("rb"));
#endif

	bool bUseDefault = false;

	//	If we opened it...
	if(f)
	{
		TCHAR cTemp[512] = _T("");
		TCHAR *pToken;

		static const TCHAR s_acSeps[] = _T("|\n");

		for(int x = 0; x < 8; x++)
		{
		//	Try to read a line from the file. If we can't...
			
			if(!_fgetts(cTemp, 512, f))
			{
				bUseDefault = true;
				break;
			}

			double fTotalHeight = 0.0;

			//	Look for the next seperator
			pToken = _tcstok(cTemp, s_acSeps);
			for(int i = 0; i < 3; i++)
			{
			//	If we couldn't find the expected seperator
				if(!pToken)
				{
					bUseDefault = true;
					break;
				}

			//	Extract the next percentage
				fItemHeights[i][x] = _tstof(pToken);
				//TRACE("fItemHeights[%d][%d] = %f\r\n", i, x, _tstof(pToken));	
				
			//	Find the next seperator
				pToken = _tcstok(NULL, s_acSeps);

			//	If we somehow read a negative percentage...
				if(fItemHeights[i][x] < 0)	// this should never happen
				{
					bUseDefault = true;
					break;
				}
			//	Total up the percentages for this expansion pattern
				fTotalHeight += fItemHeights[i][x];
			}
			if (bUseDefault)
				break;

			//	If the percentages don't total up to 100 somehow...
			if(fTotalHeight >= 101 || fTotalHeight <= 99 && fTotalHeight != 0) // i'm very tolerant ;)
			{
				bUseDefault = true;
				break;
			}
		}

	//
	//	Restore the user's last expansion state
	//

	//	Try to read the next line
		
		if(!_fgetts(cTemp, 512, f))
			bUseDefault = true;

		if(!bUseDefault)
		{
			pToken = _tcstok(cTemp, s_acSeps);

			for(int i = 0; i < 3; i++)
			{
				if(!pToken)
				{
					bUseDefault = true;
					break;
				}

				m_ctlRollup.ExpandItem(i, (_tstoi(pToken)) ? true : false );
				pToken = _tcstok(NULL, s_acSeps);
			}
				}
		fclose(f);
	}
	//	If there are no saved GUI settings...
	else
		bUseDefault = true;

	pafItemHeights = (bUseDefault) ? (double (*)[8])s_afDefItemHeights : fItemHeights;

	m_ctlRollup.SetItemHeights(0, pafItemHeights[0], 8);
	m_ctlRollup.SetItemHeights(1, pafItemHeights[1], 8);
	m_ctlRollup.SetItemHeights(2, pafItemHeights[2], 8);

}

void CTransferWnd::SaveRollupItemHeights()
{	
//	Don't try to save if objects weren't created
	if (m_ctlRollup.GetCount() >= 3)
	{
		FILE *f;
		CString fullpath;

		fullpath.Format(_T("%sgui.dat"),thePrefs.GetMuleDirectory(EMULE_CONFIGDIR));
		f = _tfopen(fullpath, _T("wb"));

		if(f)
		{
			for(int exp = 0; exp < 8; exp++)
			{
				double f1,f2,f3;

				f1 = m_ctlRollup.GetItem(0)->pSizes[exp];
				f2 = m_ctlRollup.GetItem(1)->pSizes[exp];
				f3 = m_ctlRollup.GetItem(2)->pSizes[exp];

				// get rid off some rounding errors: ///
				if(f3)
					f3 = f1 ? (f2 ? (100 - f1 - f2) : (100 - f1)) : (100 - f2);
				else if(f2)
					f2 = 100 - f1;
				////////////////////////////////////////

				fprintf(f, "%f|%f|%f\n", f1, f2, f3);
			}
			fprintf( f, "%u|%u|%u\n",
					m_ctlRollup.GetItem(0)->pHeader->IsExpanded(),
					m_ctlRollup.GetItem(1)->pHeader->IsExpanded(),
					m_ctlRollup.GetItem(2)->pHeader->IsExpanded() );
			fclose(f);
		}
	}
}

BOOL CTransferWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	NMHDR* pNMHDR = (NMHDR*)lParam;

	if (pNMHDR->hwndFrom == m_dlTab.GetSafeHwnd())
	{
		switch(pNMHDR->code)
		{
			case NM_RCLICK:
				OnNMRclickDltab(pNMHDR, pResult);
				break;
			case NM_DBLCLK:
			case WM_LBUTTONDBLCLK:
				OnDblclickDltab();
				break;
			case TCN_SELCHANGE:
				OnTcnSelchangeDltab(pNMHDR, pResult);
				break;
		}
	}
	else if(pNMHDR->hwndFrom == downloadlistctrl.GetSafeHwnd())
	{
		switch(pNMHDR->code)
		{
			case LVN_BEGINDRAG:
				OnLvnBegindrag(pNMHDR, pResult);
				break;
		}
	}

	return CResizableDialog::OnNotify(wParam, lParam, pResult);
}

void CTransferWnd::OnDestroy()
{	
	if(m_pwndDummyForDownloadList)
	{
		m_pwndDummyForDownloadList->DestroyWindow();
		delete m_pwndDummyForDownloadList;
	}
	CResizableDialog::OnDestroy();
}

void CTransferWnd::UpdateDownloadHeader()
{	
	CString strBuffer;

//==> GlobalSources in RollUps
	CDownloadQueue::SDownloadStats myStats;
	theApp.downloadqueue->GetDownloadSourcesStats(myStats);
//<== GlobalSources in RollUps

	theApp.downloadqueue->FileStatsCount();

		strBuffer.Format(GetResString(IDS_RUP_DOWNINFO), 
		theApp.downloadqueue->GetFileCount(),
		theApp.downloadqueue->GetDownloadingFileCount(),
		theApp.downloadqueue->GetTransferingCount(),
		theApp.downloadqueue->GetStoppedCount(),

//==> GlobalSources in RollUps
			myStats.a[0],
//<== GlobalSources in RollUps
			static_cast<double>(theApp.downloadqueue->GetDatarate()/1024.0));

	m_ctlRollup.SetText(0, strBuffer);
}

void CTransferWnd::UpdateUploadHeader()
{	
	CString strBuffer;

		strBuffer.Format(GetResString(IDS_RUP_UPINFO),
			theApp.uploadqueue->GetWaitingUserCount(),
			theApp.uploadqueue->GetUploadQueueLength(),
			theApp.clientlist->GetBannedCount(),
			static_cast<double>(theApp.uploadqueue->GetDatarate())/1024.0);

	m_ctlRollup.SetText(1, strBuffer);
}

void CTransferWnd::UpdateExtendedHeader()
{	
	switch (m_nActiveExtWnd)
	{
		case EPW_LIST1:
		{
			CString strBuffer;

			strBuffer.Format(GetResString(IDS_RUP_EXTINFO),
				downloadclientsctrl.GetItemCount(),
				static_cast<double>(theApp.downloadqueue->GetDatarate()) / 1024.0
				);

			m_ctlRollup.SetText(2, strBuffer);			
			break;
		}
		case EPW_LIST2:
		{

			break;
		}
	}
}

BOOL CTransferWnd::OnEraseBkgnd(CDC* pDC)
{
	CRect rect;
	GetClientRect( rect );
	COLORREF WS=RGB(255,255,255); 
	pDC->FillSolidRect( &rect, WS );

	return TRUE;
}
//<== dlarge RollUps

//==> NextEMF New Tooltips [Rayita]
int CTransferWnd::GetClientImage(CUpDownClient* client)
{
	if (client->IsFriend())
		return 6;
	int iImage = 0;
	switch(client->GetClientSoft())
	{
		case SO_EDONKEY:
			iImage = 7;
			break;
		case SO_MLDONKEY:
			iImage = 8;
			break;
		case SO_EDONKEYHYBRID:
			iImage = 9;
			break;
		case SO_SHAREAZA:
			iImage = 10;
			break;
		case SO_AMULE:
			iImage = 11;
			break;
		case SO_LPHANT:
			iImage = 12;
			break;
		default:
			if (client->ExtProtocolAvailable())
				iImage = 5;
			else
				iImage = 4;
	}

	return iImage;
	}

void CTransferWnd::UpdateToolTips(void)
{
	
	// Update tooltips for Category tabs
	CPoint		point;
	bool		bPop = true;

	::GetCursorPos(&point);

	int iSel = GetTabUnderMouse(&point);

	// Update tooltips for Download List
	CListCtrl	*pListCtrl = &downloadlistctrl;

	iSel = GetItemUnderMouse(pListCtrl);	
	if (iSel != -1)
	{
		bPop = false;
		if (iSel != m_iOldToolTipItemDownload) 
		{
			if (m_ttip.IsWindowVisible())
				m_ttip.UpdateData();
			m_iOldToolTipItemDownload = iSel;
			return;
		}
	}

	//	Update tooltips for Upload List
	pListCtrl = &uploadlistctrl;
	iSel = GetItemUnderMouse(pListCtrl);
	if (iSel != -1)
	{
		bPop = false;
		if (iSel != m_iOldToolTipItemUpload)
		{
			if (m_ttip.IsWindowVisible())
				m_ttip.UpdateData();
			m_iOldToolTipItemUpload = iSel;
			return;
		}
	}

	//	Update tooltips for Queue List
	pListCtrl = &queuelistctrl;
	iSel = GetItemUnderMouse(pListCtrl);
	if (iSel != -1)
	{
		bPop = false;
		if (iSel != m_iOldToolTipItemQueue)
		{
			if (m_ttip.IsWindowVisible())
				m_ttip.UpdateData();
			m_iOldToolTipItemQueue = iSel;
			return;
		}
	}

	//	Update tooltips for Clients List
	pListCtrl = &clientlistctrl;
	iSel = GetItemUnderMouse(pListCtrl);
	if (iSel != -1)
	{
		bPop = false;
		if (iSel != m_iOldToolTipItemClients)
		{
			if (m_ttip.IsWindowVisible())
				m_ttip.UpdateData();
			m_iOldToolTipItemClients = iSel;
			return;
		}
	}

	if (bPop)
		m_ttip.Pop();
}

BOOL CTransferWnd::OnToolTipNotify(UINT /*id*/, NMHDR *pNMH, LRESULT* /*pResult*/)
{
	NM_PPTOOLTIP_DISPLAY	*pNotify = (NM_PPTOOLTIP_DISPLAY*)pNMH;
	int						control_id = CWnd::FromHandle(pNotify->ti->hWnd)->GetDlgCtrlID();

	if (control_id == NULL)
		return FALSE;

	CString info;

	switch (control_id)
	{
		case TRANS_DOWNLOADTABS:
			{
			return TRUE;
			}
		case TRANS_DOWNLOADLIST:
			{

				DWORD_PTR pItem;

				if (downloadlistctrl.GetItemCount() < 1)
					return FALSE;

				int	iSel = GetItemUnderMouse(&downloadlistctrl);

				if (iSel < 0)
					return FALSE;

				pItem = downloadlistctrl.GetItemData(iSel);
				
				// build info text and display it
				CtrlItem_Struct* pContent = (CtrlItem_Struct*)pItem;
					if (!pContent->value) return FALSE;
				if(pContent->type == FILE_TYPE)	// for downloading files
				{
					CPartFile* partfile = (CPartFile*)pContent->value;

					partfile->GetTooltipFileInfo(info);

					SHFILEINFO shfi;
						memset(&shfi,0, sizeof(shfi));
					SHGetFileInfo(partfile->GetFileName(), FILE_ATTRIBUTE_NORMAL, &shfi, sizeof(shfi), SHGFI_ICON|SHGFI_USEFILEATTRIBUTES);
					pNotify->ti->hIcon = shfi.hIcon;

					downloadlistctrl.SetFocus();
				}
				else if (pContent->type == AVAILABLE_SOURCE || pContent->type == UNAVAILABLE_SOURCE) // for sources
				{
					CUpDownClient* client = (CUpDownClient*)pContent->value;

					pNotify->ti->hIcon = m_ImageList.ExtractIcon(GetClientImage(client));

					client->GetTooltipDownloadInfo(info, pContent->type == UNAVAILABLE_SOURCE, pContent->owner);
				}

				break;
			}
		case TRANS_UPLOADLIST:
			{
				if (uploadlistctrl.GetItemCount() < 1)
					return FALSE;

				int	iSel = GetItemUnderMouse(&uploadlistctrl);

				if (iSel < 0)
					return FALSE;

				CUpDownClient* pSource = (CUpDownClient*)uploadlistctrl.GetItemData(iSel);
				pNotify->ti->hIcon = m_ImageList.ExtractIcon(GetClientImage(pSource));
				pSource->GetTooltipUploadInfo(info, true);
				break;
			}
		case TRANS_QUEUELIST:
			{
				if (queuelistctrl.GetItemCount() < 1)
					return FALSE;

				int	iSel = GetItemUnderMouse(&queuelistctrl);

				if (iSel < 0)
					return FALSE;

				CUpDownClient* pSource = (CUpDownClient*)queuelistctrl.GetItemData(iSel);
				pNotify->ti->hIcon = m_ImageList.ExtractIcon(GetClientImage(pSource));
				pSource->GetTooltipQueueInfo(info);
				break;
			}
		case TRANS_CLIENTLIST:
			{
				if (clientlistctrl.GetItemCount() < 1)
					return FALSE;
				
				int iSel = clientlistctrl.GetItemUnderMouse();

				if (iSel < 0)
					return FALSE;

				CUpDownClient* pSource = (CUpDownClient*)clientlistctrl.GetItemData(iSel);
				pNotify->ti->hIcon = m_ImageList.ExtractIcon(GetClientImage(pSource));
				pSource->GetTooltipClientInfo(info);
				break;
			}
	}

//	SetDlgItemFocus(control_id);
	pNotify->ti->sTooltip = info;

	return TRUE;
}

void CTransferWnd::SetDlgItemFocus(int nID)
{
	GetDlgItem(nID)->SetFocus();
}

void CTransferWnd::SetTTDelay()
{
	m_ttip.SetDelayTime(TTDT_AUTOPOP, 20000);
	m_ttip.SetDelayTime(TTDT_INITIAL, thePrefs.GetToolTipDelay() * 500);
	m_tabtip.SetDelayTime(TTDT_AUTOPOP, 40000);
	m_tabtip.SetDelayTime(TTDT_INITIAL, thePrefs.GetToolTipDelay() * 500);
	//m_othertips.SetDelayTime(TTDT_AUTOPOP, 20000);
	//m_othertips.SetDelayTime(TTDT_INITIAL, thePrefs.GetToolTipDelay() * 500);
}
//<== NextEMF New Tooltips [Rayita]
