// MainDlg.cpp : implementation of the CMainDlg class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MainDlg.h"
#include "StabtypeControl.h"
#include "CLashConfig.h"
#include "SysProxy.h"

CMainDlg::CMainDlg() : SHostWnd(_T("LAYOUT:XML_MAINWND")), m_base_clash(nullptr), pNodeAdapter(nullptr)
{
	m_bLayoutInited = FALSE;
	m_refresh = false;
	m_connect_mage = nullptr;
}

CMainDlg::~CMainDlg()
{
	if (m_base_clash)
	{
		delete m_base_clash;
		m_base_clash = nullptr;
	}

	if (m_connect_mage)
	{
		delete m_connect_mage;
		m_connect_mage = nullptr;
	}
}

int CMainDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	SetMsgHandled(FALSE);
	return 0;
}

BOOL CMainDlg::OnInitDialog(HWND hWnd, LPARAM lParam)
{
	m_bLayoutInited = TRUE;
	Init();
	OnConnecting_UdateUi(false, CONNECT_NODE_MSG,L"");

	/*CManageNetWork m_manageNetwork;
	m_manageNetwork.GetNodeList();*/
	CManageNetWork::getSingletonPtr()->GetNodeList();
	return 0;
}

void CMainDlg::Init()
{
	CApp::getSingletonPtr()->SetupDataDirectory();	

	//FindChildByName2<STabCtrl>(L"tabmain");
	if (!m_base_clash)
	{
		m_base_clash = new CLashConfig();
		m_base_clash->InitClash();
		m_base_clash->StartClash();
	}

	if (!m_connect_mage)
	{
		m_connect_mage = new CConnectMage();
		m_connect_mage->SetClashConfig((CLashConfig*)m_base_clash);
		m_connect_mage->Init();
	}

	SysMode list;
	list.id = 0;
	list.name = L"系统代理";
	list.proxy_mode = PROXY_MODE::sys_mode;
	SysMode list1;
	list1.id = 1;
	list1.name = L"网卡代理";
	list1.proxy_mode = PROXY_MODE::tun_mode;
	m_sysmode_vctor.push_back(list);
	m_sysmode_vctor.push_back(list1);
	
	RouteMode route;
	route.id = 0;
	route.name = L"智能";
	route.route_mode = ROUT_MODE::cn_mode;

	RouteMode route2;
	route2.id = 1;
	route2.name = L"全局";
	route2.route_mode = ROUT_MODE::qg_mode;

	
	
	m_route_vctor.push_back(route);

	m_route_vctor.push_back(route2);

	

	StabtypeControl* tabtype = FindChildByName2<StabtypeControl>(L"sysmode");
	if (tabtype)
	{
		for (auto i = 0; i < m_sysmode_vctor.size(); i++)
		{
			tabtype->ItemCreateChildren(m_sysmode_vctor[i].id, m_sysmode_vctor[i].name,i == 0 ? true : false );
		}
		if (m_sysmode_vctor.size() > 0)
		{
			CApp::getSingletonPtr()->SetSysMode(PROXY_MODE::sys_mode);
		}
		tabtype->GetEventSet()->subscribeEvent(EVT_TABTYPE_CONTROL,
			Subscriber(&CMainDlg::OnSysModeType, this));
	}

	StabtypeControl* routetype = FindChildByName2<StabtypeControl>(L"routemode");
	if (routetype)
	{
		for (auto i = 0; i < m_route_vctor.size(); i++)
		{
			routetype->ItemCreateChildren(m_route_vctor[i].id, m_route_vctor[i].name, i == 0 ? true : false);
		}
		if (m_route_vctor.size() > 0)
		{
			CApp::getSingletonPtr()->SetRouteMode(ROUT_MODE::cn_mode);
		}
		routetype->GetEventSet()->subscribeEvent(EVT_TABTYPE_CONTROL,
			Subscriber(&CMainDlg::OnRouteModeType, this));
	}

	auto funRecent2 = std::bind(&CMainDlg::ShowView, this, std::placeholders::_1, std::placeholders::_2);
	auto funRecent3 = std::bind(&CMainDlg::ItemRClick, this, std::placeholders::_1);
	STileView* pTileView = FindChildByName2<STileView>("nodeList");
	if (pTileView)
	{
		/*std::vector<SStringT> vctInfo{ L"Test1",L"Fun1", L"Ming", L"Get" };*/
		pNodeAdapter = new CNodeAdapter(pTileView);
		pTileView->SetAdapter(pNodeAdapter);
		pNodeAdapter->SetShowView(funRecent2);
		pNodeAdapter->SetItemClickCallBack(funRecent3);
		//pNodeAdapter->Release();
	}

	UpDateUserInfo();
}

void CMainDlg::OnNode()
{
	STabCtrl* m_tab_main = FindChildByName2<STabCtrl>(L"tabmain");
	if (m_tab_main)
	{
		m_tab_main->SetCurSel(1);
		m_tab_main->Invalidate();
	}



}

void CMainDlg::OnBackNode()
{
	STabCtrl* m_tab_main = FindChildByName2<STabCtrl>(L"tabmain");
	if (m_tab_main)
	{
		m_tab_main->SetCurSel(0);
		m_tab_main->Invalidate();
	}
}

bool CMainDlg::OnSysModeType(SOUI::EventArgs* pEvt)
{
	SOUI::EventTabtypeControl* pTestControlEvent =
		SOUI::sobj_cast<SOUI::EventTabtypeControl>(pEvt);
	if (!pTestControlEvent)
	{
		return false;
	}
	CApp::getSingletonPtr()->SetSysMode(m_sysmode_vctor[pTestControlEvent->nIndex].proxy_mode);
	return true;
}

bool CMainDlg::OnRouteModeType(SOUI::EventArgs* pEvt)
{
	SOUI::EventTabtypeControl* pTestControlEvent =
		SOUI::sobj_cast<SOUI::EventTabtypeControl>(pEvt);
	if (!pTestControlEvent)
	{
		return false;
	}
	CApp::getSingletonPtr()->SetRouteMode(m_route_vctor[pTestControlEvent->nIndex].route_mode);


	return true;
}

void CMainDlg::OnAuthFinish(SOUI::EventArgs* pEvt)
{
	EventAUTH* e2 = sobj_cast<EventAUTH>(pEvt);
	if (!e2)
	{
		return;
	}

	if (e2->status != 200)
	{
		OnConnecting_UdateUi(TRUE, L"未连接");
		SMessageBox(m_hWnd, e2->msg, L"提醒", 0);
	}
	else
	{
		OnConnect();
	}

}

void CMainDlg::OnServerListFinish(SOUI::EventArgs* pEvt)
{
	EventNodeList* e2 = sobj_cast<EventNodeList>(pEvt);
	if (!e2)
	{
		return;
	}

	if (e2->status != 200 )
	{
		if (m_refresh)
		{
			SStatic* refresh_status = FindChildByName2<SStatic>(L"refresh_status");
			if (refresh_status)
			{
				refresh_status->SetWindowTextW(e2->msg);
				refresh_status->Invalidate();
			}


			SStatic* text_touch = FindChildByName2<SStatic>(L"text_touch");
			if (text_touch)
			{
				text_touch->SetWindowTextW(e2->msg);
				text_touch->Invalidate();
			}

			OnConnecting_UdateUi(TRUE, e2->msg);
			m_refresh = false;
		}
		else {
			UPdateMsgStatus(e2->msg);
			OnConnecting_UdateUi(TRUE, e2->msg);
		}
		
	}
	else if (e2->status == 200)
	{
		if (m_refresh)
		{
			SStatic* refresh_status = FindChildByName2<SStatic>(L"refresh_status");
			if (refresh_status)
			{
				refresh_status->SetWindowTextW(L"更新完成..");
				refresh_status->Invalidate();
			}

			SStatic* text_touch = FindChildByName2<SStatic>(L"text_touch");
			if (text_touch)
			{
				text_touch->SetWindowTextW(L"更新完成...");
				text_touch->Invalidate();
			}
			m_refresh = false;
		}
		else {
			OnConnecting_UdateUi(TRUE, SUEECS_NODE_MSG);

			CManageNetWork::getSingletonPtr()->GetVersion();
		}
	

		//更新 节点数据
		if (pNodeAdapter)
		{
			pNodeAdapter->SetCount(CApp::getSingletonPtr()->GetServerList()->vectlistmode.size());
		}
	}
 
}

void CMainDlg::OnVersionFinish(SOUI::EventArgs* pEvt)
{
	EventVerions* e2 = sobj_cast<EventVerions>(pEvt);
	if (!e2)
	{
		return;
	}

	if (e2->status == 200)
	{
		UPdateVersionMsgStatus(e2->msg, S_CA2W(CApp::getSingletonPtr()->GetVerinfo()->appdownload.c_str()),e2->versionupdate);
	}
	else  {
		UPdateVersionMsgStatus(e2->msg);
	}
}

void CMainDlg::OnConnectFinish(SOUI::EventArgs* pEvt)
{
	EventConnect* e2 = sobj_cast<EventConnect>(pEvt);
	if (!e2)
	{
		return;
	}

	if (e2->status == ConnectState::Stop)
	{
		OnConnecting_UdateUi(true, e2->msg, L"", false);
		OnUpdataNodeName();

	} else if (e2->status == ConnectState::SwitchConfigSuccEss)
	{
		OnConnecting_UdateUi(true, e2->msg, L"", true);
		OnUpdataNodeName();

	} else if (e2->status == ConnectState::SwitchNodeSuccEss)
	{
		OnConnecting_UdateUi(true, e2->msg, L"", true);
		OnUpdataNodeName();
	}
	 
}

void CMainDlg::OnClashPreoceeQutFinish(SOUI::EventArgs* pEvt)
{
	if (m_base_clash)
	{
		m_base_clash->StartClash();


	}

	if (m_connect_mage)
	{
		m_connect_mage->ReqConfig();
	}
}

void CMainDlg::UPdateMsgStatus(SStringW msg)
{
	//text_touch
	SStatic* text_touch = FindChildByName2<SStatic>(L"text_touch");
	if (text_touch)
	{
		text_touch->SetWindowTextW(msg);
		text_touch->EnableWindow(FALSE);
		text_touch->Invalidate();
	}

}

void CMainDlg::UPdateVersionMsgStatus(SStringW msg, SStringW url,int appversionupdate)
{
	SLink* app_version = FindChildByName2<SLink>(L"app_version");
	if (app_version)
	{
		if (!url.IsEmpty())
		{
			app_version->SetAttribute(L"href", url);
		}
		
		app_version->SetWindowTextW(msg);
		app_version->EnableWindow(true);
		app_version->Invalidate();
	}

	if (appversionupdate == 1)
	{
		SMessageBox(m_hWnd, msg, L"更新提示", 0);
		::ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWNORMAL);
	}

}

void CMainDlg::UpDateUserInfo()
{
	CUserInfo* userinfo = CApp::getSingletonPtr()->GetUserinfo();
	if (!userinfo)
	{
		return;
	}
	SStatic* username = FindChildByName2<SStatic>(L"username");
	if (username)
	{
		SStringW enable = L"禁用";
		if (CApp::getSingletonPtr()->GetUserinfo()->enable == true)
		{
			enable =  L"启用" ;
		}
		else {
			enable = L"禁用";
		}
		username->SetWindowTextW(SStringW().Format(L"用户名:%s 代理状态:%s", S_CA2W(userinfo->username.c_str()), enable));
		username->EnableWindow(FALSE);
		username->Invalidate();
	}

	SStatic* username_time = FindChildByName2<SStatic>(L"username_time");
	if (username_time)
	{
		username_time->SetWindowTextW(SStringW().Format(L"到期时间:%s", S_CA2W(userinfo->expiretime.c_str())));
		username_time->EnableWindow(FALSE);
		username_time->Invalidate();
	}

	SStatic* username_liulaing = FindChildByName2<SStatic>(L"username_liulaing");
	if (username_liulaing)
	{
		username_liulaing->SetWindowTextW(SStringW().Format(L"用户流量:%s", S_CA2W(userinfo->unusedTraffic.c_str())));
		username_liulaing->EnableWindow(FALSE);
		username_liulaing->Invalidate();
	}

	SLink* username_jiaocheng = FindChildByName2<SLink>(L"username_jiaocheng");
	if (username_jiaocheng)
	{
		username_jiaocheng->SetAttribute(L"href", CApp::getSingletonPtr()->GetSysconfig()->GetTutorialLink());
		username_jiaocheng->EnableWindow(true);
		username_jiaocheng->Invalidate();
	}

	SLink* username_chongzhi = FindChildByName2<SLink>(L"username_chongzhi");
	if (username_chongzhi)
	{
		username_chongzhi->SetAttribute(L"href", CApp::getSingletonPtr()->GetSysconfig()->GetBuyLink());
		username_chongzhi->EnableWindow(true);
		username_chongzhi->Invalidate();
	}

	SLink* username_tuiguang = FindChildByName2<SLink>(L"username_tuiguang");
	if (username_tuiguang)
	{
		username_tuiguang->SetAttribute(L"href", CApp::getSingletonPtr()->GetSysconfig()->GetAffLink());
		username_tuiguang->EnableWindow(true);
		username_tuiguang->Invalidate();
	}

	SLink* username_online_kf = FindChildByName2<SLink>(L"username_online_kf");
	if (username_online_kf)
	{
		username_online_kf->SetAttribute(L"href", CApp::getSingletonPtr()->GetSysconfig()->GetOnlineLink());
		username_online_kf->EnableWindow(true);
		username_online_kf->Invalidate();
	}

	if (m_base_clash)
	{
		auto http_prot = m_base_clash->GetHttpPort();
		auto sock_prot = m_base_clash->GetSocketPort();
		SStatic* httpproxy = FindChildByName2<SStatic>(L"httpproxy");
		if (httpproxy)
		{
			httpproxy->SetWindowTextW(SStringW().Format(L"http proxy 127.0.0.1:%d", http_prot));
			httpproxy->EnableWindow(FALSE);
			httpproxy->Invalidate();
		}

		SStatic* socksproxy = FindChildByName2<SStatic>(L"socksproxy");
		if (socksproxy)
		{
			socksproxy->SetWindowTextW(SStringW().Format(L"socks proxy 127.0.0.1:%d", sock_prot));
			socksproxy->EnableWindow(FALSE);
			socksproxy->Invalidate();
		}
	}
}

void CMainDlg::ShowView(int nItem, SWindow* pItem)
{
	if (!pNodeAdapter)
	{
		return;
	}
	CServerList* p = CApp::getSingletonPtr()->GetServerList();

	if (!p)
	{
		return;
	}

	auto vectorserverlist = p->vectlistmode;
	
	SStatic* servername = pItem->FindChildByName2<SStatic>(L"servername");
	if (servername)
	{
		servername->SetWindowTextW(S_CA2W(vectorserverlist[nItem].name.c_str(),CP_UTF8));
	}

	SStatic* serverms = pItem->FindChildByName2<SStatic>(L"serverms");
	if (serverms)
	{

		SStringW msg = L"";
		SStringW color = L"";

		//SLOG_DEBUG(vectorserverlist[nItem].online_users);

		if(vectorserverlist[nItem].online_users < 29) { //空闲
			msg = L"空闲";
			color = L"#6aa84f";
		}
		else if (vectorserverlist[nItem].online_users > 30 && vectorserverlist[nItem].online_users < 150) {
			msg = L"正常";
			color = L"#6aa84f";
		}
		else if (vectorserverlist[nItem].online_users > 151 && vectorserverlist[nItem].online_users < 200) {
			msg = L"繁忙";
			color = L"#7c7c7c";
		}
		else if (vectorserverlist[nItem].online_users > 201 && vectorserverlist[nItem].online_users < 500){
			msg = L"拥挤";
			color = L"#696969";
		}
		else {
			msg = L"维护";
			color = L"#696969";
		}
		serverms->SetWindowTextW(msg);
		serverms->SetAttribute(L"colorText", color);
	}
}

void CMainDlg::ItemRClick(int nItem)
{
	CServerList* p = CApp::getSingletonPtr()->GetServerList();

	if (!p)
	{
		return;
	}

	auto vectorserverlist = p->vectlistmode;
	auto name = vectorserverlist[nItem].name;

	OnBackNode();

	SLOG_DEBUG(name.c_str());

	//切换CLash api  
	if (m_connect_mage)
	{
		m_connect_mage->SetNodeName(name);
		m_connect_mage->ReqConfig();
	}

	CApp::getSingletonPtr()->SetSelect_node(name);

	OnUpdataNodeName();
}

void CMainDlg::OnRefresh()
{
	if (m_refresh)
	{
		return;
	}
	//更新 节点数据
	if (pNodeAdapter)
	{
		pNodeAdapter->SetCount(0);
	}
	CManageNetWork::getSingletonPtr()->GetNodeList();
	m_refresh = true;
	//refresh_status
	SStatic* refresh_status = FindChildByName2<SStatic>(L"refresh_status");
	if (refresh_status)
	{
		refresh_status->SetWindowTextW(L"正在刷新节点...");
		refresh_status->Invalidate();
	}

	SStatic* text_touch = FindChildByName2<SStatic>(L"text_touch");
	if (text_touch)
	{
		text_touch->SetWindowTextW(L"正在刷新节点...");
		text_touch->Invalidate();
	}
}

void CMainDlg::OnConnect()
{
	if (!m_connect_mage)
	{
		return;
	}

	if (m_connect_mage->GetConnectStatus() == ConnectState::Stop)
	{
		m_connect_mage->ReqConfig();
		OnConnecting_UdateUi(false, L"正在启动中..", L"", false);
	}
	else {
		m_connect_mage->Stop();
		DisableSystemProxy();
		OnConnecting_UdateUi(true, L"停止成功", L"", false);
	}
}

void CMainDlg::OnAuth()
{
	if (m_connect_mage->GetConnectStatus() == ConnectState::Stop) {
		OnConnecting_UdateUi(false, L"正在验证中..", L"", false);
		CManageNetWork::getSingletonPtr()->Auth();
	}
	else {
		OnConnect();
	}
}

void CMainDlg::OnUpdataNodeName(SStringW nodename)
{
	SStatic* node_name = FindChildByName2<SStatic>(L"node_name");
	if (node_name)
	{
		if (nodename.IsEmpty())
		{ 
			if (!CApp::getSingletonPtr()->GetSelect_node().empty())
			{
				node_name->SetWindowTextW(S_CA2W(CApp::getSingletonPtr()->GetSelect_node().c_str(), CP_UTF8));
			}
			else {
				if (!CApp::getSingletonPtr()->GetServerList()->node_name.empty());
				{
					node_name->SetWindowTextW(S_CA2W(CApp::getSingletonPtr()->GetServerList()->node_name.c_str(), CP_UTF8));
				}
			}

		}
		else {
			//node_name->SetWindowTextW(nodename);
		}
	
		node_name->Invalidate();
	}
}

//连接状态 更新UI
void CMainDlg::OnConnecting_UdateUi(bool b,SStringW msg,SStringW acc_msg,bool connect)
{
	SWindow* selectnode = FindChildByName2<SWindow>(L"selectnode");
	if (selectnode)
	{
		selectnode->EnableWindow(b);
		selectnode->Invalidate();
	}

	SImageButton* Refresh = FindChildByName2<SImageButton>(L"OnRefresh");
	if (Refresh)
	{
		Refresh->EnableWindow(b);
		Refresh->Invalidate();
	}

	SStatic* text_touch = FindChildByName2<SStatic>(L"text_touch");
	if (text_touch)
	{
		text_touch->SetWindowTextW(msg);
		text_touch->EnableWindow(b);
		text_touch->Invalidate();
	}

	SImageButton* connect_touch = FindChildByName2<SImageButton>(L"connect_touch");

	if (connect_touch)
	{
		if (connect)
		{
			connect_touch->SetAttribute(L"skin", L"skin_btnswitchon");
		}
		else {
			connect_touch->SetAttribute(L"skin", L"skin_btnswitchoff");
		}
		connect_touch->EnableWindow(b);
		connect_touch->Invalidate();
	}
}
//TODO:消息映射
void CMainDlg::OnClose()
{
	ShowWindow(SW_HIDE);
}

void CMainDlg::OnMaximize()
{
	SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE);
}
void CMainDlg::OnRestore()
{
	SendMessage(WM_SYSCOMMAND, SC_RESTORE);
}
void CMainDlg::OnMinimize()
{
	SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
}
void ShowConsoleWindow(bool show) {
	const HWND hWnd = CProcessManager::getSingletonPtr()->GetConsoleWindow();
	if (hWnd)
	{
		ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
		if (show)
			SetForegroundWindow(hWnd);
	}
}
void CMainDlg::OnCommand(UINT uNotifyCode, int nID, HWND wndCtl) {

	if (uNotifyCode == 0)
	{
		if (nID == 2)
		{
			const HWND hWndConsole = CProcessManager::getSingletonPtr()->GetConsoleWindow();
			if (hWndConsole)
			{
				ShowConsoleWindow(!::IsWindowVisible(hWndConsole));
			}
			else
				ShowConsoleWindow(false);
		}
		else if (nID == 6) {
			if (m_refresh)
			{
				SMessageBox(m_hWnd, L"正在刷新,无法退出", L"提示", 0);
			}
			else {
				if (m_base_clash)
				{
					DisableSystemProxy();
					CProcessManager::getSingletonPtr()->SendStopSignal();
					WaitForSingleObject(CProcessManager::getSingletonPtr()->GetClashProcessInfo().hProcess, 3000);
					CProcessManager::getSingletonPtr()->Stop();
					m_base_clash->StopClash();
					delete m_base_clash;
					m_base_clash = nullptr;
				}
				CSimpleWnd::DestroyWindow();
			}
		}
 
	}
}