// This file is a part of the xMule Project.
//
// Copyright (c) 2004 Theodore R. Smith (hopeseekr@xmule.ws / http://www.xmule.ws/)
// DSA-1024 Fingerprint: 10A0 6372 9092 85A2 BB7F 907B CB8B 654B E33B F1ED
//
// Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.xmule-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.

// QueueListCtrl.cpp : implementation file

#ifdef PRECOMP
#	include "xmule-headers.h"
#else
#	include "ChatWnd.h"
#include "ClientCredits.h"                  // CClientCredits
#	include "ClientDetailDialog.h"
#	include "FriendList.h"
#	include "KnownFile.h"
#	include "muuli_wdr.h"
#	include "opcodes.h"
#	include "otherfunctions.h"
#include "otherstructs.h"                   // ServerMet_Struct - audited 5 Nov 2004
#include "PartFile.h"                       // Needed for PR_VERYHIGH - audited 5 Nov 2004
#include "Preferences.h"                    // CPreferences::List Settings
#	include "QueueListCtrl.h"
#	include "SharedFileList.h"
#	include "TransferWnd.h"
#include "updownclient.h"                   // Needed for CUpDownClient - audited 5 Nov 2004
#	include "UploadQueue.h"
#	include "wintypes.h"
#	include "xmule.h"
#	include "xmuleDlg.h"
#endif

#include <DynPrefs/DynPrefs.h>              // Needed for DynamicPreferences

#include <wx/menu.h>                        // Needed for wxMenu

#define SYSCOLOR(x) (wxSystemSettings::GetColour(x))

// images
#include "pixmaps/neutral.ico.xpm"
#include "pixmaps/compatible.ICO.xpm"
#include "pixmaps/plus.ICO.xpm"
#include "pixmaps/pluscompa.ICO.xpm"
#include "pixmaps/Friend.ico.xpm"
#include "pixmaps/mldonk.ico.xpm"
#include "pixmaps/plusmldonk.ico.xpm"
#include "pixmaps/eDonkeyHybrid.ico.xpm"
#include "pixmaps/pluseDonkeyHybrid.ico.xpm"
#include "pixmaps/thief.ico.xpm"

// CQueueListCtrl

//IMPLEMENT_DYNAMIC(CQueueListCtrl, CMuleListCtrl)
BEGIN_EVENT_TABLE(CQueueListCtrl, CMuleListCtrl)
    EVT_RIGHT_DOWN(CQueueListCtrl::OnNMRclick)
    EVT_LIST_COL_CLICK(ID_QUEUELIST, CQueueListCtrl::OnColumnClick)
    EVT_TIMER(2349, CQueueListCtrl::OnTimer)
END_EVENT_TABLE()

CQueueListCtrl::CQueueListCtrl()
{
}

CQueueListCtrl::CQueueListCtrl(wxWindow *&parent, int id, const wxPoint &pos, wxSize siz, int flags)
: CMuleListCtrl(parent, id, pos, siz, flags |wxLC_OWNERDRAW)
{
    m_ClientMenu = NULL;
    wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
    wxColour newcol = wxColour(((int) col.Red() *125) /100,
    ((int) col.Green() *125) /100,
    ((int) col.Blue() *125) /100);
    m_hilightBrush = new wxBrush(newcol, wxSOLID);
    col = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
    newcol = wxColour(((int) col.Red() *125) /100,
    ((int) col.Green() *125) /100,
    ((int) col.Blue() *125) /100);
    m_hilightUnfocusBrush = new wxBrush(newcol, wxSOLID);
    Init();
    // load images
    // load images
    imagelist.Add(wxBitmap(neutral_ico));
    imagelist.Add(wxBitmap(compatible_ICO));
    imagelist.Add(wxBitmap(plus_ICO));
    imagelist.Add(wxBitmap(pluscompa_ICO));
    imagelist.Add(wxBitmap(Friend_ico));
    imagelist.Add(wxBitmap(mldonk_ico));
    imagelist.Add(wxBitmap(plusmldonk_ico));
    imagelist.Add(wxBitmap(eDonkeyHybrid_ico));
    imagelist.Add(wxBitmap(pluseDonkeyHybrid_ico));
    // Add Thief icon
    imagelist.Add(wxBitmap(thief_ico));
    m_hTimer.SetOwner(this, 2349);
    m_hTimer.Start(10000);
}

void CQueueListCtrl::InitSort()
{
    LoadSettings(CPreferences::tableQueue);
    // Barry - Use preferred sort order from preferences
    int sortItem = theApp.glob_prefs->GetColumnSortItem(CPreferences::tableQueue);
    bool sortAscending = theApp.glob_prefs->GetColumnSortAscending(CPreferences::tableQueue);
    SetSortArrow(sortItem, sortAscending);
    SortItems(SortProc, sortItem + (sortAscending ? 0: 100));
}

// paha lametus :)
#define LVCFMT_LEFT wxLIST_FORMAT_LEFT

void CQueueListCtrl::Init()
{
    InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, 150);
    InsertColumn(1, GetResString(IDS_FILE), LVCFMT_LEFT, 275);
    InsertColumn(2, GetResString(IDS_FILEPRIO), LVCFMT_LEFT, 110);
    InsertColumn(3, GetResString(IDS_QL_RATING), LVCFMT_LEFT, 60);
    InsertColumn(4, GetResString(IDS_SCORE), LVCFMT_LEFT, 60);
    InsertColumn(5, GetResString(IDS_ASKED), LVCFMT_LEFT, 60);
    InsertColumn(6, GetResString(IDS_LASTSEEN), LVCFMT_LEFT, 110);
    InsertColumn(7, GetResString(IDS_ENTERQUEUE), LVCFMT_LEFT, 110);
    InsertColumn(8, GetResString(IDS_BANNED), LVCFMT_LEFT, 60);
    InsertColumn(9, GetResString(IDS_UPSTATUS), LVCFMT_LEFT, 100);
#if 0
    // something that can't be done here and now. moved to InitSort()
    // Barry - Use preferred sort order from preferences
    int sortItem = theApp.glob_prefs->GetColumnSortItem(CPreferences::tableQueue);
    bool sortAscending = theApp.glob_prefs->GetColumnSortAscending(CPreferences::tableQueue);
    SetSortArrow(sortItem, sortAscending);
    SortItems(SortProc, sortItem + (sortAscending ? 0: 10));
#endif
#if 0
    SetExtendedStyle(LVS_EX_FULLROWSELECT);
    InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, 150, 0);
    InsertColumn(1, GetResString(IDS_FILE), LVCFMT_LEFT, 275, 1);
    InsertColumn(2, GetResString(IDS_FILEPRIO), LVCFMT_LEFT, 110, 2);
    InsertColumn(3, GetResString(IDS_QL_RATING), LVCFMT_LEFT, 60, 3);
    InsertColumn(4, GetResString(IDS_SCORE), LVCFMT_LEFT, 60, 4);
    InsertColumn(5, GetResString(IDS_ASKED), LVCFMT_LEFT, 60, 5);
    InsertColumn(6, GetResString(IDS_LASTSEEN), LVCFMT_LEFT, 110, 6);
    InsertColumn(7, GetResString(IDS_ENTERQUEUE), LVCFMT_LEFT, 110, 7);
    InsertColumn(8, GetResString(IDS_BANNED), LVCFMT_LEFT, 60, 8);
    imagelist.Create(16, 16, ILC_COLOR32 |ILC_MASK, 0, 10);
    imagelist.SetBkColor(RGB(255, 255, 255));
    imagelist.Add(theApp.LoadIcon(IDI_USER0));
    imagelist.Add(theApp.LoadIcon(IDI_COMPPROT));
    imagelist.Add(theApp.LoadIcon(IDI_PLUS));
    imagelist.Add(theApp.LoadIcon(IDI_PLUSCOMPROT));
    SetImageList( &imagelist, LVSIL_SMALL);
    m_ClientMenu.CreatePopupMenu();
    m_ClientMenu.AddMenuTitle(GetResString(IDS_CLIENTS));
    m_ClientMenu.AppendMenu(MF_STRING, MP_DETAIL, GetResString(IDS_SHOWDETAILS));
    m_ClientMenu.AppendMenu(MF_STRING, MP_MESSAGE, GetResString(IDS_SEND_MSG));
    m_ClientMenu.AppendMenu(MF_STRING, MP_UNBAN, GetResString(IDS_UNBAN));
    m_ClientMenu.AppendMenu(MF_SEPARATOR);
    m_ClientMenu.AppendMenu(MF_STRING, MP_SWITCHCTRL, GetResString(IDS_VIEWUPLOADS));
    SetMenu( &m_ClientMenu);
    LoadSettings(CPreferences::tableQueue);
#endif
}

CQueueListCtrl::~CQueueListCtrl()
{
    m_hTimer.Stop();
    delete m_hilightBrush;
    delete m_hilightUnfocusBrush;
}

void CQueueListCtrl::OnNMRclick(wxMouseEvent &evt)
{
    // Check if clicked item is selected. If not, unselect all and select it.
    long item = - 1;
    int lips = 0;
    int index = HitTest(evt.GetPosition(), lips);
    if (!GetItemState(index, wxLIST_STATE_SELECTED))
    {
        for ( ; ;)
        {
            item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
            if (item == - 1) break;
            SetItemState(item, 0, wxLIST_STATE_SELECTED);
        }
        SetItemState(index, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
    }
    if (m_ClientMenu == NULL)
    {
        wxMenu *menu = new wxMenu(GetResString(IDS_CLIENTS));
        menu->Append(MP_DETAIL, GetResString(IDS_SHOWDETAILS));
        menu->Append(MP_ADDFRIEND, GetResString(IDS_ADDFRIEND));
        menu->Append(MP_MESSAGE, GetResString(IDS_SEND_MSG));
        menu->Append(MP_UNBAN, GetResString(IDS_UNBAN));
        menu->Append(MP_SHOWLIST, GetResString(IDS_VIEWFILES));
        menu->AppendSeparator();
        menu->Append(MP_SWITCHCTRL, GetResString(IDS_VIEWUPLOADS));
        m_ClientMenu = menu;
    }
    PopupMenu(m_ClientMenu, evt.GetPosition());
}

void CQueueListCtrl::Localize()
{
#if 0
    CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
    HDITEM hdi;
    hdi.mask = HDI_TEXT;
    if (pHeaderCtrl->GetItemCount() != 0)
    {
        wxString strRes;
        strRes = GetResString(IDS_QL_USERNAME);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(0, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_FILE);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(1, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_FILEPRIO);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(2, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_QL_RATING);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(3, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_SCORE);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(4, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_ASKED);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(5, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_LASTSEEN);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(6, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_ENTERQUEUE);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(7, &hdi);
        strRes.ReleaseBuffer();
        strRes = GetResString(IDS_BANNED);
        hdi.pszText = strRes.GetBuffer();
        pHeaderCtrl->SetItem(8, &hdi);
        strRes.ReleaseBuffer();
    }
#endif
}

void CQueueListCtrl::AddClient(CUpDownClient *client)
{
    uint32_t itemnr = GetItemCount();
    itemnr = InsertItem(itemnr, client->GetUserName());
    SetItemData(itemnr, (long) client);
    wxListItem myitem;
    myitem.m_itemId = itemnr;
    myitem.SetBackgroundColour(SYSCOLOR(wxSYS_COLOUR_LISTBOX));
    SetItem(myitem);
    RefreshClient(client);
}

void CQueueListCtrl::RemoveClient(CUpDownClient *client)
{
    int32_t itemnr = FindItem( - 1, (long) client);
    if (itemnr != ( - 1))
    DeleteItem(itemnr);
}

void CQueueListCtrl::RefreshClient(CUpDownClient *client)
{
    int16_t result = FindItem( - 1, (long) client);
    if (result != - 1)
    {
        long first, last;
        first = last = 0;
        GetVisibleLines( &first, &last);
        if (result >= first &&result <= last)
        {
            RefreshItems(result, result);
        }
    }
}

void CQueueListCtrl::OnDrawItem(int item, wxDC *dc, const wxRect &rect, const wxRect &rectHL, bool highlighted)
{
    /* Don't do any drawing if there's nobody watching. */
    if ((!theApp.xmuledlg->transferwnd->windowtransferstate) || (theApp.xmuledlg->GetActiveDialog() != 2))
    {
        return;
    }
    if (!theApp.xmuledlg->IsRunning())
    return;
    if (highlighted)
    {
        if (GetFocus())
        {
            dc->SetBackground( *m_hilightBrush);
            dc->SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
        }
        else
        {
            dc->SetBackground( *m_hilightUnfocusBrush);
            dc->SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
        }
    }
    else
    {
        dc->SetBackground( * (wxTheBrushList->FindOrCreateBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX), wxSOLID)));
        dc->SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
    }
    // fill it
    wxPen mypen;
    if (highlighted)
    {
        // set pen so that we'll get nice border
        wxColour old = GetFocus() ?m_hilightBrush->GetColour(): m_hilightUnfocusBrush->GetColour();
        wxColour newcol = wxColour(((int) old.Red() *65) /100,
        ((int) old.Green() *65) /100,
        ((int) old.Blue() *65) /100);
        mypen = wxPen(newcol, 1, wxSOLID);
        dc->SetPen(mypen);
    }
    else
    {
        dc->SetPen( *wxTRANSPARENT_PEN);
    }
    dc->SetBrush(dc->GetBackground());
    dc->DrawRectangle(rectHL);
    dc->SetPen( *wxTRANSPARENT_PEN);
    // then stuff from original xmule
    //lpDrawItemStruct->itemData;:
    CUpDownClient *client = (CUpDownClient *) GetItemData(item);
    //CMemDC dc(CDC::FromHandle(lpDrawItemStruct->hDC),&CRect(lpDrawItemStruct->rcItem));
    //dc.SelectObject(GetFont());
    //COLORREF crOldTextColor = dc->GetTextColor();
    //COLORREF crOldBkColor = dc->GetBkColor();
    RECT cur_rec;
    //memcpy(&cur_rec,&lpDrawItemStruct->rcItem,sizeof(RECT));
    cur_rec.left = rect.x;
    cur_rec.top = rect.y;
    cur_rec.right = rect.x + rect.width;
    cur_rec.bottom = rect.y + rect.height;
    wxString Sbuffer;
    //	char buffer[100];
    CKnownFile *file = theApp.sharedfiles->GetFileByID(client->GetUploadFileID());
    //CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
    // pHeaderCtrl->GetItemCount();:
    int iCount = GetColumnCount();
    cur_rec.right = cur_rec.left - 8;
    cur_rec.left += 4;
    for (int iCurrent = 0 ; iCurrent < iCount ; iCurrent++)
    {
        //pHeaderCtrl->OrderToIndex(iCurrent);:
        int iColumn = iCurrent;
        if (1)
        {
            // columns can't be hidden
            wxListItem listitem;
            GetColumn(iColumn, listitem);
            int cx = listitem.GetWidth();
            //GetColumnWidth(iColumn);:
            cur_rec.right += cx;
            wxDCClipper *clipper = new wxDCClipper( *dc, cur_rec.left, cur_rec.top, cur_rec.right - cur_rec.left,
            cur_rec.bottom - cur_rec.top);
            switch (iColumn)
            {
            case 0:
                {
                    uint8_t image;
                    if (client->IsFriend())
                    image = 4;
                    else if(client->ExtProtocolAvailable())
                    {
                        if (client->Credits()->GetScoreRatio(client->GetIP()) > 1)
                        image = 3;
                        else
                        image = 1;
                    }
                    else
                    {
                        if (client->GetClientSoft() == SO_MLDONKEY || client->GetClientSoft() == SO_NEW_MLDONKEY)
                        {
                            if (client->Credits()->GetScoreRatio(client->GetIP()) > 1)
                            image = 6;
                            else
                            image = 5;
                        }
                        else if(client->GetClientSoft() == SO_EDONKEYHYBRID)
                        {
                            if (client->Credits()->GetScoreRatio(client->GetIP()) > 1)
                            image = 8;
                            else
                            image = 7;
                        }
                        else
                        {
                            if (client->Credits()->GetScoreRatio(client->GetIP()) > 1)
                            image = 2;
                            else
                            image = 0;
                        }
                    }
                    // Added Thief Icon [BlackRat]
                    if (client->thief)
                    image = 9;
                    POINT point =
                    {
                        cur_rec.left, cur_rec.top + 1
                                        };
                    //imagelist.Draw(dc,image, point, ILD_NORMAL);
                    imagelist.Draw(image, *dc, cur_rec.left, cur_rec.top + 1, wxIMAGELIST_DRAW_TRANSPARENT);
                    Sbuffer.Printf("%s", client->GetUserName());
                    cur_rec.left += 20;
                    dc->DrawText(Sbuffer, cur_rec.left, cur_rec.top + 3);
                    cur_rec.left -= 20;
                    break;
                }
            case 1:
                if (file)
                Sbuffer.Printf("%s", file->GetFileName());
                else
                Sbuffer = "?";
                break;
            case 2:
                if (file)
                {
                    switch (file->GetUpPriority())
                    {
                    case PR_VERYHIGH:
                        Sbuffer.Printf("%s", GetResString(IDS_PRIORELEASE) .GetData());
                        break;
                    case PR_HIGH:
                        Sbuffer.Printf("%s", GetResString(IDS_PRIOHIGH) .GetData());
                        break;
                    case PR_LOW:
                        Sbuffer.Printf("%s", GetResString(IDS_PRIOLOW) .GetData());
                        break;
                    case PR_VERYLOW:
                        Sbuffer.Printf("%s", GetResString(IDS_PRIOVERYLOW) .GetData());
                        break;
                    default:
                        Sbuffer.Printf("%s", GetResString(IDS_PRIONORMAL) .GetData());
                        break;
                    }
                }
                else
                Sbuffer = "?";
                break;
            case 3:
                Sbuffer.Printf("%.1f", (float) client->GetScore(false, false, true));
                break;
            case 4:
                Sbuffer.Printf("%i", client->GetScore(false));
                break;
            case 5:
                Sbuffer.Printf("%i", client->GetAskedCount());
                break;
            case 6:
                Sbuffer.Printf("%s", CastSecondsToHM((::GetTickCount() - client->GetLastUpRequest()) /1000) .GetData());
                break;
            case 7:
                Sbuffer.Printf("%s", CastSecondsToHM((::GetTickCount() - client->GetWaitStartTime()) /1000) .GetData());
                break;
            case 8:
                if (client->IsBanned())
                Sbuffer.Printf("%s", GetResString(IDS_YES) .GetData());
                else
                Sbuffer.Printf("%s", GetResString(IDS_NO) .GetData());
                break;
            case 9:
                if (client->GetUpPartCount())
                {
                    wxMemoryDC memdc;
                    cur_rec.bottom--;
                    cur_rec.top++;
                    int iWidth = cur_rec.right - cur_rec.left;
                    int iHeight = cur_rec.bottom - cur_rec.top;
                    wxBitmap memBmp(iWidth, iHeight);
                    memdc.SelectObject(memBmp);
                    memdc.SetPen( *wxTRANSPARENT_PEN);
                    memdc.SetBrush( *wxWHITE_BRUSH);
                    memdc.DrawRectangle(wxRect(0, 0, iWidth, iHeight));
                    client->DrawUpStatusBar( &memdc, wxRect(0, 0, iWidth, iHeight), false, false);
                    dc->Blit(cur_rec.left, cur_rec.top, iWidth, iHeight, &memdc, 0, 0);
                    memdc.SelectObject(wxNullBitmap);
                    cur_rec.bottom++;
                    cur_rec.top--;
                }
                break;
            }
            if (iColumn != 9 &&iColumn != 0)
            //dc->DrawText(Sbuffer,Sbuffer.GetLength(),&cur_rec,DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX|DT_END_ELLIPSIS);
            dc->DrawText(Sbuffer, cur_rec.left, cur_rec.top + 3);
            //GetColumnWidth(iColumn);:
            cur_rec.left += cx;
            delete clipper;
        }
    }
}

#if 0
BEGIN_MESSAGE_MAP(CQueueListCtrl, CMuleListCtrl)
ON_NOTIFY_REFLECT(NM_RCLICK, OnNMRclick)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
END_MESSAGE_MAP()
#endif

#if 0
// CQueueListCtrl message handlers
void CQueueListCtrl::OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult)
{
    POINT point;
    ::GetCursorPos( &point);
    m_ClientMenu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this);
    *pResult = 0;
}

#endif

bool CQueueListCtrl::ProcessEvent(wxEvent &evt)
{
    if (evt.GetEventType() != wxEVT_COMMAND_MENU_SELECTED)
    return CMuleListCtrl::ProcessEvent(evt);
    wxCommandEvent &event = (wxCommandEvent &) evt;
    int cursel = GetNextItem( - 1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
    if (cursel != ( - 1))
    {
        CUpDownClient *client = (CUpDownClient *) GetItemData(cursel);
        switch (event.GetId())
        {
        case MP_SHOWLIST:
            client->RequestSharedFileList();
            break;
        case MP_MESSAGE:
            {
                theApp.xmuledlg->chatwnd->StartSession(client);
                break;
            }
        case MP_ADDFRIEND:
            {
                theApp.friendlist->AddFriend(client);
                break;
            }
        case MP_UNBAN:
            {
                if (client->IsBanned())
                client->UnBan();
                break;
            }
        case MP_DETAIL:
            {
                CClientDetailDialog *dialog = new CClientDetailDialog(this, client);
                dialog->ShowModal();
                delete dialog;
                return TRUE;
                break;
            }
        }
    }
    switch (event.GetId())
    {
    case MP_SWITCHCTRL:
        {
            //((CTransferWnd*)GetParent())->SwitchUploadList();
            theApp.xmuledlg->transferwnd->SwitchUploadList(event);
            break;
        }
    }
    return CMuleListCtrl::ProcessEvent(evt);
}

void CQueueListCtrl::OnColumnClick(wxListEvent &evt)
{
    //NMHDR* pNMHDR, LRESULT* pResult){
    //	theApp.uploadqueue->ResetClientPos();
    CUpDownClient *update = theApp.uploadqueue->GetNextClient(NULL);
    while (update)
    {
        RefreshClient(update);
        update = theApp.uploadqueue->GetNextClient(update);
    }
    // Barry - Store sort order in preferences
    // Determine ascending based on whether already sorted on this column
    int sortItem = theApp.glob_prefs->GetColumnSortItem(CPreferences::tableQueue);
    bool m_oldSortAscending = theApp.glob_prefs->GetColumnSortAscending(CPreferences::tableQueue);
    bool sortAscending = (sortItem != evt.GetColumn()) ? true: !m_oldSortAscending;
    // Item is column clicked
    sortItem = evt.GetColumn();
    // Save new preferences
    theApp.glob_prefs->SetColumnSortItem(CPreferences::tableQueue, sortItem);
    theApp.glob_prefs->SetColumnSortAscending(CPreferences::tableQueue, sortAscending);
    // Sort table
    SetSortArrow(sortItem, sortAscending);
    SortItems(SortProc, sortItem + (sortAscending ? 0: 100));
}

int CQueueListCtrl::SortProc(long lParam1, long lParam2, long lParamSort)
{
    CUpDownClient *item1 = (CUpDownClient *) lParam1;
    CUpDownClient *item2 = (CUpDownClient *) lParam2;
    CKnownFile *file1 = theApp.sharedfiles->GetFileByID(item1->GetUploadFileID());
    CKnownFile *file2 = theApp.sharedfiles->GetFileByID(item2->GetUploadFileID());
    switch (lParamSort)
    {
    case 0:
        return wxString(item1->GetUserName()) .CmpNoCase(item2->GetUserName());
    case 100:
        return wxString(item2->GetUserName()) .CmpNoCase(item1->GetUserName());
    case 1:
        if ((file1 != NULL) && (file2 != NULL))
        return wxString(file1->GetFileName()) .CmpNoCase(file2->GetFileName());
        else if(file1 == NULL)
        return 1;
        else
        return 0;
    case 101:
        if ((file1 != NULL) && (file2 != NULL))
        return wxString(file2->GetFileName()) .CmpNoCase(file1->GetFileName());
        else if(file1 == NULL)
        return 1;
        else
        return 0;
    case 2:
        if ((file1 != NULL) && (file2 != NULL))
        return file1->GetUpPriority() - file2->GetUpPriority();
        else if(file1 == NULL)
        return 1;
        else
        return 0;
    case 102:
        if ((file1 != NULL) && (file2 != NULL))
        return file2->GetUpPriority() - file1->GetUpPriority();
        else if(file1 == NULL)
        return 1;
        else
        return 0;
    case 3:
        return(int)((float) item1->GetScore(false, false, true) - (float) item2->GetScore(false, false, true));
    case 103:
        return(int)((float) item2->GetScore(false, false, true) - (float) item1->GetScore(false, false, true));
    case 4:
        return item1->GetScore(false) - item2->GetScore(false);
    case 104:
        return item2->GetScore(false) - item1->GetScore(false);
    case 5:
        return item1->GetAskedCount() - item2->GetAskedCount();
    case 105:
        return item2->GetAskedCount() - item1->GetAskedCount();
    case 6:
        return item1->GetLastUpRequest() - item2->GetLastUpRequest();
    case 106:
        return item2->GetLastUpRequest() - item1->GetLastUpRequest();
    case 7:
        return item1->GetWaitStartTime() - item2->GetWaitStartTime();
    case 107:
        return item2->GetWaitStartTime() - item1->GetWaitStartTime();
    case 8:
        return item1->IsBanned() - item2->IsBanned();
    case 108:
        return item2->IsBanned() - item1->IsBanned();
    default:
        return 0;
    }
}

void CQueueListCtrl::OnTimer(wxTimerEvent &evt)
{
    // Don't do anything if the app is shutting down - can cause unhandled exceptions
    if (!theApp.xmuledlg->IsRunning() || theApp.dynprefs->Get<bool>("realtime-queue") == false)
	{
		return;
	}

	CUpDownClient *update = theApp.uploadqueue->GetNextClient(NULL);
    while (update)
    {
        theApp.xmuledlg->transferwnd->queuelistctrl->RefreshClient(update);
        update = theApp.uploadqueue->GetNextClient(update);
    }
}

// Barry - Refresh the queue every 10 secs
//HWND hwnd, UINT uiMsg, UINT idEvent, DWORD dwTime):
void CQueueListCtrl::QueueUpdateTimer()
{
    // Don't do anything if the app is shutting down - can cause unhandled exceptions
    if (!theApp.xmuledlg->IsRunning() || theApp.dynprefs->Get<bool>("realtime-queue") == false)
	{
		return;
	}

    CUpDownClient *update = theApp.uploadqueue->GetNextClient(NULL);
    while (update)
    {
        theApp.xmuledlg->transferwnd->queuelistctrl->RefreshClient(update);
        update = theApp.uploadqueue->GetNextClient(update);
    }
}

void CQueueListCtrl::ShowSelectedUserDetails()
{
    if (GetSelectedItemCount() > 0)
    {
        int sel = GetNextItem( - 1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        CUpDownClient *client = (CUpDownClient *) GetItemData(sel);
        if (client)
        {
            CClientDetailDialog dialog(this, client);
            dialog.ShowModal();
        }
    }
}

