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

// FriendListCtrl.cpp : implementation file

#ifdef PRECOMP
#	include "xmule-headers.h"
#else
#	include "AddFriend.h"
#	include "ChatWnd.h"
#	include "ClientDetailDialog.h"
#	include "ClientList.h"
#	include "Friend.h"
#include "FriendList.h"                     // FriendList
#	include "FriendListCtrl.h"
#include "ListenSocket.h"                   // CClientReqSocket - audited 5 Nov 2004
#include "opcodes.h"                        // MP_DETAIL
#include "otherfunctions.h"                 // GetTickCount - audited 5 Nov 2004
#include "updownclient.h"                   // Needed for CUpDownClient - audited 5 Nov 2004
#	include "wintypes.h"
#	include "xmule.h"
#	include "xmuleDlg.h"
#endif

#include <wx/menu.h>

// CFriendListCtrl

BEGIN_EVENT_TABLE(CFriendListCtrl, CMuleListCtrl)
EVT_RIGHT_DOWN(CFriendListCtrl::OnNMRclick)
END_EVENT_TABLE()

//IMPLEMENT_DYNAMIC(CFriendListCtrl, CListCtrl)
CFriendListCtrl::CFriendListCtrl()
{
}

CFriendListCtrl::~CFriendListCtrl()
{
}

CFriendListCtrl::CFriendListCtrl(wxWindow *&parent, int id, const wxPoint &pos, wxSize siz, int flags)
: CMuleListCtrl(parent, id, pos, siz, flags)
{
    Init();
}

#if 0
BEGIN_MESSAGE_MAP(CFriendListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(NM_RCLICK, OnNMRclick)
END_MESSAGE_MAP()
#endif

// CFriendListCtrl message handlers

void CFriendListCtrl::Init()
{
    wxRect rc = GetClientRect();
    InsertColumn(0, GetResString(IDS_QL_USERNAME), wxLIST_FORMAT_LEFT, rc.width - 4);
    // not not here
    //theApp.friendlist->SetWindow(this);
    //theApp.friendlist->ShowFriends();
#if 0
    SetExtendedStyle(LVS_EX_FULLROWSELECT);
    RECT rcWindow;
    GetWindowRect( &rcWindow);
    InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT,
    rcWindow.right - rcWindow.left - 4, 0);
    imagelist.Create(16, 16, ILC_COLOR32 |ILC_MASK, 0, 10);
    imagelist.SetBkColor(RGB(255, 255, 255));
    imagelist.Add(theApp.LoadIcon(IDI_FRIENDS1));
    imagelist.Add(theApp.LoadIcon(IDI_FRIENDS2));
    imagelist.Add(theApp.LoadIcon(IDI_FRIENDS3));
    SetImageList( &imagelist, LVSIL_SMALL);
    theApp.friendlist->SetWindow(this);
    theApp.friendlist->ShowFriends();
#endif
}

void CFriendListCtrl::Localize()
{
#if 0
    CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
    HDITEM hdi;
    hdi.mask = HDI_TEXT;
    wxString strRes;
    strRes = GetResString(IDS_QL_USERNAME);
    hdi.pszText = strRes.GetBuffer();
    pHeaderCtrl->SetItem(0, &hdi);
    strRes.ReleaseBuffer();
#endif
}

void CFriendListCtrl::AddFriend(CFriend *toadd)
{
    uint32_t itemnr = GetItemCount();
    //itemnr = InsertItem(LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE,itemnr,toadd->m_strName.GetBuffer(),0,0,1,(LPARAM)toadd);
    itemnr = InsertItem(itemnr, toadd->m_strName.GetData());
    SetItemData(itemnr, (long) toadd);
    RefreshFriend(toadd);
}

void CFriendListCtrl::RemoveFriend(CFriend *toremove)
{
    //LVFINDINFO find;
    //find.flags = LVFI_PARAM;
    //find.lParam = (LPARAM)toremove;
    int32_t result = FindItem( - 1, (long) toremove);
    if (result != ( - 1))
    DeleteItem(result);
}

void CFriendListCtrl::RefreshFriend(CFriend *toupdate)
{
    //LVFINDINFO find;
    //find.flags = LVFI_PARAM;
    //find.lParam = (LPARAM)toupdate;
    int32_t itemnr = FindItem( - 1, (long) toupdate);
    wxString temp;
    temp.Printf("%s", toupdate->m_strName.GetData());
    SetItem(itemnr, 0, temp);
    if (itemnr == ( - 1))
    return;
    uint8_t image;
    if (!toupdate->m_LinkedClient)
    image = 0;
    else if(toupdate->m_LinkedClient->socket &&toupdate->m_LinkedClient->socket->IsConnected())
    image = 2;
    else
    image = 1;
    //SetItem(itemnr,0,LVIF_IMAGE,0,image,0,0,0,0);
}

void CFriendListCtrl::OnNMRclick(wxMouseEvent &evt)
{
    CFriend *cur_friend = NULL;
    wxMenu *menu = new wxMenu(GetResString(IDS_FRIENDLIST));
    int cursel = GetNextItem( - 1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
    if (cursel != ( - 1))
    {
        cur_friend = (CFriend *) GetItemData(cursel);
        menu->Append(MP_DETAIL, GetResString(IDS_SHOWDETAILS));
        menu->Enable(MP_DETAIL, ((cur_friend->m_LinkedClient) ?TRUE: FALSE));
    }
    menu->Append(MP_ADDFRIEND, GetResString(IDS_ADDAFRIEND));
    if (cursel != ( - 1))
    {
        menu->Append(MP_REMOVEFRIEND, GetResString(IDS_REMOVEFRIEND));
        menu->Append(MP_MESSAGE, GetResString(IDS_SEND_MSG));
        menu->Append(MP_SHOWLIST, GetResString(IDS_VIEWFILES));
        menu->AppendCheckItem(MP_FRIENDSLOT, GetResString(IDS_FRIENDSLOT));
        if (cur_friend->m_LinkedClient)
        {
            menu->Enable(MP_FRIENDSLOT, TRUE);
            menu->Check(MP_FRIENDSLOT, ((cur_friend->m_LinkedClient->GetFriendSlot()) ?TRUE: FALSE));
        }
        else
        menu->Enable(MP_FRIENDSLOT, FALSE);
    }
    PopupMenu(menu, evt.GetPosition());
}

#if 0
void CFriendListCtrl::OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult)
{
    POINT point;
    ::GetCursorPos( &point);
    CFriend *cur_friend;
    if (m_ClientMenu) m_ClientMenu.DestroyMenu();
    m_ClientMenu.CreatePopupMenu();
    m_ClientMenu.AddMenuTitle(GetResString(IDS_FRIENDLIST));
    if (GetSelectionMark() != ( - 1))
    {
        cur_friend = (CFriend *) GetItemData(GetSelectionMark());
        m_ClientMenu.AppendMenu(MF_STRING, MP_DETAIL, GetResString(IDS_SHOWDETAILS));
        m_ClientMenu.EnableMenuItem(MP_DETAIL, ((cur_friend->m_LinkedClient) ? MF_ENABLED: MF_GRAYED));
    }
    m_ClientMenu.AppendMenu(MF_STRING, MP_ADDFRIEND, GetResString(IDS_ADDAFRIEND));
    if (GetSelectionMark() != ( - 1))
    {
        m_ClientMenu.AppendMenu(MF_STRING, MP_REMOVEFRIEND, GetResString(IDS_REMOVEFRIEND));
        m_ClientMenu.AppendMenu(MF_STRING, MP_MESSAGE, GetResString(IDS_SEND_MSG));
        m_ClientMenu.AppendMenu(MF_STRING, MP_SHOWLIST, GetResString(IDS_VIEWFILES));
        m_ClientMenu.AppendMenu(MF_STRING, MP_FRIENDSLOT, GetResString(IDS_FRIENDSLOT));
        if (cur_friend->m_LinkedClient)
        {
            m_ClientMenu.EnableMenuItem(MP_FRIENDSLOT, MF_ENABLED);
            m_ClientMenu.CheckMenuItem(MP_FRIENDSLOT, ((cur_friend->m_LinkedClient->GetFriendSlot()) ?MF_CHECKED: MF_UNCHECKED));
        }
        else
        m_ClientMenu.EnableMenuItem(MP_FRIENDSLOT, MF_GRAYED);
    }
    SetMenu( &m_ClientMenu);
    m_ClientMenu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this);
    *pResult = 0;
    m_ClientMenu.DestroyMenu();
}

#endif

bool CFriendListCtrl::ProcessEvent(wxEvent &evt)
{
    CFriend *cur_friend;
    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)) cur_friend = (CFriend *) GetItemData(cursel);
    switch (event.GetId())
    {
    case MP_MESSAGE:
        {
            if (cur_friend->m_LinkedClient)
            theApp.xmuledlg->chatwnd->StartSession(cur_friend->m_LinkedClient);
            else
            {
                CUpDownClient *chatclient = new CUpDownClient(cur_friend->m_nLastUsedPort, cur_friend->m_dwLastUsedIP, 0, 0, 0);
                chatclient->SetUserName((char *) cur_friend->m_strName.GetData());
                theApp.clientlist->AddClient(chatclient);
                theApp.xmuledlg->chatwnd->StartSession(chatclient);
            }
            break;
        }
    case MP_REMOVEFRIEND:
        {
            theApp.friendlist->RemoveFriend(cur_friend);
            break;
        }
    case MP_ADDFRIEND:
        {
            CAddFriend *dialog2 = new CAddFriend(this);
            dialog2->ShowModal();
            delete dialog2;
            // hmm.. if not return here, we'll end up in preferences dlg
            return TRUE;
        }
        break;
    case MP_DETAIL:
        if (cur_friend->m_LinkedClient)
        {
            CClientDetailDialog *dialog = new CClientDetailDialog(this, cur_friend->m_LinkedClient);
            dialog->ShowModal();
            delete dialog;
            return TRUE;
        }
        break;
    case MP_SHOWLIST:
        {
            if (cur_friend->m_LinkedClient)
            cur_friend->m_LinkedClient->RequestSharedFileList();
            else
            {
                CUpDownClient *newclient = new CUpDownClient(cur_friend->m_nLastUsedPort, cur_friend->m_dwLastUsedIP, 0, 0, 0);
                newclient->SetUserName((char *) cur_friend->m_strName.GetData());
                theApp.clientlist->AddClient(newclient);
                newclient->RequestSharedFileList();
            }
            break;
        }
    case MP_FRIENDSLOT:
        {
            if (cur_friend->m_LinkedClient)
            {
                bool IsAlready;
                IsAlready = cur_friend->m_LinkedClient->GetFriendSlot();
                theApp.friendlist->RemoveAllFriendSlots();
                if (!IsAlready)
                cur_friend->m_LinkedClient->SetFriendSlot(true);
            }
            break;
        }
    }
    return CMuleListCtrl::ProcessEvent(evt);
}

