// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "pch.h"
#include <process.h>

#include "..\..\..\..\Source\WiFi\wclWiFi.h"

using namespace std;

using namespace wclCommon;
using namespace wclWiFi;

string wtoa(const tstring& w)
{
	return string(w.begin(), w.end());
}

class CSoftAp
{
private:
	HANDLE	TerminateEvent;
	HANDLE	Thread;

	void SoftApStopped(void* Sender)
	{
		UNREFERENCED_PARAMETER(Sender);

		cout << endl << "WiFi Direct Soft AP has been stopped" << endl;
	}

	void SoftApDeviceConnected(void* Sender, CwclWiFiDirectDevice* const Device)
	{
		UNREFERENCED_PARAMETER(Sender);

		cout << "Device has been connected" << endl;
		cout << "  Name: " << wtoa(Device->Name).c_str() << endl;
		cout << "  Local IP addresss: " << wtoa(Device->LocalAddress).c_str() << endl;
		cout << "  Remote IP addresss: " << wtoa(Device->RemoteAddress).c_str() << endl;
	}

	void SoftApDeviceDisconnected(void* Sender, CwclWiFiDirectDevice* const Device)
	{
		UNREFERENCED_PARAMETER(Sender);

		cout << "Device " << wtoa(Device->Name).c_str() << " has been disconnected" << endl;
	}

	void SoftApStarted(void* Sender)
	{
		cout << "WiFi Direct Soft AP has been started" << endl;

		tstring ts;
		int Res = ((CwclWiFiSoftAP*)Sender)->GetSsid(ts);
		if (Res != WCL_E_SUCCESS)
			cout << "  SSID: read error 0x" << hex << Res << dec << endl;
		else
			cout << "  SSID: " << wtoa(ts).c_str() << endl;

		Res = ((CwclWiFiSoftAP*)Sender)->GetPassphrase(ts);
		if (Res != WCL_E_SUCCESS)
			cout << "  Passphrase: read error 0x" << hex << Res << dec << endl;
		else
			cout << "  Passphrase: " << wtoa(ts).c_str() << endl;
	}

	static UINT __stdcall _ThreadProc(LPVOID Param)
	{
		((CSoftAp*)Param)->ThreadProc();
		return 0;
	}

	void ThreadProc()
	{
		CwclWiFiSoftAP* Ap = new CwclWiFiSoftAP();
		Ap->MessageProcessing = mpAsync;
		__hook(&CwclWiFiSoftAP::OnStarted, Ap, &CSoftAp::SoftApStarted);
		__hook(&CwclWiFiSoftAP::OnStopped, Ap, &CSoftAp::SoftApStopped);
		__hook(&CwclWiFiSoftAP::OnDeviceConnected, Ap, &CSoftAp::SoftApDeviceConnected);
		__hook(&CwclWiFiSoftAP::OnDeviceDisconnected, Ap, &CSoftAp::SoftApDeviceDisconnected);

		int Res = Ap->Start(_T("WiFi_Framework"), _T("12345678"));
		if (Res != WCL_E_SUCCESS)
			cout << "Failed to start WiFi Direct Soft AP: 0x" << hex << Res << dec << endl;

		WaitForSingleObject(TerminateEvent, INFINITE);

		if (Ap->Active)
		{
			Res = Ap->Stop();
			if (Res != WCL_E_SUCCESS)
				cout << "Failed to stop WiFi Direct Soft AP: 0x" << hex << Res << dec << endl;
		}
		__unhook(Ap);
		delete Ap;
	}

public:
	void Run()
	{
		TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		Thread = (HANDLE)_beginthreadex(NULL, 0, _ThreadProc, this, 0, NULL);
	}

	void Stop()
	{
		SetEvent(TerminateEvent);
		WaitForSingleObject(Thread, INFINITE);
		CloseHandle(Thread);
		CloseHandle(TerminateEvent);
	}
};


int main(int argc, char **argv)
{
	UNREFERENCED_PARAMETER(argc);
	UNREFERENCED_PARAMETER(argv);

	system("cls");
	cout << "WIFI DIRECT SOFT AP DEMO" << endl;
	cout << "========================" << endl;
	CSoftAp* Ap = new CSoftAp();
	Ap->Run();
	system("pause");
	Ap->Stop();
	delete Ap;
}
