/*
 *  psychlops_app_state_Win32.h
 *  Psychlops Standard Library (Universal)
 *
 *  Last Modified 2007/06/22 by Kenchi HOSOKAWA
 *  (C) 2006 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
 */

#include <windows.h>
#include <iostream>

#include "psychlops_app_state_Win32.h"
#include "../../core/ApplicationInterfaces/psychlops_app_info.h"

namespace Psychlops {


	int AppState::createSynchronousProcess(std::string command)
	{
		const char *lpArg = command.c_str();
		PROCESS_INFORMATION pi;
		STARTUPINFO si;
		ZeroMemory(&si,sizeof(si));
		si.cb=sizeof(si);

		ZeroMemory(&pi,sizeof(pi));
		if(!CreateProcess(NULL,(LPTSTR)lpArg,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si, &pi))
		{
			std::cout << "createSynchronousProcess:CreateProcess" << std::endl;
		}

		CloseHandle(pi.hThread);
		WaitForSingleObject(pi.hProcess,INFINITE);
		CloseHandle(pi.hProcess);

		return 0;
	}

	APIApplicationProperties APIApplicationProperties::startupinfo;

	APIApplicationProperties::APIApplicationProperties(){
		initialize();
	}
	APIApplicationProperties::APIApplicationProperties(HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR _lpCmdLine, int _iCmdShow)
	: hInstance_(_hInstance), hPrevInstance_(_hPrevInstance), lpCmdLine_(_lpCmdLine), iCmdShow_(_iCmdShow)	{
		initialize();
	}
	APIApplicationProperties::~APIApplicationProperties() {
	}

	void APIApplicationProperties::set(HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR _lpCmdLine, int _iCmdShow) {
		hInstance_ = _hInstance;
		hPrevInstance_ = _hPrevInstance;
		lpCmdLine_ = _lpCmdLine;
		iCmdShow_ = _iCmdShow;
		initialize();
	}
	DWORD APIApplicationProperties::getPrimaryThreadID() {
		return primaryThreadID;
	}

	void APIApplicationProperties::initialize() {
		primaryThreadID = GetCurrentThreadId();
		pClassName = "PsychlopsWindow";
		pAppName = "Psychlops Application";

		thread_state_[AppState::SLEEP] = IDLE_PRIORITY_CLASS;
		thread_state_[AppState::IDLE] = IDLE_PRIORITY_CLASS;
		thread_state_[AppState::LOW] = BELOW_NORMAL_PRIORITY_CLASS;
		thread_state_[AppState::NORMAL] = NORMAL_PRIORITY_CLASS;
		thread_state_[AppState::HIGH] = HIGH_PRIORITY_CLASS;
		SetPriorityClass(GetCurrentProcess(), thread_state_[AppState::NORMAL]);
	}
	LRESULT CALLBACK APIApplicationProperties::proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
		switch (message) {
			case WM_QUIT:
				return DefWindowProc( hWnd, message, wParam, lParam );
				//ExitThread(TRUE);
			case WM_CLOSE:
			case WM_DESTROY:
				PostQuitMessage(0);
				return 0;
			default:
				return DefWindowProc( hWnd, message, wParam, lParam );
		}
	}
	void APIApplicationProperties::setThreadPriority( unsigned int priority ) {
		if(priority>=0 && priority<5) {
			SetPriorityClass(GetCurrentProcess(), startupinfo.thread_state_[priority]);
		}
	}
	int APIApplicationProperties::getThreadPriority() {
		DWORD threadState = GetPriorityClass(GetCurrentProcess());
		switch(threadState) {
		case IDLE_PRIORITY_CLASS:
			return AppState::IDLE;
		case BELOW_NORMAL_PRIORITY_CLASS:
			return AppState::LOW;
		default:
		case NORMAL_PRIORITY_CLASS:
			return AppState::NORMAL;
		case HIGH_PRIORITY_CLASS:
			return AppState::HIGH;
		}
	}

	void APIApplicationProperties::analyzeAPIError() {
		LPVOID lpMsgBuf;
		FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
		MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
		LocalFree(lpMsgBuf);
	}



	void AppState::alert(std::string message) {
		unsigned char str[255];
		MessageBox( NULL, message.c_str(), "Psychlops Notification", MB_OK );
	}

}	/*	<- namespace Psycholops 	*/
