/*! 
	\file Wheelchair.h 
	\brief main application header.
*/

/* July 2011
Modifications made by Radhika for implementation of Shared Control 
are explicity mentioned with comments labelled "radhika"
*/

#pragma once

#ifndef __AFXWIN_H__
	#error "include 'stdafx.h' before including this file for PCH"
#endif

#define UWM_SERVER_READY (WM_APP + 1)

#include "resource.h"		// main symbols
#include "USARSocket.h"
#include "Utils.h"
#include "mmsystem.h"
#include "math.h"
#include "SimWnd.h"
#include "SettingsDlg.h"
#include "WheelchairDlg.h"
#include "MessageParser.h"
#include "AppConfig.h"
#include "ConfigurationDlg.h"
#include "StateControl.h"
#include "SharedControl.h" //radhika

#include <vcclr.h>
#include <afxmt.h>

#define RIGHT 2
#define LEFT 4
#define FORWARD 3
#define BACKWARD 1
#define STOP 0


class CWheelchairDlg;
class CSimWnd;
class CSettingsDlg;
class CConfigurationDlg;
class USARSocket;
class StateControl;
class SharedControl; //radhika

using namespace System;
using namespace System::IO;


//! The main class of the application. 
/* Initialises the application and starts the main dialog (CWheelchairDlg) 
	where all functionality is implemented. */
class CWheelchairApp : public CWinApp
{
friend class StateControl;
friend class SharedControl; //radhika
public:
	CWheelchairApp();

	bool StartTimer(void);
	void StopTimer(void);
	bool LoadUT(CString map);
	bool CloseUT(void);
	void ShowUT(void);
	void HideUT(void);
	bool Connect(CString host);
	void CloseConnection();
	bool StartSimWnd(void);
	bool StopSimWnd(void);
	bool TestSimWnd(void);
	bool Spawn(CString model, CString position, CString rotation);
	int  KMove(WPARAM wParam, LPARAM lParam, int type);
	void MMove(float xMove, float yMove, float scale = 1.0);
	void JMove();
	bool ProcessStartPoses(CString &resp, int & n_poses, CString* & tags, CString* & poses, CString* & rotations);
	bool OpenSettings(void);
	bool OpenConfiguration(void);
	CString CorrectElevation(CString model, CString location);
	bool SaveImg(void);
	bool SaveSPIImg(unsigned char* pRGBA, CString fname = "");
	bool SaveLog(CString str);
	bool AppendToLog(CString str);
	void ProcessMessage(bool test=false);
	void OnSharedControl(BOOL m_startSharedCtrl); //radhika

private:
	bool GetpfFrameData(void);
	static void CALLBACK TimerProc_Wrapper(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
	//static void CALLBACK QueueTimerProc_Wrapper(PVOID lpParam, BOOL TimerOrWaitFired);
	void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
	//void CALLBACK TimerProc2(void);
	void CleanUp();


// Overrides
	public:
	virtual BOOL InitInstance();


// Implementation

	DECLARE_MESSAGE_MAP()

// MEMBERS
public:
	//! \name SPI Settings
	/*! These settings are initialised based on the configuration file. */
	//@{
	float	m_LensPosY;	//!< SPI Config: Vertical position of the lens (normalised to dome radius). 
	float	m_LensPosZ;	//!< SPI Config: Horizontal position of the lens (normalised to dome radius). 
	float	m_EyePosY;	//!< SPI Config: Vertical "eye" position (normalised to dome radius). 
	float	m_EyePosZ;	//!< SPI Config: Horizontal "eye" position (normalised to dome radius).
	//@}
	bool	m_bSPISettingsChange; //!< Indicates change in SPI Config Settings.
	bool    m_bSPICaptureImage;   //!< Flags next frame for backbuffer capture.
	bool	m_bUTFreeze;		  //!< If true, new frames are not acquired from UT.
	CEvent *m_pEvent; //!< Used for synchronisation.

	//! \name Configurable properties
	/*! These settings are initialised based on the configuration file. */
	//@{
	bool	m_bFirstRun;	//!< Indicates if the application is run for the first time
	bool	m_bShowConfig;	//!< Determines if Configuration is displayed on next start
	int		m_cPORTNUM;		//!< Port number used by CWheelchairApp::m_pUSARSocket
	CString m_cUTCCMD;		//!< Command used to start the UTClient. Determines gametype, etc.
	int		m_cUTWIDTH;		//!< Width of the UT2004 window
	int		m_cUTHEIGHT;	//!< Height of the UT2004 window 
	int		m_cFPS;			//!< Target FPS. Determines the timer frequency.
	int		m_ChanSize;		//!< Channel Size
	int		m_SimWidth;		//!< Horizontal resolution of the SPI window/screen
	int		m_SimHeight;	//!< Vertical resolution of the SPI window/screen
	bool	m_bUseFBO;		//!< Indicates whether frame buffer objects are used.
	CString	m_ConfUTPath;	//!< Path to the main UT folder.
	CString m_AppPath;		//!< Path to the application directory.
	CString	m_Device;		//!< Name of the designated device, if used
	UINT	m_RawInputDataSize; //!< Size of Raw Input data
	int		m_CtrlDev;	//!< Control Device choice 
	int		m_CtrlMode;	//!< Switches between absolute (0) and relative (1) mode of control
	bool	m_useSharedControl; //! Enables Shared Control functionality //radhika

	//@}

	
private:
//METHOD:
	void EmergencyArchiveDestroy(void);
	void ConnectionLost(void);
	bool CheckConnection(void);
	bool ReadUTMessage(CString & str);
	bool SendUTMessage(CString msg);
	afx_msg void OnServerReady(WPARAM, LPARAM);
	
//MEMBERS:
	CWnd				* m_utclient;		//!< Pointer to the UT2004 Window.
	CWheelchairDlg		* m_pMainGUI;		//!< Pointer to Main Application GUI.
	CSimWnd				* m_pSim;			//!< Pointer to Simulation Window instance.
	CSettingsDlg		* m_pSettingsDlg;	//!< Pointer to SPI Settings dialog.
	CConfigurationDlg	* m_pConfigurationDlg; //!< Pointer to ConfigurationDlg
	StateControl		* m_pStateControl; //!< Pointer to StateContorl class.
	SharedControl		* m_pSharedControl; //!< Pointer to SharedStateControl class. //radhika

	char	m_utPath[512];	//!< Path to the UT System folder
	char	m_dllPath[512];	//!< Path to the Hook.dll file

	//! \name Communication
	//@{
		CSocketFile * m_File;		//!< Pointer to the CSocketFile used for communication
		CArchive	* m_arOut;		//!< Outgoing message archive attached to m_File
		CArchive	* m_arIn;		//!< Incoming message archive attached to m_File
		USARSocket	* m_pUSARSocket;//!< Pointer to USARSocket instance used for communication with the server.
		bool		m_bConnected;	//!< Indicates whether the socket is currently connected.
		bool		m_bServerReady;
		gcroot<StreamWriter^> m_logfile; //!< Pointer to the logfile.
	//@}


	//! \name Movement
	//@{
		float		m_turnAmount;	//!< Difference in left and right wheel speed. Causes turning. Used for keyboard control.
		float		m_moveAmount;	//!< Speed control for keyboard control
		CachedMove	m_CachedMove;	//!< Stores previous kinematic data for robot and camera
	//@}

	JOYINFOEX	m_Joyinfo;	//!< Joystick information structure
	HINSTANCE	m_hookDLL;  //!< Pointer to the hook library

	clock_t		m_lastClock;	//!< time at last OnTimer execution. Used to calculate FPS.
	int 		m_frameCount;	//!< counts frames. FPS is updated every 30 frames.
	FrameData	* m_pFrameData;	//!< Frame Data.
	pfFrameData	m_pfFrameData;	//!< Pointer to the FrameData function
	int			m_sequence;		//!< Stores the current usable frame sequence number
	//int			m_iJMoveCount;	//!< counts JMove executions. Log message every 10 executions.

	UINT_PTR	m_pTimer;		//!< Pointer to timer
	static void * pObject;		//!< Required for TimerProc_Wrapper
};

extern CWheelchairApp theApp; //!< The one and only CWheelchairApp object, defined in  \ref Wheelchair.cpp 