// 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 "CatDialog.h"
#include "DownloadListCtrl.h"               // Needed for CDownloadListCtrl - audited 5 Nov 2004
#	include "DownloadQueue.h"
#include "MuleNotebook.h"                   // CMuleNotebook
#	include "muuli_wdr.h"
#include "opcodes.h"                        // MP_CANCEL - audited 5 Nov 2004
#	include "otherfunctions.h"
#include "PartFile.h"                       // Needed for SRV_PR_HIGH - audited 5 Nov 2004
#include "Preferences.h"                    // CPreferences::GetCategory
#include "QueueListCtrl.h"                  // Needed for CQueueListCtrl
#	include "TransferWnd.h"
#include "UploadListCtrl.h"                 // Needed for CUploadListCtrl - 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/msgdlg.h>                      // Needed for wxMessageBox
#include <wx/settings.h>
#include <wx/sizer.h>                       // Needed for wxSizer
#include <wx/splitter.h>

enum
{
    MP_CAT_ADD,
    MP_CAT_EDIT,
    MP_CAT_REMOVE,
    MP_CAT_SET1,
    MP_CAT_SET2,
    MP_CAT_SET3,
    MP_CAT_SET4,
    MP_CAT_SET5,
    MP_CAT_SET6,
    MP_CAT_SET7,
    MP_CAT_SET8,
    MP_CAT_SET9,
    MP_CAT_SET10,
    MP_CAT_SET11,
    MP_CAT_SET12,
    MP_CAT_SET13,
    MP_CAT_SET14,
    MP_CAT_SET15
};

IMPLEMENT_DYNAMIC_CLASS(CTransferWnd, wxPanel)

BEGIN_EVENT_TABLE(CTransferWnd, wxPanel)
    EVT_RIGHT_DOWN(CTransferWnd::OnNMRclickDLtab)
    EVT_SPLITTER_SASH_POS_CHANGED(ID_SPLATTER, CTransferWnd::OnSashPositionChanged)
    EVT_MENU_RANGE(MP_CAT_ADD, MP_CAT_SET15, CTransferWnd::HandleCatMenu)
    EVT_MENU_RANGE(MP_CANCEL, MP_PRIOAUTO, CTransferWnd::HandleCatMenu)
    EVT_BUTTON(IDC_UPLOAD_ICO, CTransferWnd::HandleCatMenu)
    EVT_NOTEBOOK_PAGE_CHANGED(ID_CATEGORIES, CTransferWnd:: OnSelchangeDltab)
//    EVT_MENU_RANGE(, CTransferWnd::HandleCatMenu)
END_EVENT_TABLE()

CTransferWnd::CTransferWnd(wxWindow* pParent): wxPanel(pParent, -1)
{
    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWFRAME));
    wxSizer *content = transferDlg(this, TRUE);
    content->Show(this, TRUE);
    wxSplitterWindow *split = (wxSplitterWindow *) FindWindow("splitterWnd");
    wxPanel *subContent1 = new wxPanel(split, - 1);
    subContent1->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWFRAME));
    transferTopPane(subContent1, TRUE);
    wxPanel *subContent2 = new wxPanel(split, - 1);
    subContent2->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWFRAME));
    wxSizer *subC2 = transferBottomPane(subContent2, FALSE);
    split->SplitHorizontally(subContent1, subContent2);
    uploadlistctrl = (CUploadListCtrl *) FindWindowByName("uploadList");
    downloadlistctrl = (CDownloadListCtrl *) FindWindowByName("downloadList");
    queuelistctrl = (CQueueListCtrl *) FindWindowByName("uploadQueue");
    // let's hide the queue
    queueSizer->Remove(queuelistctrl);
    subC2->SetDimension(0, 0, 100, 50);
    queueSizer->Layout();
    //subC2->Layout();
    queuelistctrl->Show(FALSE);
    // allow notebook to dispatch right mouse clicks to us
    CMuleNotebook *nb = (CMuleNotebook *) FindWindowById(ID_CATEGORIES);
    nb->SetSize(-1, 0);
    nb->SetMouseListener(GetEventHandler());
    windowtransferstate = false;
    CatMenu = false;
}

CTransferWnd::~CTransferWnd()
{
}

bool CTransferWnd::OnInitDialog()
{
    m_dlTab = (CMuleNotebook *) FindWindowById(ID_CATEGORIES);
    // show & cat-tabs
    theApp.glob_prefs->GetCategory(0)->title = GetCatTitle(theApp.glob_prefs->GetAllcatType());
    theApp.glob_prefs->GetCategory(0)->incomingpath = theApp.dynprefs->Get<wxString>("incoming-directory");
    for (int ix = 0 ; ix < theApp.glob_prefs->GetCatCount() ; ix++)
    {
        wxPanel *nullPanel = new wxPanel(m_dlTab);
        wxString tmpstrstr(theApp.glob_prefs->GetCategory(ix)->title);
        // just temporary string.:
        m_dlTab->AddPage(nullPanel, "-");
        // for some odd reason, wxwin2.5 and gtk2 will not allow non utf strings for AddPage()
        // but they will be accepted in SetPageText().. so let's use this as a countermeasure
        m_dlTab->SetPageText(ix, tmpstrstr);
    }
    return true;
}

void CTransferWnd::ShowQueueCount(uint32_t number)
{
    char buffer[100];
    wxString fmtstr = "%u (%u " + GetResString(IDS_BANNED) .MakeLower() + ")";
    sprintf(buffer, fmtstr.GetData(), number, theApp.uploadqueue->GetBanCount());
    wxStaticCast(FindWindowByName("clientCount"), wxStaticText)->SetLabel(buffer);
    //this->GetDlgItem(IDC_QUEUECOUNT)->SetWindowText(buffer);
}

void CTransferWnd::SwitchUploadList(wxCommandEvent &evt)
{
    if (windowtransferstate == false)
    {
        windowtransferstate = true;
        // hide the upload list
        queueSizer->Remove(uploadlistctrl);
        uploadlistctrl->Show(FALSE);
        queueSizer->Add(queuelistctrl, 1, wxGROW |wxALIGN_CENTER_VERTICAL |wxALL, 5);
        queuelistctrl->Show();
        queueSizer->Layout();
        wxStaticCast(FindWindowByName("uploadTitle"), wxStaticText)->SetLabel(GetResString(IDS_ONQUEUE));
    }
    else
    {
        windowtransferstate = false;
        // hide the queuelist
        queueSizer->Remove(queuelistctrl);
        queuelistctrl->Show(FALSE);
        queueSizer->Add(uploadlistctrl, 1, wxGROW |wxALIGN_CENTER_VERTICAL |wxALL, 5);
        uploadlistctrl->Show();
        queueSizer->Layout();
        wxStaticCast(FindWindowByName("uploadTitle"), wxStaticText)->SetLabel(GetResString(IDS_TW_UPLOADS));
    }
}

void CTransferWnd::OnSelchangeDltab(wxNotebookEvent &evt)
{
    downloadlistctrl->ChangeCategory(evt.GetSelection());
    downloadlistctrl->InitSort();
}

void CTransferWnd::HandleCatMenu(wxCommandEvent& event)
{
    const int id = event.GetId();

    if (id >= MP_CAT_SET1 && id <= MP_CAT_SET15)
    {
        theApp.glob_prefs->SetAllcatType(event.GetId() - MP_CAT_SET1);
        theApp.glob_prefs->GetCategory(0)->title = GetCatTitle(theApp.glob_prefs->GetAllcatType());
        wxString csName;
        csName = theApp.glob_prefs->GetCategory(0)->title;
        EditCatTabLabel(0, csName);
        downloadlistctrl->ChangeCategory(0);
        downloadlistctrl->InitSort();
    }
    else if (id == MP_CAT_ADD)
    {
        int newindex = AddCategorie("?", theApp.dynprefs->Get<wxString>("incoming-directory"), "", false);
        //m_dlTab.InsertItem(newindex,theApp.glob_prefs->GetCatego
        //	       ry(newindex)->title);
        wxPanel *nullPanel = new wxPanel(m_dlTab, - 1);
        m_dlTab->AddPage(nullPanel, theApp.glob_prefs->GetCategory(newindex)->title);
        CCatDialog dialog(this, newindex);
        dialog.OnInitDialog();
        //dialog.DoModal();
        dialog.ShowModal();
        //arning TODO: fix this
        //theApp.emuledlg->searchwnd->UpdateCatTabs();
        EditCatTabLabel(newindex, theApp.glob_prefs->GetCategory(newindex)->title);
        // Save Cats
        theApp.glob_prefs->Save(2);
    }
    else if (id == MP_CAT_EDIT)
    {
        CCatDialog dialog(this, m_dlTab->GetSelection());
        dialog.OnInitDialog();
        dialog.ShowModal();
        wxString csName;
        csName = theApp.glob_prefs->GetCategory(m_dlTab->GetSelection())->title;
        EditCatTabLabel(m_dlTab->GetSelection(), csName);
        //arning TODO: fix this
        //theApp.emuledlg->searchwnd.UpdateCatTabs();
        // Save Cats            
        theApp.glob_prefs->Save(2);
    }
    else if (id == MP_CAT_REMOVE)
    {
        // Do not remove the first tab
        if (m_dlTab->GetSelection() == 0)
        {
            return;
        }

        theApp.downloadqueue->ResetCatParts(m_dlTab->GetSelection());
        theApp.glob_prefs->RemoveCat(m_dlTab->GetSelection());
        m_dlTab->RemovePage(m_dlTab->GetSelection());
        m_dlTab->SetSelection(0);
        downloadlistctrl->ChangeCategory(0);
        // Save Cats            
        theApp.glob_prefs->Save(2);
        if (theApp.glob_prefs->GetCatCount() == 1) 
        {
            theApp.glob_prefs->SetAllcatType(0);
        }
        //arning TODO: fix this
        //theApp.emuledlg->searchwnd.UpdateCatTabs();
    }
    else if (id == MP_PRIOLOW)
    {
        theApp.downloadqueue->SetCatPrio(m_dlTab->GetSelection(), PR_LOW);
    }
    else if (id == MP_PRIONORMAL)
    {
        theApp.downloadqueue->SetCatPrio(m_dlTab->GetSelection(), PR_NORMAL);
    }
    else if (id == MP_PRIOHIGH)
    {
        theApp.downloadqueue->SetCatPrio(m_dlTab->GetSelection(), PR_HIGH);
    }
    else if (id == MP_PRIOAUTO)
    {
        theApp.downloadqueue->SetCatPrio(m_dlTab->GetSelection(), PR_AUTO);
    }
    else if (id == MP_PAUSE)
    {
        theApp.downloadqueue->SetCatStatus(m_dlTab->GetSelection(), MP_PAUSE);
    }
    else if (id == MP_STOP)
    {
        theApp.downloadqueue->SetCatStatus(m_dlTab->GetSelection(), MP_STOP);
    }
    else if (id == MP_CANCEL)
    {
        if (wxMessageBox(GetResString(IDS_CATEGORY_DELETE), GetResString(IDS_CONFIRMATION),
/*->*/      wxYES_NO |wxCENTRE |wxICON_EXCLAMATION) == wxYES)
        {
            theApp.downloadqueue->SetCatStatus(m_dlTab->GetSelection(), MP_CANCEL);
        }
    }
    else if (id == MP_RESUME)
    {
        theApp.downloadqueue->SetCatStatus(m_dlTab->GetSelection(), MP_RESUME);
    }
#if 0
    else if (id == MP_RESUMENEXT)
    {
        theApp.downloadqueue->StartNextFile(m_dlTab->GetSelection());
    }
#endif
    else if (id == IDC_UPLOAD_ICO)
    {
        wxCommandEvent nullEvt;
        SwitchUploadList(nullEvt);
    }
    else if (id == IDC_QUEUE_REFRESH_BUTTON)
    {
        //arning TODO: fix this
        //OnBnClickedQueueRefreshButton();
    }
}

void CTransferWnd::OnNMRclickDLtab(wxMouseEvent &evt)
{
    CMuleNotebook *nb = (CMuleNotebook *)FindWindowById(ID_CATEGORIES);
    if (nb->GetSelection() == - 1)
    {
        return;
    }
    // Avoid opening another menu when it's already open
    if (CatMenu == false)
    {
        CatMenu = true;
        wxMenu *menu = new wxMenu(GetResString(IDS_CAT));
        if (nb->GetSelection() == 0)
        {
            wxMenu *m_CatMenu = new wxMenu();
            m_CatMenu->Append(MP_CAT_SET1, GetResString(IDS_ALL));
            m_CatMenu->Append(MP_CAT_SET2, GetResString(IDS_ALLOTHERS));
            m_CatMenu->AppendSeparator();
            m_CatMenu->Append(MP_CAT_SET3, GetResString(IDS_STATUS_NOTCOMPLETED));
            m_CatMenu->Append(MP_CAT_SET4, GetResString(IDS_DL_TRANSFCOMPL));
            m_CatMenu->Append(MP_CAT_SET5, GetResString(IDS_WAITING));
            m_CatMenu->Append(MP_CAT_SET6, GetResString(IDS_DOWNLOADING));
            m_CatMenu->Append(MP_CAT_SET7, GetResString(IDS_ERRORLIKE));
            m_CatMenu->Append(MP_CAT_SET8, GetResString(IDS_PAUSED));
            m_CatMenu->Append(MP_CAT_SET9, GetResString(IDS_STOPPED));
            m_CatMenu->AppendSeparator();
            m_CatMenu->Append(MP_CAT_SET10, GetResString(IDS_VIDEO));
            m_CatMenu->Append(MP_CAT_SET11, GetResString(IDS_AUDIO));
            m_CatMenu->Append(MP_CAT_SET12, GetResString(IDS_SEARCH_ARC));
            m_CatMenu->Append(MP_CAT_SET13, GetResString(IDS_SEARCH_CDIMG));
            m_CatMenu->Append(MP_CAT_SET14, GetResString(IDS_SEARCH_PICS));
            m_CatMenu->Append(MP_CAT_SET15, GetResString(IDS_TEXT));
            //m_CatMenu.CheckMenuItem( MP_CAT_SET0+theApp.glob_prefs->GetAllcatType() ,MF_CHECKED | MF_BYCOMMAND);
            menu->Append(47321, GetResString(IDS_CHANGECATVIEW), m_CatMenu);
        }
        menu->Append(MP_CAT_ADD, GetResString(IDS_CAT_ADD));
        menu->Append(MP_CAT_EDIT, GetResString(IDS_CAT_EDIT));
        menu->Append(MP_CAT_REMOVE, GetResString(IDS_CAT_REMOVE));
        menu->AppendSeparator();
        //menu->Append(472834,GetResString(IDS_PRIORITY),m_PrioMenu);
        menu->Append(MP_CANCEL, GetResString(IDS_MAIN_BTN_CANCEL));
        menu->Append(MP_STOP, GetResString(IDS_DL_STOP));
        menu->Append(MP_PAUSE, GetResString(IDS_DL_PAUSE));
        menu->Append(MP_RESUME, GetResString(IDS_DL_RESUME));
        //menu->Append(MP_RESUMENEXT, GetResString(IDS_DL_RESUMENEXT));
        // the point coming from mulenotebook control isn't in screen coordinates
        // (unlike std mouse event, which always returns screen coordinates)
        // so we must do the conversion here
        wxPoint pt = evt.GetPosition();
        wxPoint newpt = nb->ClientToScreen(pt);
        newpt = ScreenToClient(newpt);
        //evt.Skip();
        PopupMenu(menu, newpt);
        CatMenu = false;
    }
}

int CTransferWnd::AddCategorie(wxString newtitle, wxString newincoming, wxString newcomment, bool addTab)
{
    Category_Struct *newcat = new Category_Struct;
    newcat->title = newtitle;
    newcat->prio = 0;
    newcat->incomingpath = newincoming;
    newcat->comment = newcomment;
    int index = theApp.glob_prefs->AddCat(newcat);

    if (addTab)
    {
        //m_dlTab.InsertItem(index,newtitle);
        wxPanel *nullPanel = new wxPanel(m_dlTab, - 1);
        m_dlTab->AddPage(nullPanel, newtitle);
    }

    return index;
}

void CTransferWnd::EditCatTabLabel(int index, wxString newlabel)
{
    //TCITEM tabitem;
    //tabitem.mask = TCIF_PARAM;
    //m_dlTab.GetItem(index,&tabitem);
    //tabitem.mask = TCIF_TEXT;
    if (theApp.glob_prefs->ShowCatTabInfos())
    {
        CPartFile* cur_file;
        uint16_t count, dwl;
        count = dwl = 0;
        for (int i = 0 ; i < theApp.downloadqueue->GetFileCount() ; i++)
        {
            cur_file = theApp.downloadqueue->GetFileByIndex(i);

            if (cur_file == 0)
            {
                continue;
            }

            if (CheckShowItemInGivenCat(cur_file, index))
            {
                count++;

                if (cur_file->GetTransferingSrcCount() > 0)
                {
                    dwl++;
                }
                //                              speed+=cur_file->GetDatarate()/1024.0f;
                //                              size+=cur_file->GetFileSize();
                //                              trsize+=cur_file->GetCompletedSize();
            }
        }

        wxString title = newlabel;
        newlabel << title << wxT(" (") << dwl << wxT("/") << count << wxT(")");
    }
    //tabitem.pszText = newlabel.LockBuffer();
    //m_dlTab.SetItem(index,&tabitem);
    //newlabel.UnlockBuffer();
    m_dlTab->SetPageText(index, newlabel);
}

void CTransferWnd::OnSashPositionChanged(wxSplitterEvent& event)
{
    theApp.xmuledlg->split_pos = ((wxSplitterWindow *) FindWindow("splitterWnd"))->GetSashPosition();
}
