BOOL CChatSelector::OnCommand(WPARAM wParam, LPARAM lParam)
{
	switch (wParam){ 
		case MP_DETAIL:{
			const CChatItem* ci = GetCurrentChatItem();
			if (ci) {
				CClientDetailDialog dialog(ci->client);
				dialog.DoModal();
			}
			break;
		}
		case MP_ADDFRIEND:{
			const CChatItem* ci = GetCurrentChatItem();
			if (ci && !ci->client->IsFriend() )
				theApp.friendlist->AddFriend(ci->client);
			break;
		}
		case MP_REMOVE:{
			const CChatItem* ci = GetCurrentChatItem();
			if (ci)
				EndSession(ci->client);
			break;
		}
//==>Fix for closed  [cyrex2001]
#ifdef FIX_CLOSED
		default:
			return CClosableTabCtrl::OnCommand(wParam, lParam);
#endif //Fix for closed
//<==Fix for closed [cyrex2001]
	}
	return TRUE;
}
void CChatSelector::ShowChat()
{
	CChatItem* ci = GetCurrentChatItem();
	if (!ci)
		return;

	// show current chat window
	ci->log->ShowWindow(SW_SHOW);
	m_pParent->m_wndMessage.SetFocus();

	TCITEM item;
	item.mask = TCIF_IMAGE;
	item.iImage = 0;
	SetItem(GetCurSel(), &item);
	HighlightItem(GetCurSel(), FALSE);

	// hide all other chat windows
	item.mask = TCIF_PARAM;
	int i = 0;
	while (GetItem(i++, &item)){
		CChatItem* ci2 = (CChatItem*)item.lParam;
		if (ci2 != ci)
			ci2->log->ShowWindow(SW_HIDE);
	}

	ci->notify = false;
}
bool CChatSelector::SendMessage(const CString& rstrMessage)
{
	CChatItem* ci = GetCurrentChatItem();
	if (!ci)
		return false;

	if ((UINT)ci->history.GetCount() == thePrefs.GetMaxChatHistoryLines())
		ci->history.RemoveAt(0);
	ci->history.Add(rstrMessage);
	ci->history_pos = ci->history.GetCount();

	// advance spamfilter stuff
	ci->client->IncMessagesSent();
	ci->client->SetSpammer(false);
	if (ci->client->GetChatState() == MS_CONNECTING)
		return false;
	
	if (ci->client->GetChatCaptchaState() == CA_CAPTCHARECV)
		ci->client->SetChatCaptchaState(CA_SOLUTIONSENT);
	else if (ci->client->GetChatCaptchaState() == CA_SOLUTIONSENT)
		ASSERT( false ); // we responsed to a captcha but didn't heard from the client afterwards - hopefully its just lag and this message will get through
	else
		ci->client->SetChatCaptchaState(CA_ACCEPTING);

	


	// there are three cases on connectiing/sending the message:
	if (ci->client->socket && ci->client->socket->IsConnected())
	{
		// 1.) the client is connected already - this is simple, jsut send it
		ci->client->SendChatMessage(rstrMessage);
		if (thePrefs.GetIRCAddTimeStamp())
			AddTimeStamp(ci);
		ci->log->AppendKeyWord(thePrefs.GetUserNick(), SENT_TARGET_MSG_COLOR);
		ci->log->AppendText(_T(": "));
		ci->log->AppendText(rstrMessage + _T("\n"));
	}
	else if (ci->client->GetFriend() != NULL)
	{
		// We are not connected and this client is a friend - friends have additional ways to connect and additional checks
		// to make sure they are really friends, let the friend class is handling it
		ci->strMessagePending = rstrMessage;
		ci->client->SetChatState(MS_CONNECTING);
		ci->client->GetFriend()->TryToConnect(this);
	}
	else
	{
		// this is a normal client, who is not connected right now. just try to connect to the given IP, without any
		// additional checks or searchings.
		if (thePrefs.GetIRCAddTimeStamp())
			AddTimeStamp(ci);
		ci->log->AppendKeyWord(_T("*** ") + GetResString(IDS_CONNECTING), STATUS_MSG_COLOR);
		ci->strMessagePending = rstrMessage;
		ci->client->SetChatState(MS_CONNECTING);
		ci->client->TryToConnect(true);
	}
	return true;
}
bool CChatSelector::SendMessage(const CString& rstrMessage)
{
	CChatItem* ci = GetCurrentChatItem();
	if (!ci)
		return false;

	if (ci->history.GetCount() == thePrefs.GetMaxChatHistoryLines())
		ci->history.RemoveAt(0);
	ci->history.Add(rstrMessage);
	ci->history_pos = ci->history.GetCount();

	// advance spamfilter stuff
	ci->client->IncMessagesSent();
	ci->client->SetSpammer(false);
	if (ci->client->GetChatState() == MS_CONNECTING)
		return false;
//==>timestamp in chatwindow [shadow2004]
	if (thePrefs.GetIRCAddTimestamp())
		AddTimeStamp(ci);
//<==timestamp in chatwindow [shadow2004]
	if (ci->client->socket && ci->client->socket->IsConnected())
	{
		CSafeMemFile data;
		data.WriteString(rstrMessage, ci->client->GetUnicodeSupport());
		Packet* packet = new Packet(&data, OP_EDONKEYPROT, OP_MESSAGE);
		theStats.AddUpDataOverheadOther(packet->size);
		ci->client->socket->SendPacket(packet, true, true);

		ci->log->AppendKeyWord(thePrefs.GetUserNick(), RGB(1,180,20));
		ci->log->AppendText(_T(": "));
		ci->log->AppendText(rstrMessage + _T("\n"));
	}
	else
	{
		ci->log->AppendKeyWord(_T("*** ") + GetResString(IDS_CONNECTING), RGB(255,0,0));
		ci->strMessagePending = rstrMessage;
		ci->client->SetChatState(MS_CONNECTING);
//==>Fix for closed  [cyrex2001]
#ifdef FIX_CLOSED
		ci->client->TryToConnect(true);
#else //Fix for closed
		ci->client->TryToConnect();
#endif //Fix for closed
//<==Fix for closed [cyrex2001]
	}
	return true;
}
bool CChatSelector::SendMessage(const CString& message)
{
	if (!g_App.m_pMDlg->IsRunning())
		return false;

	CChatItem	*pChatItem = GetCurrentChatItem();

	if (pChatItem == NULL || pChatItem->m_pClient == NULL)
		return false;

	if (pChatItem->m_strHistoryArray.GetCount() == g_App.m_pPrefs->GetMaxChatHistoryLines())
		pChatItem->m_strHistoryArray.RemoveAt(0);
	pChatItem->m_strHistoryArray.Add(CString(message));
	pChatItem->m_iHistoryIndex = pChatItem->m_strHistoryArray.GetCount();

	if (pChatItem->m_pClient->GetChatState() == MS_CONNECTING)
		return false;

#ifdef OLD_SOCKETS_ENABLED
	if (pChatItem->m_pClient->IsHandshakeFinished())
	{
		SendMessagePacket(*pChatItem, message);

		COleDateTime	timelog(COleDateTime::GetCurrentTime());
		CString			strTmp;

		strTmp.Format(_T("%s (%s): "), g_App.m_pPrefs->GetUserNick(), timelog.Format(_T("%c")));
		pChatItem->m_pLog->AppendText(strTmp, RGB(1, 180, 20));
		pChatItem->m_pLog->AppendText(message + _T('\n'));
	}
	else
	{
		pChatItem->m_pLog->AppendText(_T("*** ") + GetResString(IDS_CONNECTING), RGB(255, 0, 0));
		pChatItem->m_strMessagePending = message;
		pChatItem->m_pClient->SetChatState(MS_CONNECTING);
		pChatItem->m_pClient->TryToConnect();
	}
#endif //OLD_SOCKETS_ENABLED
	return true;
}
void CChatSelector::OnContextMenu(CWnd*, CPoint point)
{
	TCHITTESTINFO hti = {0};
	::GetCursorPos(&hti.pt);
	ScreenToClient(&hti.pt);


	m_iContextIndex=this->HitTest(&hti);
	if (m_iContextIndex==-1)
		return;

	TCITEM item;
	item.mask = TCIF_PARAM;
	GetItem(m_iContextIndex, &item);

	const CChatItem* ci = (CChatItem*)item.lParam;
	if (ci == NULL)
		return;

	CFriend* pFriend = theApp.friendlist->SearchFriend(ci->client->GetUserHash(), 0, 0);

	CTitleMenu menu;
	menu.CreatePopupMenu();
	menu.AddMenuTitle(GetResString(IDS_CLIENT), true);

	menu.AppendMenu(MF_STRING, MP_DETAIL, GetResString(IDS_SHOWDETAILS), _T("CLIENTDETAILS"));

	GetCurrentChatItem();
	if (pFriend == NULL)
		menu.AppendMenu(MF_STRING, MP_ADDFRIEND, GetResString(IDS_IRC_ADDTOFRIENDLIST), _T("ADDFRIEND"));
	else
		menu.AppendMenu(MF_STRING, MP_REMOVEFRIEND, GetResString(IDS_REMOVEFRIEND), _T("DELETEFRIEND"));
	
	menu.AppendMenu(MF_STRING, MP_REMOVE, GetResString(IDS_FD_CLOSE));

	m_ptCtxMenu = point;
	ScreenToClient(&m_ptCtxMenu);
	menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}
void CChatSelector::OnContextMenu(CWnd* pWnd, CPoint point)
{ 
	const CChatItem* ci = GetCurrentChatItem();
	if (!ci)
		return;


	bool  isvalidconclient=false;
	if (ci->client &&  ci->client->HasValidHash())
		isvalidconclient=true;

	CTitleMenu ChatMenu;
	ChatMenu.CreatePopupMenu(); 
	ChatMenu.AddMenuTitle(GetResString(IDS_CW_MESSAGES),true);

	ChatMenu.AppendMenu(MF_STRING | isvalidconclient?MF_ENABLED : MF_GRAYED, MP_DETAIL, GetResString(IDS_SHOWDETAILS),_T("CLIENTDETAILS"));
	ChatMenu.AppendMenu(MF_STRING | (isvalidconclient && !ci->client->IsFriend() )? MF_ENABLED : MF_GRAYED , MP_ADDFRIEND, GetResString(IDS_ADDAFRIEND),_T("ADDFRIEND"));
	ChatMenu.AppendMenu(MF_STRING, MP_REMOVE, GetResString(IDS_FD_CLOSE), _T("DELETE") );

	ChatMenu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, point.x, point.y, this);
 	VERIFY( ChatMenu.DestroyMenu() );
	
}
void CChatSelector::ShowChat()
{
	int	iCurSel = GetCurSel();

	if (iCurSel == -1)
		return;

	bool	bWasChanged = (GetItemState(iCurSel, TCIS_HIGHLIGHTED) & TCIS_HIGHLIGHTED);

	SetItemState(iCurSel, TCIS_HIGHLIGHTED, NULL);

	CChatItem	*pChatItem = GetCurrentChatItem(), *pUpdateItem;

	if (pChatItem == NULL)
		return;

	pChatItem->m_pLog->SetRedraw(false);
	pChatItem->m_pLog->ShowWindow(SW_SHOW);
	if ((pChatItem->m_pLog->m_dwFlags & HTC_ISAUTOSCROLL) != 0 && bWasChanged)
		pChatItem->m_pLog->ScrollToLastLine();
	pChatItem->m_pLog->SetRedraw(true);

	TCITEM	tcitem;
	int		i = 0;

	tcitem.mask = TCIF_PARAM;
	while (GetItem(i++, &tcitem))
	{
		pUpdateItem = (CChatItem*)tcitem.lParam;
		if (pUpdateItem != pChatItem)
			pUpdateItem->m_pLog->ShowWindow(SW_HIDE);
	}

	pChatItem->m_pLog->SetTitle(pChatItem->m_pClient->GetUserName());
	pChatItem->m_bNotify = false;
	g_App.m_pMDlg->m_wndChat.m_ctlInputText.SetFocus();
}