// NEO: ASF - [AdvancedServerFilter] -- Xanatos -->

#include "stdafx.h"
#include "emule.h"
#include "emuledlg.h"
#include "serverwnd.h"
#include "serverlistctrl.h"
#include "Preferences.h"
#include "ServerFilter.h"
#include "ServerList.h"
#include "types.h"
#include "Server.h"
#include "Log.h"
#include "OtherFunctions.h"

IMPLEMENT_DYNAMIC(CServerFilter, CModelessDialog) // NEO: MLD - [ModelesDialogs]
CServerFilter::CServerFilter(CServerList* sl)
: CModelessDialog(CServerFilter::IDD, 0) // NEO: MLD - [ModelesDialogs]
{
	serverlist = sl;
	m_changes = false;
	serverlist->SaveServermetToFile();
}

CServerFilter::~CServerFilter()
{
}

void CServerFilter::DoDataExchange(CDataExchange* pDX)
{
	CModelessDialog::DoDataExchange(pDX); // NEO: MLD - [ModelesDialogs]
	DDX_Control(pDX, IDC_FILTERLIST1, filterlist1);
	DDX_Control(pDX, IDC_FILTERLIST2, filterlist2);
	DDX_Control(pDX, IDC_FILTEROP, filterop);
}

BOOL CServerFilter::OnInitDialog()
{
	CModelessDialog::OnInitDialog(); // NEO: MLD - [ModelesDialogs]
	Localize();

	((CEdit*)GetDlgItem(IDC_FILTER1))->SetLimitText(25);
	((CEdit*)GetDlgItem(IDC_FILTER2))->SetLimitText(25);

	return (serverlist->SaveServermetToFile());
}

BEGIN_MESSAGE_MAP(CServerFilter, CModelessDialog) // NEO: MLD - [ModelesDialogs]
	ON_BN_CLICKED(IDOK, OnBnClickedApply)
	ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
	ON_BN_CLICKED(IDC_FILTER_REMOVE, OnBnClickedFilterRemove)
	ON_CBN_SELCHANGE(IDC_FILTERLIST1, OnChangeFilterlist)
	ON_CBN_SELCHANGE(IDC_FILTERLIST2, OnChangeFilterlist)
	ON_CBN_SELCHANGE(IDC_FILTEROP, OnChangeFilterOp)
END_MESSAGE_MAP()

void CServerFilter::OnBnClickedApply()
{
	OnOK();
}

void CServerFilter::OnBnClickedCancel()
{
	if (m_changes) {
		CString tmp;
		tmp.Format(_T("%sserver_met.old"),thePrefs.GetConfigDir());
		if (serverlist->AddServerMetToList(tmp,false)) {
			theApp.emuledlg->serverwnd->serverlistctrl.ShowServers();
			theApp.emuledlg->serverwnd->serverlistctrl.ShowServerCount();
			ModLog(GetResString(IDS_X_SERVER_FILTERED_RESTORE));
		}
	}
	OnCancel();
}

void CServerFilter::OnBnClickedFilterRemove()
{
	int count=0;
	int scount=0;
	bool keepstatic=(IsDlgButtonChecked(IDC_FILTERSTATIC)!=0);
	theApp.emuledlg->serverwnd->serverlistctrl.Hide();
	for (POSITION pos=serverlist->list.GetHeadPosition(); pos!=NULL; serverlist->list.GetNext(pos)) {
		CServer* cur_srv=serverlist->list.GetAt(pos);
		if (FilterQuery(cur_srv)) {
			if (cur_srv->IsStaticMember()) {
				if (keepstatic)
					continue;
				if (!theApp.emuledlg->serverwnd->serverlistctrl.StaticServerFileRemove(cur_srv))
					continue;
				scount++;
			}
			serverlist->RemoveServer(cur_srv);
			count++;
			if ((pos=serverlist->list.GetHeadPosition())==NULL)
				break;
		}
	}
	theApp.emuledlg->serverwnd->serverlistctrl.Visable();
	if (count) {
		theApp.emuledlg->serverwnd->serverlistctrl.ShowServers();
		theApp.emuledlg->serverwnd->serverlistctrl.ShowServerCount();
		ModLog(GetResString(IDS_X_SERVER_FILTERED2),count,scount);
		m_changes=true;
	}
}

void CServerFilter::OnChangeFilterlist()
{
	if (filterlist1.GetCurSel()==filterlist2.GetCurSel())
		if (filterlist1.GetCurSel()==0)
			filterlist2.SetCurSel(1);
		else
			filterlist2.SetCurSel(0);
}

void CServerFilter::OnChangeFilterOp()
{
	bool on=(filterop.GetCurSel()!=0);
	GetDlgItem(IDC_FILTERLIST2)->EnableWindow(on);
	GetDlgItem(IDC_FILTER2)->EnableWindow(on);
}

void CServerFilter::Localize()
{
	SetWindowText(GetResString(IDS_X_ADVANCED_SERVER_FILTER));
	GetDlgItem(IDC_STATIC1)->SetWindowText(GetResString(IDS_X_SERVER_FILTER_ONE));
	GetDlgItem(IDC_STATIC2)->SetWindowText(GetResString(IDS_X_SERVER_FILTER_OP));
	GetDlgItem(IDC_STATIC3)->SetWindowText(GetResString(IDS_X_SERVER_FILTER_TWO));
	GetDlgItem(IDC_FILTERSTATIC)->SetWindowText(GetResString(IDS_X_FILTER_STATIC));
	GetDlgItem(IDC_FILTERDATALESS)->SetWindowText(GetResString(IDS_X_FILTER_DATALESS));
	GetDlgItem(IDC_FILTER_REMOVE)->SetWindowText(GetResString(IDS_X_FILTER_REMOVE));
	GetDlgItem(IDOK)->SetWindowText(GetResString(IDS_X_DONE));
	GetDlgItem(IDCANCEL)->SetWindowText(GetResString(IDS_CANCEL));

	while (filterlist1.GetCount()>0) filterlist1.DeleteString(0);
	filterlist1.AddString(GetResString(IDS_PING));
	filterlist1.AddString(GetResString(IDS_LUSERS));
	filterlist1.AddString(GetResString(IDS_MAXCLIENT));
	filterlist1.AddString(GetResString(IDS_FILES));
	filterlist1.AddString(GetResString(IDS_HARDFILES));
	filterlist1.AddString(GetResString(IDS_SOFTFILES));
	filterlist1.AddString(GetResString(IDS_FAILED));
	filterlist1.AddString(GetResString(IDS_SL_SERVERNAME));
	filterlist1.AddString(GetResString(IDS_DESCRIPTION));
	filterlist1.SetCurSel(0);

	while (filterlist2.GetCount()>0) filterlist2.DeleteString(0);
	filterlist2.AddString(GetResString(IDS_PING));
	filterlist2.AddString(GetResString(IDS_LUSERS));
	filterlist2.AddString(GetResString(IDS_MAXCLIENT));
	filterlist2.AddString(GetResString(IDS_FILES));
	filterlist2.AddString(GetResString(IDS_HARDFILES));
	filterlist2.AddString(GetResString(IDS_SOFTFILES));
	filterlist2.AddString(GetResString(IDS_FAILED));
	filterlist2.AddString(GetResString(IDS_SL_SERVERNAME));
	filterlist2.AddString(GetResString(IDS_DESCRIPTION));
	filterlist2.SetCurSel(1);

	while (filterop.GetCount()>0) filterop.DeleteString(0);
	filterop.AddString(GetResString(IDS_X_DISABLED));
	filterop.AddString(GetResString(IDS_X_AND));
	filterop.AddString(GetResString(IDS_X_OR));
	filterop.AddString(GetResString(IDS_X_NOT_AND));
	filterop.AddString(GetResString(IDS_X_NOT_OR));
	filterop.AddString(GetResString(IDS_X_XOR));
	filterop.AddString(GetResString(IDS_X_NOR));
	filterop.AddString(GetResString(IDS_X_NAND));
	filterop.SetCurSel(0);

	GetDlgItem(IDC_FILTER1)->SetWindowText(_T("10000"));
	GetDlgItem(IDC_FILTER2)->SetWindowText(_T("1000"));

	CheckDlgButton(IDC_FILTERSTATIC, TRUE);
	CheckDlgButton(IDC_FILTERDATALESS, TRUE);

}

uint32 CServerFilter::ServerItem(CServer* srv, int item)
{
	switch (item) {
	case 0: return (uint32)(srv->GetPing());
	case 1: return (uint32)(srv->GetUsers());
	case 2: return (uint32)(srv->GetMaxUsers());
	case 3: return (uint32)(srv->GetFiles());
	case 4: return (uint32)(srv->GetHardFiles());
	case 5: return (uint32)(srv->GetSoftFiles());
	case 6: return (uint32)(srv->GetFailedCount());
	default: return (uint32)0;
	}
}

bool CServerFilter::FilterQuery(CServer* srv)
{
	CString filter1,filter2;
	GetDlgItemText(IDC_FILTER1, filter1);
	GetDlgItemText(IDC_FILTER2, filter2);

	int sel1=filterlist1.GetCurSel();
	int sel2=filterlist2.GetCurSel();
	bool b1=false;
	bool b2=false;
	bool removedataless=(IsDlgButtonChecked(IDC_FILTERDATALESS)!=0);
	if (filter1!=_T("")) {
		if (sel1==7) {
			CString name(srv->GetListName());
			b1=(name.Find(filter1)!=-1);
		}
		else if (sel1==8) {
			CString desc(srv->GetDescription());
			b1=(desc.Find(filter1)!=-1);
		}
		else {
			uint32 n1=(uint32)StrToInt(filter1);
			uint32 si1=ServerItem(srv,sel1);
			if (sel1==0 || sel1==6)
				b1=(si1>n1);
			else
				b1=(si1<n1);
			if (removedataless && si1!=6)
				b1|=(si1==0);
		}
	}
	if (sel2 && filter2!=_T("")) {
		if (sel2==7) {
			CString name(srv->GetListName());
			b2=(name.Find(filter2)!=-1);
		}
		else if (sel2==8) {
			CString desc(srv->GetDescription());
			b2=(desc.Find(filter2)!=-1);
		}
		else {
			uint32 n2=(uint32)StrToInt(filter2);
			uint32 si2=ServerItem(srv,sel2);
			if (sel2==0 || sel2==6)
				b2=(si2>n2);
			else
				b2=(si2<n2);
			if (removedataless && si2!=6)
				b2|=(si2==0);
		}
	}
	switch (filterop.GetCurSel()) {
	case 0: return (b1);
	case 1: return (b1 && b2);
	case 2: return (b1 || b2);
	case 3: return (b1 && !b2);
	case 4: return (b1 || !b2);
	case 5: return (b1!=b2);
	case 6: return (!(b1 || b2));
	case 7: return (!(b1 && b2));
	default: return false;
	}
	// no need to del (no match found), so query returns false
}
// NEO: ASF END <-- Xanatos --