// 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.

#ifdef PRECOMP
#	include "xmule-headers.h"
#else
#	include "CommentDialog.h"
#	include "muuli_wdr.h"
#	include "otherfunctions.h"
#include "PartFile.h"                       // Needed for PR_NORMAL - audited 5 Nov 2004
#include "Preferences.h"                    // CPreferences::List Settings
#	include "SharedFilesCtrl.h"
#	include "SharedFilesWnd.h"
#	include "xmule.h"
#	include "xmuleDlg.h"
#endif

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

#include <wx/msgdlg.h>                      // Needed for wxMessageBox
#include <wx/stattext.h>                    // wxStaticText

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

//IMPLEMENT_DYNAMIC(CSharedFilesCtrl, CMuleListCtrl)

BEGIN_EVENT_TABLE(CSharedFilesCtrl, CMuleListCtrl)
    EVT_LIST_ITEM_RIGHT_CLICK(ID_SHFILELIST, CSharedFilesCtrl::OnNMRclick)
    EVT_LIST_COL_CLICK(ID_SHFILELIST, CSharedFilesCtrl::OnColumnClick)
END_EVENT_TABLE()

CSharedFilesCtrl::CSharedFilesCtrl()
{
    // i_a:
    sflist = 0;
    // i_a:
    memset( &sortstat, 0, sizeof(sortstat));
}

CSharedFilesCtrl::~CSharedFilesCtrl()
{
}

CSharedFilesCtrl::CSharedFilesCtrl(wxWindow *&parent, int id, const wxPoint &pos, wxSize siz, int flags)
: CMuleListCtrl(parent, id, pos, siz, flags |wxLC_OWNERDRAW)
{
    // i_a:
    sflist = 0;
    // i_a:
    memset( &sortstat, 0, sizeof(sortstat));
    m_SharedFilesMenu = NULL;
    Init();
}

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

#define LVCFMT_LEFT wxLIST_FORMAT_LEFT

void CSharedFilesCtrl::Init()
{
    InsertColumn(0, GetResString(IDS_DL_FILENAME), LVCFMT_LEFT, 250);
    InsertColumn(1, GetResString(IDS_DL_SIZE), LVCFMT_LEFT, 100);
    InsertColumn(2, GetResString(IDS_TYPE), LVCFMT_LEFT, 50);
    InsertColumn(3, GetResString(IDS_PRIORITY), LVCFMT_LEFT, 70);
    InsertColumn(4, GetResString(IDS_PERMISSION), LVCFMT_LEFT, 100);
    InsertColumn(5, GetResString(IDS_FILEID), LVCFMT_LEFT, 220);
    InsertColumn(6, GetResString(IDS_SF_REQUESTS), LVCFMT_LEFT, 100);
    InsertColumn(7, GetResString(IDS_SF_ACCEPTS), LVCFMT_LEFT, 100);
    InsertColumn(8, GetResString(IDS_SF_TRANSFERRED), LVCFMT_LEFT, 120);
    InsertColumn(9, GetResString(IDS_UPSTATUS), LVCFMT_LEFT, 120);
#if 0
    SetExtendedStyle(LVS_EX_FULLROWSELECT);
    ModifyStyle(LVS_SINGLESEL, 0);
    InsertColumn(0, GetResString(IDS_DL_FILENAME), LVCFMT_LEFT, 250, 0);
    InsertColumn(1, GetResString(IDS_DL_SIZE), LVCFMT_LEFT, 100, 1);
    InsertColumn(2, GetResString(IDS_TYPE), LVCFMT_LEFT, 50, 2);
    InsertColumn(3, GetResString(IDS_PRIORITY), LVCFMT_LEFT, 70, 3);
    InsertColumn(4, GetResString(IDS_PERMISSION), LVCFMT_LEFT, 100, 4);
    InsertColumn(5, GetResString(IDS_FILEID), LVCFMT_LEFT, 220, 5);
    InsertColumn(6, GetResString(IDS_SF_REQUESTS), LVCFMT_LEFT, 100, 5);
    InsertColumn(7, GetResString(IDS_SF_ACCEPTS), LVCFMT_LEFT, 100, 5);
    InsertColumn(8, GetResString(IDS_SF_TRANSFERRED), LVCFMT_LEFT, 120, 5);
    m_SharedFilesMenu.CreatePopupMenu();
    m_SharedFilesMenu.AddMenuTitle(GetResString(IDS_SHAREDFILES));
    // add priority switcher
    m_PrioMenu.CreateMenu();
    m_PrioMenu.AppendMenu(MF_STRING, MP_PRIOVERYLOW, GetResString(IDS_PRIOVERYLOW));
    m_PrioMenu.AppendMenu(MF_STRING, MP_PRIOLOW, GetResString(IDS_PRIOLOW));
    m_PrioMenu.AppendMenu(MF_STRING, MP_PRIONORMAL, GetResString(IDS_PRIONORMAL));
    m_PrioMenu.AppendMenu(MF_STRING, MP_PRIOHIGH, GetResString(IDS_PRIOHIGH));
    m_PrioMenu.AppendMenu(MF_STRING, MP_PRIOVERYHIGH, GetResString(IDS_PRIORELEASE));
    // add permission switcher
    m_PermMenu.CreateMenu();
    m_PermMenu.AppendMenu(MF_STRING, MP_PERMNONE, GetResString(IDS_FSTATUS_LOCKED));
    m_PermMenu.AppendMenu(MF_STRING, MP_PERMFRIENDS, GetResString(IDS_FSTATUS_FRIENDSONLY));
    m_PermMenu.AppendMenu(MF_STRING, MP_PERMALL, GetResString(IDS_FSTATUS_PUBLIC));
    // todo enable when it works
    m_SharedFilesMenu.AppendMenu(MF_STRING |MF_POPUP, (UINT_PTR) m_PrioMenu.m_hMenu, GetResString(IDS_PRIORITY));
    //m_SharedFilesMenu.AppendMenu(MF_STRING|MF_POPUP,(UINT_PTR)m_PermMenu.m_hMenu, (LPCTSTR)"Permissions");
    m_SharedFilesMenu.AppendMenu(MF_STRING |MF_SEPARATOR);
    m_SharedFilesMenu.AppendMenu(MF_STRING, MP_OPEN, GetResString(IDS_OPENFILE));
    m_SharedFilesMenu.AppendMenu(MF_STRING, MP_GETED2KLINK, GetResString(IDS_DL_LINK1));
    m_SharedFilesMenu.AppendMenu(MF_STRING, MP_GETHTMLED2KLINK, GetResString(IDS_DL_LINK2));
    m_SharedFilesMenu.AppendMenu(MF_STRING, 123456789, GetResString(IDS_IRC_ADDLINKTOIRC));
    //This menu option is is for testing..
    LoadSettings(CPreferences::tableShared);
#endif
}

void CSharedFilesCtrl::OnNMRclick(wxListEvent &evt)
{
    // Check if clicked item is selected. If not, unselect all and select it.
    long item = - 1;
    if (!GetItemState(evt.GetIndex(), wxLIST_STATE_SELECTED))
    {
        for ( ; ;)
        {
            item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
            if (item == - 1) break;
            SetItemState(item, 0, wxLIST_STATE_SELECTED);
        }
        SetItemState(evt.GetIndex(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
    }
    if (m_SharedFilesMenu == NULL)
    {
        wxMenu *menu = new wxMenu(GetResString(IDS_SHAREDFILES));
        wxMenu *prioMenu = new wxMenu();
        prioMenu->AppendCheckItem(MP_PRIOVERYLOW, GetResString(IDS_PRIOVERYLOW));
        prioMenu->AppendCheckItem(MP_PRIOLOW, GetResString(IDS_PRIOLOW));
        prioMenu->AppendCheckItem(MP_PRIONORMAL, GetResString(IDS_PRIONORMAL));
        prioMenu->AppendCheckItem(MP_PRIOHIGH, GetResString(IDS_PRIOHIGH));
        prioMenu->AppendCheckItem(MP_PRIOVERYHIGH, GetResString(IDS_PRIORELEASE));
        prioMenu->AppendCheckItem(MP_PRIOAUTO, GetResString(IDS_PRIOAUTO));
        wxMenu *permMenu = new wxMenu();
        permMenu->AppendCheckItem(MP_PERMNONE, GetResString(IDS_FSTATUS_LOCKED));
        permMenu->AppendCheckItem(MP_PERMFRIENDS, GetResString(IDS_FSTATUS_FRIENDSONLY));
        permMenu->AppendCheckItem(MP_PERMALL, GetResString(IDS_FSTATUS_PUBLIC));
        menu->Append(438312, GetResString(IDS_PRIORITY), prioMenu);
        menu->Append(438313, _("Permissions"), permMenu);
        menu->AppendSeparator();
        menu->Append(MP_OPEN, GetResString(IDS_OPENFILE));
        //***Comments 11/27/03**//
        menu->Append(MP_CMT, GetResString(IDS_CMT_ADD));
        menu->AppendSeparator();
        //****end  comments***//
        menu->Append(MP_GETED2KLINK, GetResString(IDS_DL_LINK1));
        menu->Append(MP_GETHTMLED2KLINK, GetResString(IDS_DL_LINK2));
        menu->Append(123456789, GetResString(IDS_IRC_ADDLINKTOIRC));
        m_SharedFilesMenu = menu;
    }
    PopupMenu(m_SharedFilesMenu, evt.GetPoint());
}

void CSharedFilesCtrl::Localize()
{
#if 0
    CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
    HDITEM hdi;
    hdi.mask = HDI_TEXT;
    wxString strRes;
    strRes = GetResString(IDS_DL_FILENAME);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(0, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_DL_SIZE);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(1, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_TYPE);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(2, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_PRIORITY);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(3, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_PERMISSION);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(4, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_FILEID);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(5, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_SF_REQUESTS);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(6, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_SF_ACCEPTS);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(7, &hdi);
    strRes.ReleaseBuffer();
    strRes = GetResString(IDS_SF_TRANSFERRED);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(8, &hdi);
    strRes.ReleaseBuffer();
#endif
}

void CSharedFilesCtrl::ShowFileList(CSharedFileList *in_sflist)
{
    DeleteAllItems();
    sflist = in_sflist;
    for (CKnownFileMap::iterator pos = sflist->m_Files_map.begin() ; pos != sflist->m_Files_map.end() ; pos++)
    {
        ShowFile(pos->second);
    }
}

void CSharedFilesCtrl::RemoveFile(CKnownFile *toRemove)
{
    int nItem = FindItem( - 1, (long) toRemove);
    if (nItem != - 1)
    DeleteItem(nItem);
    ShowFilesCount();
}

void CSharedFilesCtrl::UpdateFile(CKnownFile *file, uint32_t itemnr)
{
    wxString buffer;
    SetItemData(itemnr, (long) file);
    SetItem(itemnr, 1, CastItoXBytes(file->GetFileSize()));
    // added by InterCeptor (show filetype) 11.11.02:
    SetItem(itemnr, 2, GetFiletypeByName(file->GetFileName()));
    //UAP
    if (theApp.dynprefs->Get<bool>("auto-priority-share") && file->IsAutoUpPriority())
    {
        switch (file->GetUpPriority())
        {
        case PR_NORMAL:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIOAUTONORMAL));
                break;
            }
        case PR_HIGH:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIOAUTOHIGH));
                break;
            }
        case PR_VERYHIGH:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIOAUTORELEASE));
                break;
            }
        }
    }
    else
    {
        //endUAP
        switch (file->GetUpPriority())
        {
        case PR_VERYLOW:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIOVERYLOW));
                break;
            }
        case PR_LOW:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIOLOW));
                break;
            }
        case PR_NORMAL:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIONORMAL));
                break;
            }
        case PR_HIGH:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIOHIGH));
                break;
            }
        case PR_VERYHIGH:
            {
                SetItem(itemnr, 3, GetResString(IDS_PRIORELEASE));
                break;
            }
        }
    }
 /*if (file->GetPermissions() == PERM_NOONE)
 SetItemText(itemnr,4,"Hidden");
 else if (file->GetPermissions() == PERM_FRIENDS)
 SetItemText(itemnr,4,"Friends Only");
 else
    SetItemText(itemnr,4,"Public Shared");*/
    SetItem(itemnr, 4, GetResString(IDS_FSTATUS_PUBLIC));
    //	buffer[0] = 0;
    //	for (uint16_t i = 0;i != 16;i++) // hmm I wonder if there is a standard function for this
    //		sprintf(buffer,"%s%02X",buffer,file->GetFileHash()[i]);
    SetItem(itemnr, 5, EncodeBase16(file->GetFileHash(), 16));
    buffer.Printf("%u (%u)", file->statistic.GetRequests(), file->statistic.GetAllTimeRequests());
    SetItem(itemnr, 6, buffer);
    buffer.Printf("%u (%u)", file->statistic.GetAccepts(), file->statistic.GetAllTimeAccepts());
    SetItem(itemnr, 7, buffer);
    buffer.Printf("%s (%s)", CastItoXBytes(file->statistic.GetTransfered()) .GetData(), CastItoXBytes(file->statistic.GetAllTimeTransfered()) .GetData());
    SetItem(itemnr, 8, buffer);
#if 0
    char buffer[50];
    char buffer2[50];
    char buffer3[50];
    CastItoXBytes(file->GetFileSize(), buffer);
    SetItem(itemnr, 1, buffer);
    // added by InterCeptor (show filetype) 11.11.02:
    SetItem(itemnr, 2, GetFiletypeByName(file->GetFileName()));
    if (file->GetUpPriority() == PR_VERYLOW)
    SetItem(itemnr, 3, GetResString(IDS_PRIOVERYLOW));
    else if(file->GetUpPriority() == PR_LOW)
    SetItem(itemnr, 3, GetResString(IDS_PRIOLOW));
    else if(file->GetUpPriority() == PR_NORMAL)
    SetItem(itemnr, 3, GetResString(IDS_PRIONORMAL));
    else if(file->GetUpPriority() == PR_HIGH)
    SetItem(itemnr, 3, GetResString(IDS_PRIOHIGH));
    else if(file->GetUpPriority() == PR_VERYHIGH)
    SetItem(itemnr, 3, GetResString(IDS_PRIORELEASE));
 /*if (file->GetPermissions() == PERM_NOONE)
 SetItemText(itemnr,4,"Hidden");
 else if (file->GetPermissions() == PERM_FRIENDS)
 SetItemText(itemnr,4,"Friends Only");
 else
    SetItemText(itemnr,4,"Public Shared");*/
    SetItem(itemnr, 4, GetResString(IDS_FSTATUS_PUBLIC));
    buffer[0] = 0;
    // hmm I wonder if there is a standard function for this:
    for (uint16_t i = 0 ; i != 16 ; i++)
    sprintf(buffer, "%s%02X", buffer, file->GetFileHash() [i]);
    SetItem(itemnr, 5, buffer);
    sprintf(buffer, "%u (%u)", file->statistic.GetRequests(), file->statistic.GetAllTimeRequests());
    SetItem(itemnr, 6, buffer);
    sprintf(buffer, "%u (%u)", file->statistic.GetAccepts(), file->statistic.GetAllTimeAccepts());
    SetItem(itemnr, 7, buffer);
    CastItoXBytes(file->statistic.GetTransfered(), buffer);
    CastItoXBytes(file->statistic.GetAllTimeTransfered(), buffer2);
    sprintf(buffer3, "%s (%s)", buffer, buffer2);
    SetItem(itemnr, 8, buffer3);
#endif
}

void CSharedFilesCtrl::ShowFile(CKnownFile *file)
{
    ShowFile(file, GetItemCount());
}

void CSharedFilesCtrl::ShowFile(CKnownFile *file, uint32_t itemnr)
{
    //InsertItem(LVIF_TEXT|LVIF_PARAM,itemnr,file->GetFileName(),0,0,0,(LPARAM)file);
    int newitem = InsertItem(itemnr, file->GetFileName());
    SetItemData(newitem, (long) file);
    // set background...
    wxListItem myitem;
    myitem.m_itemId = newitem;
    myitem.SetBackgroundColour(SYSCOLOR(wxSYS_COLOUR_LISTBOX));
    SetItem(myitem);
    UpdateFile(file, itemnr);
    ShowFilesCount();
}

#if 0
BEGIN_MESSAGE_MAP(CSharedFilesCtrl, CMuleListCtrl)
ON_WM_CONTEXTMENU()
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
END_MESSAGE_MAP()
#endif

#if 0
// CSharedFilesCtrl message handlers
void CSharedFilesCtrl::OnContextMenu(CWnd *pWnd, CPoint point)
{
    m_SharedFilesMenu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this);
}

#endif

//bool CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
bool CSharedFilesCtrl::ProcessEvent(wxEvent &evt)
{
    if (evt.GetEventType() != wxEVT_COMMAND_MENU_SELECTED)
    return CMuleListCtrl::ProcessEvent(evt);
    wxCommandEvent &event = (wxCommandEvent &) evt;
    UINT selectedCount = this->GetSelectedItemCount();
    //GetSelectionMark();:
    int iSel = GetNextItem( - 1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
    if (iSel != ( - 1))
    {
        CKnownFile *file = (CKnownFile *) GetItemData(iSel);
        switch (event.GetId())
        {
        case 123456789:
            {
                //theApp.xmuledlg->ircwnd.SetSendFileString(theApp.CreateED2kLink(file));
                printf("todo: ircwnd\n");
                break;
            }
        case MP_GETED2KLINK:
            {
                if (selectedCount > 1)
                {
                    int i = iSel;
                    wxString str;
                    do
                    {
                        CKnownFile *file2 = (CKnownFile *) GetItemData(i);
                        str += theApp.CreateED2kLink(file2) + "\n";
                    }
                    while ((i = GetNextItem(i, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != - 1);
                    theApp.CopyTextToClipboard(str);
                    break;
                }
                theApp.CopyTextToClipboard(theApp.CreateED2kLink(file));
                break;
            }
        case MP_GETHTMLED2KLINK:
            {
                if (selectedCount > 1)
                {
                    int i = iSel;
                    wxString str;
                    do
                    {
                        CKnownFile *file2 = (CKnownFile *) GetItemData(i);
                        str += theApp.CreateHTMLED2kLink(file2) + "\n";
                    }
                    while ((i = GetNextItem(i, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != - 1);
                    theApp.CopyTextToClipboard(str);
                    break;
                }
                theApp.CopyTextToClipboard(theApp.CreateHTMLED2kLink(file));
                break;
            }
        case MP_OPEN:
            {
                char *buffer = new char[250];
                sprintf(buffer, "%s/%s", file->GetPath(), file->GetFileName());
                theApp.xmuledlg->AddLogLine(false, "%s/%s", file->GetPath(), file->GetFileName());
                //ShellOpenFile(buffer);
                printf("todo: shellopenfile %s\n", buffer);
                delete buffer;
                break;
            }
            //For Comments
        case MP_CMT:
            {
                CCommentDialog dialog(this, file);
                //dialog.DoModal();
                dialog.ShowModal();
                break;
            }
        case MP_PRIOVERYLOW:
        case MP_PRIOLOW:
        case MP_PRIONORMAL:
        case MP_PRIOHIGH:
        case MP_PRIOVERYHIGH:
        case MP_PRIOAUTO:
            {
                //POSITION pos = this->GetFirstSelectedItemPosition();
                bool no_partfile_selected = false;
                long pos = GetNextItem( - 1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
                while (pos != ( - 1))
                {
                    //this->GetNextSelectedItem(pos);:
                    int iSel = pos;
                    file = (CKnownFile *) this->GetItemData(iSel);
                    switch (event.GetId())
                    {
                    case MP_PRIOVERYLOW:
                        {
                            file->SetAutoUpPriority(false);
                            file->SetUpPriority(PR_VERYLOW);
                            SetItem(iSel, 3, GetResString(IDS_PRIOVERYLOW));
                            break;
                        }
                    case MP_PRIOLOW:
                        {
                            file->SetAutoUpPriority(false);
                            file->SetUpPriority(PR_LOW);
                            SetItem(iSel, 3, GetResString(IDS_PRIOLOW));
                            break;
                        }
                    case MP_PRIONORMAL:
                        {
                            file->SetAutoUpPriority(false);
                            file->SetUpPriority(PR_NORMAL);
                            SetItem(iSel, 3, GetResString(IDS_PRIONORMAL));
                            break;
                        }
                    case MP_PRIOHIGH:
                        {
                            file->SetAutoUpPriority(false);
                            file->SetUpPriority(PR_HIGH);
                            SetItem(iSel, 3, GetResString(IDS_PRIOHIGH));
                            break;
                        }
                    case MP_PRIOVERYHIGH:
                        {
                            file->SetAutoUpPriority(false);
                            file->SetUpPriority(PR_VERYHIGH);
                            SetItem(iSel, 3, GetResString(IDS_PRIORELEASE));
                            break;
                        }
                    case MP_PRIOAUTO:
                        {
                            if (file->IsPartFile())
                            {
                                file->SetAutoUpPriority(true);
                                file->UpdateAutoUpPriority();
                                if (file->GetUpPriority() == PR_VERYHIGH)
                                SetItem(iSel, 3, GetResString(IDS_PRIOAUTORELEASE));
                                else if(file->GetUpPriority() == PR_HIGH)
                                SetItem(iSel, 3, GetResString(IDS_PRIOAUTOHIGH));
                                else if(file->GetUpPriority() == PR_NORMAL)
                                SetItem(iSel, 3, GetResString(IDS_PRIOAUTONORMAL));
                            }
                            else no_partfile_selected = true;
                        }
                    }
                    pos = GetNextItem(pos, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
                }
                break;
            }
        case MP_PERMNONE:
            {
                printf("FIX: ei tue multi-select\n");
                if (((CPartFile *) file)->IsPartFile())
                //AfxMessageBox(GetResString(IDS_ERR_NOPRIMCHANGE));
                wxMessageBox(GetResString(IDS_ERR_NOPRIMCHANGE));
                else
                {
                    file->SetPermissions(PERM_NOONE);
                    SetItem(iSel, 4, GetResString(IDS_HIDDEN));
                }
                break;
            }
        case MP_PERMFRIENDS:
            {
                if (((CPartFile *) file)->IsPartFile())
                //AfxMessageBox(GetResString(IDS_ERR_NOPRIMCHANGE));
                wxMessageBox(GetResString(IDS_ERR_NOPRIMCHANGE));
                else
                {
                    file->SetPermissions(PERM_FRIENDS);
                    SetItem(iSel, 4, GetResString(IDS_FSTATUS_FRIENDSONLY));
                }
                break;
            }
        case MP_PERMALL:
            {
                file->SetPermissions(PERM_ALL);
                SetItem(iSel, 4, GetResString(IDS_FSTATUS_PUBLIC));
                break;
            }
        }
    }
    return CMuleListCtrl::ProcessEvent(evt);
}

//void CSharedFilesCtrl::OnColumnClick( NMHDR* pNMHDR, LRESULT* pResult){
void CSharedFilesCtrl::OnColumnClick(wxListEvent &evt)
{
    //NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    // Barry - Store sort order in preferences
    // Determine ascending based on whether already sorted on this column
    int sortItem = theApp.glob_prefs->GetColumnSortItem(CPreferences::tableShared);
    bool m_oldSortAscending = theApp.glob_prefs->GetColumnSortAscending(CPreferences::tableShared);
    bool sortAscending = (sortItem != evt.GetColumn()) ? true: !m_oldSortAscending;
    // Item is column clicked
    sortItem = evt.GetColumn();
    // Save new preferences
    theApp.glob_prefs->SetColumnSortItem(CPreferences::tableShared, sortItem);
    theApp.glob_prefs->SetColumnSortAscending(CPreferences::tableShared, sortAscending);
    // Ornis 4-way-sorting
    int adder = 0;
    if (evt.GetColumn() > 5 &&evt.GetColumn() < 9)
    {
        if (!sortAscending) sortstat[evt.GetColumn() - 6] =!sortstat[evt.GetColumn() - 6];
        adder = sortstat[evt.GetColumn() - 6] ? 0: 100;
    }
    // Sort table
    if (adder == 0)
    SetSortArrow(sortItem, sortAscending);
    else
    // ? arrowDoubleUp : arrowDoubleDown);:
    SetSortArrow(sortItem, sortAscending);
    SortItems(SortProc, sortItem + adder + (sortAscending ? 0: 20));
}

int CSharedFilesCtrl::SortProc(long lParam1, long lParam2, long lParamSort)
{
    CKnownFile *item1 = (CKnownFile *) lParam1;
    CKnownFile *item2 = (CKnownFile *) lParam2;
    switch (lParamSort)
    {
        //filename asc:
    case 0:
        return strcasecmp(item1->GetFileName(), item2->GetFileName());
        //filename desc:
    case 20:
        return strcasecmp(item2->GetFileName(), item1->GetFileName());
        //filesize asc:
    case 1:
        return item1->GetFileSize() == item2->GetFileSize() ?0: (item1->GetFileSize() > item2->GetFileSize() ?1: - 1);
        //filesize desc:
    case 21:
        return item1->GetFileSize() == item2->GetFileSize() ?0: (item2->GetFileSize() > item1->GetFileSize() ?1: - 1);
        //filetype asc:
    case 2:
        return strcasecmp(GetFiletypeByName(item1->GetFileName()), GetFiletypeByName(item2->GetFileName()));
        //filetype desc:
    case 22:
        return strcasecmp(GetFiletypeByName(item2->GetFileName()), GetFiletypeByName(item1->GetFileName()));
        //prio asc:
    case 3:
        if (item1->GetUpPriority() == PR_VERYLOW)
        return 1;
        else if(item2->GetUpPriority() == PR_VERYLOW)
        return 0;
        else
        return item2->GetUpPriority() - item1->GetUpPriority();
        //prio desc:
    case 23:
        if (item1->GetUpPriority() == PR_VERYLOW)
        return 0;
        else if(item2->GetUpPriority() == PR_VERYLOW)
        return 1;
        else
        return item1->GetUpPriority() - item2->GetUpPriority();
        //permission asc:
    case 4:
        return item2->GetPermissions() - item1->GetPermissions();
        //permission desc:
    case 24:
        return item1->GetPermissions() - item2->GetPermissions();
        //fileID asc:
    case 5:
        return strcasecmp((char *) item1->GetFileHash(), (char *) item2->GetFileHash());
        //fileID desc:
    case 25:
        return strcasecmp((char *) item2->GetFileHash(), (char *) item1->GetFileHash());
        //requests asc:
    case 6:
        return item1->statistic.GetRequests() - item2->statistic.GetRequests();
        //requests desc:
    case 26:
        return item2->statistic.GetRequests() - item1->statistic.GetRequests();
        //acc requests asc:
    case 7:
        return item1->statistic.GetAccepts() - item2->statistic.GetAccepts();
        //acc requests desc:
    case 27:
        return item2->statistic.GetAccepts() - item1->statistic.GetAccepts();
        //all transferred asc:
    case 8:
        return item1->statistic.GetTransfered() == item2->statistic.GetTransfered() ?0: (item1->statistic.GetTransfered() > item2->statistic.GetTransfered() ?1: - 1);
        //all transferred desc:
    case 28:
        return item1->statistic.GetTransfered() == item2->statistic.GetTransfered() ?0: (item2->statistic.GetTransfered() > item1->statistic.GetTransfered() ?1: - 1);
        //folder asc:
    case 10:
        return strcasecmp((wxString) item1->GetPath(), (wxString) item2->GetPath());
        //folder desc:
    case 30:
        return strcasecmp((wxString) item2->GetPath(), (wxString) item1->GetPath());
        //all requests asc:
    case 106:
        return item1->statistic.GetAllTimeRequests() - item2->statistic.GetAllTimeRequests();
        //all requests desc:
    case 126:
        return item2->statistic.GetAllTimeRequests() - item1->statistic.GetAllTimeRequests();
        //all acc requests asc:
    case 107:
        return item1->statistic.GetAllTimeAccepts() - item2->statistic.GetAllTimeAccepts();
        //all acc requests desc:
    case 127:
        return item2->statistic.GetAllTimeAccepts() - item1->statistic.GetAllTimeAccepts();
        //all transferred asc:
    case 108:
        return item1->statistic.GetAllTimeTransfered() == item2->statistic.GetAllTimeTransfered() ?0: (item1->statistic.GetAllTimeTransfered() > item2->statistic.GetAllTimeTransfered() ?1: - 1);
        //all transferred desc:
    case 128:
        return item1->statistic.GetAllTimeTransfered() == item2->statistic.GetAllTimeTransfered() ?0: (item2->statistic.GetAllTimeTransfered() > item1->statistic.GetAllTimeTransfered() ?1: - 1);
    default:
        return 0;
    }
}

void CSharedFilesCtrl::UpdateItem(CKnownFile *toupdate)
{
    //LVFINDINFO find;
    //find.flags = LVFI_PARAM;
    //find.lParam = (LPARAM)toupdate;
    int16_t result = FindItem( - 1, (long) toupdate);
    if (result != - 1)
    {
        UpdateFile(toupdate, result);
        //Update(result) ;   // Added by Tarod to real time refresh - DonGato - 11/11/2002
        theApp.xmuledlg->sharedfileswnd->Check4StatUpdate(toupdate);
    }
}

void CSharedFilesCtrl::ShowFilesCount()
{
    wxString fmtstr = wxString::Format(_("Shared Files (%i)"), GetItemCount());
    wxStaticCast(FindWindowByName(wxT("sharedFilesLabel")), wxStaticText)->SetLabel(fmtstr);
}

void CSharedFilesCtrl::OnDrawItem(int item, wxDC *dc, const wxRect &rect, const wxRect &rectHL, bool highlighted)
{
    CKnownFile *file = (CKnownFile *) GetItemData(item);
    assert(file != NULL);
    if (highlighted)
    {
        wxColour newcol;
        wxBrush hilBrush;
        if (GetFocus())
        {
            wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
            newcol = wxColour(G_BLEND(col.Red(), 125),
            G_BLEND(col.Green(), 125),
            G_BLEND(col.Blue(), 125));
            hilBrush = wxBrush(newcol, wxSOLID);
            dc->SetBackground(hilBrush);
            dc->SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
        }
        else
        {
            wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
            newcol = wxColour(G_BLEND(col.Red(), 125),
            G_BLEND(col.Green(), 125),
            G_BLEND(col.Blue(), 125));
            hilBrush = wxBrush(newcol, wxSOLID);
            dc->SetBackground(hilBrush);
            dc->SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
        }
        newcol = wxColour(((int) newcol.Red() *65) /100,
        ((int) newcol.Green() *65) /100,
        ((int) newcol.Blue() *65) /100);
        dc->SetPen(wxPen(newcol, 1, wxSOLID));
    }
    else
    {
        dc->SetBackground( * (wxTheBrushList->FindOrCreateBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX), wxSOLID)));
        dc->SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
        dc->SetPen( *wxTRANSPARENT_PEN);
    }
    dc->SetBrush(dc->GetBackground());
    dc->DrawRectangle(rectHL);
    dc->SetPen( *wxTRANSPARENT_PEN);
    wxRect columnRect = rect;
#define SPARE_PIXELS_HORZ	4
#define SPARE_PIXELS_VERT_TEXT	3
    columnRect.SetLeft(columnRect.GetLeft() + SPARE_PIXELS_HORZ);
    columnRect.SetWidth(columnRect.GetWidth() - 2 *SPARE_PIXELS_HORZ);
    for (int iColumn = 0 ; iColumn < GetColumnCount() ; iColumn++)
    {
        wxListItem columnItem;
        GetColumn(iColumn, columnItem);
        int width = columnItem.GetWidth();
        columnRect.SetWidth(width - 2 *SPARE_PIXELS_HORZ);
        wxDCClipper clipper( *dc, columnRect);
        switch (iColumn)
        {
        case 9:
            file->DrawShareStatusBar(dc, columnRect, false, (theApp.dynprefs->Get<long>("progress-bar-style") == 0));
            break;
        default:
            columnItem.m_col = iColumn;
            columnItem.m_itemId = item;
            GetItem(columnItem);
            dc->DrawText(columnItem.m_text, columnRect.GetLeft(), columnRect.GetTop() + SPARE_PIXELS_VERT_TEXT);
            break;
        }
        columnRect.SetLeft(columnRect.GetLeft() + width);
    }
}

