// MissionControlDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Dashboard.h"
#include "MissionControlDlg.h"
#include "MissionControlSettingsDlg.h"
#include "DashboardRecipient.h"
#include "DashboardDlg.h"
#include "HeadingControlDlg.h"
#include "WaypointControlDlg.h"
#include <remote/MMDropWeight.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define MISSION_TIMER 1
#define MISSION_TIMER_ELAPSE 2000		//ms

const COLORREF WHITE = RGB(255, 255, 255);
const COLORREF RED = RGB(255, 0, 0);

/////////////////////////////////////////////////////////////////////////////
// CMissionControlDlg dialog


CMissionControlDlg::CMissionControlDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMissionControlDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMissionControlDlg)
	m_altitude = 0.0f;
	m_roll = 0.0f;
	m_pitch = 0.0f;
	m_heading = 0.0f;
	m_latitude = 0.0f;
	m_longitude = 0.0f;
	m_pitchIndicator = 0.0f;
	m_rollIndicator = 0.0f;
	m_water1 = FALSE;
	m_water2 = FALSE;
	m_water3 = FALSE;
	m_water4 = FALSE;
	m_yawIndicator = 0.0f;
	m_speedIndicator = 0.0f;
	m_depthIndicator = 0.0f;
	m_timer = 0.0f;
	m_underway = FALSE;
	m_gfcurrent1 = 0.0f;
	m_gfcurrent2 = 0.0f;
	m_gfcurrent3 = 0.0f;
	m_gfcurrent4 = 0.0f;
	m_batAmp1 = 0.0f;
	m_batAmp2 = 0.0f;
	m_batAmp3 = 0.0f;
	m_batVolt1 = 0.0f;
	m_batVolt2 = 0.0f;
	m_batVolt3 = 0.0f;
	//}}AFX_DATA_INIT
	EnableToolTips(TRUE);

	m_headingCon = NULL;
	m_waypointCon = NULL;

}

CMissionControlDlg::~CMissionControlDlg()
{

}

void CMissionControlDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMissionControlDlg)
	DDX_OCFloat(pDX, IDC_ALTITUDE, DISPID(7), m_altitude);
	DDX_OCFloat(pDX, IDC_ATTITUDE, DISPID(18), m_roll);
	DDX_OCFloat(pDX, IDC_ATTITUDE, DISPID(19), m_pitch);
	DDX_OCFloat(pDX, IDC_COMPASS, DISPID(1), m_heading);
	DDX_Control(pDX, IDC_DEPTH, m_depth);
	DDX_OCFloat(pDX, IDC_LAT_INDICATOR, DISPID(7), m_latitude);
	DDX_OCFloat(pDX, IDC_LON_INDICATOR, DISPID(7), m_longitude);
	DDX_OCFloat(pDX, IDC_PITCH_INDICATOR, DISPID(7), m_pitchIndicator);
	DDX_OCFloat(pDX, IDC_ROLL_INDICATOR, DISPID(7), m_rollIndicator);
	DDX_OCBool(pDX, IDC_WATERALARM1, DISPID(2), m_water1);
	DDX_OCBool(pDX, IDC_WATERALARM2, DISPID(2), m_water2);
	DDX_OCBool(pDX, IDC_WATERALARM3, DISPID(2), m_water3);
	DDX_OCBool(pDX, IDC_WATERALARM4, DISPID(2), m_water4);
	DDX_OCFloat(pDX, IDC_YAW_INDICATOR, DISPID(7), m_yawIndicator);
	DDX_OCFloat(pDX, IDC_SPEED, DISPID(7), m_speedIndicator);
	DDX_OCFloat(pDX, IDC_DEPTH_INDICATOR, DISPID(7), m_depthIndicator);
	DDX_OCFloat(pDX, IDC_TIMER, DISPID(7), m_timer);
	DDX_OCBool(pDX, IDC_UNDERWAY, DISPID(2), m_underway);
	DDX_OCFloat(pDX, IDC_GFCURRENT1, DISPID(7), m_gfcurrent1);
	DDX_OCFloat(pDX, IDC_GFCURRENT2, DISPID(7), m_gfcurrent2);
	DDX_OCFloat(pDX, IDC_GFCURRENT3, DISPID(7), m_gfcurrent3);
	DDX_OCFloat(pDX, IDC_GFCURRENT4, DISPID(7), m_gfcurrent4);
	DDX_OCFloat(pDX, IDC_BAT_AMP_1, DISPID(7), m_batAmp1);
	DDX_OCFloat(pDX, IDC_BAT_AMP_2, DISPID(7), m_batAmp2);
	DDX_OCFloat(pDX, IDC_BAT_AMP_3, DISPID(7), m_batAmp3);
	DDX_OCFloat(pDX, IDC_BAT_VOLT_1, DISPID(7), m_batVolt1);
	DDX_OCFloat(pDX, IDC_BAT_VOLT_2, DISPID(7), m_batVolt2);
	DDX_OCFloat(pDX, IDC_BAT_VOLT_3, DISPID(7), m_batVolt3);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CMissionControlDlg, CDialog)
	//{{AFX_MSG_MAP(CMissionControlDlg)
	ON_BN_CLICKED(IDC_ABORT, OnAbort)
	ON_BN_CLICKED(IDC_KILL, OnKill)
	ON_BN_CLICKED(IDC_STARTMISSION, OnStartMission)
	ON_BN_CLICKED(IDC_HEADCON_INIT, OnHeadconInit)
	ON_BN_CLICKED(IDC_WAYCON_INIT, OnWayconInit)
	ON_WM_TIMER()
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_DROPWEIGHT, OnDropweight)
	ON_BN_CLICKED(IDC_UPDATESLOWBUTTON, OnUpdateSlow)
	ON_BN_CLICKED(IDC_UPDATEFASTBUTTON, OnUpdateFast)
	ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify )
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMissionControlDlg message handlers

BOOL CMissionControlDlg::OnToolTipNotify(UINT id, NMHDR * pTTTStruct, LRESULT * pResult)
{
	UINT nID = ::GetDlgCtrlID((HWND)pTTTStruct->idFrom);
	switch (nID) {
	case (IDC_SETTINGS):
		((NMTTDISPINFO *)pTTTStruct)->lpszText = "Change the data settings";
		break;
	case (IDC_MISSION_UPDATE):
		((NMTTDISPINFO *)pTTTStruct)->lpszText = "Request data from vehicle";
		break;
	case (IDC_DROPWEIGHT):
		((NMTTDISPINFO *)pTTTStruct)->lpszText = "Drop the emergency dropweight";
		break;
	case (IDC_ABORT):
		((NMTTDISPINFO *)pTTTStruct)->lpszText = "Send mission abort command";
		break;
	case (IDC_KILL):
		((NMTTDISPINFO *)pTTTStruct)->lpszText = "Send mission kill command";
		break;
	}
	return TRUE;
}

BOOL CMissionControlDlg::OnInitDialog()
{
	BOOL val = CDialog::OnInitDialog();
	Assert(m_recipient);

	GetWindowText(m_title);
	SetTimer(MISSION_TIMER,MISSION_TIMER_ELAPSE,0);

	m_emerDropBut.SubclassDlgItem(IDC_DROPWEIGHT,this);
	m_abortMisBut.SubclassDlgItem(IDC_ABORT,this);
	m_killMisBut.SubclassDlgItem(IDC_KILL,this);
	m_logDirLabel.SubclassDlgItem(IDC_LOG_DIR,this);

	m_emerDropBut.SetColor(RED);
	m_abortMisBut.SetColor(RED);
	m_killMisBut.SetColor(RED);
	m_logDirLabel.SetFontSize(10);
	m_logDirLabel.SetFontBold(True);

	requestUpdate();

	return val;
}

void CMissionControlDlg::resetDialog()
{
	UpdateData(TRUE);
	m_altitude = 0.0f;
	m_roll = 0.0f;
	m_pitch = 0.0f;
	m_heading = 0.0f;
	m_latitude = 0.0f;
	m_longitude = 0.0f;
	m_pitchIndicator = 0.0f;
	m_rollIndicator = 0.0f;
	m_batAmp1 = 0.0f;
	m_batAmp2 = 0.0f;
	m_batAmp3 = 0.0f;
	m_batVolt1 = 0.0f;
	m_batVolt2 = 0.0f;
	m_batVolt3 = 0.0f;
	m_water1 = FALSE;
	m_water2 = FALSE;
	m_water3 = FALSE;
	m_water4 = FALSE;
	m_yawIndicator = 0.0f;
	m_speedIndicator = 0.0f;
	m_depthIndicator = 0.0f;
	m_timer = 0.0f;
	m_underway = FALSE;
	UpdateData(FALSE);
}

void CMissionControlDlg::OnUpdateSlow()
{
	Assert(m_recipient);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMWaterAlarmBatch,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNavigationPosition,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNavigationAttitude,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMThalesBatteryInfo,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMGroundFaultCurrentBatch,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNmea,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMActiveBehavior,30);
}


void CMissionControlDlg::OnUpdateFast()
{
	Assert(m_recipient);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMWaterAlarmBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNavigationPosition,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNavigationAttitude,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMThalesBatteryInfo,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMGroundFaultCurrentBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNmea,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMActiveBehavior,3);
}

void CMissionControlDlg::requestUpdate()
{
	Assert(m_recipient);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMWaterAlarmBatch,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNavigationPosition,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNavigationAttitude,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMThalesBatteryInfo,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMGroundFaultCurrentBatch,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMNmea,30);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMActiveBehavior,30);

	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMLogDirName, 10);
}

void CMissionControlDlg::stopRequests()
{
	Assert(m_recipient);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMWaterAlarmBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMNavigationPosition,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMNavigationAttitude,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMThalesBatteryInfo,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMGroundFaultCurrentBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMNmea,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMActiveBehavior,-1);

	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMLogDirName, -1);

	resetDialog();
}

void CMissionControlDlg::OnOK() 
{
	// TODO: Add extra validation here
	CDialog::OnOK();
}
void CMissionControlDlg::OnAbort() 
{
	// TODO: Add your control notification handler code here
	Assert(m_recipient);
	if (MessageBox("Are you sure you want to abort this mission?",
		"Confirm",MB_YESNO) == IDYES) {
		m_recipient->requestData(MMAgentRequest::Single,
			ModemMessage::tMMAbortMission,-1);
	}	
}

void CMissionControlDlg::OnKill() 
{
	// TODO: Add your control notification handler code here
	Assert(m_recipient);
	if (MessageBox("Are you sure you want to kill this mission?",
		"Confirm",MB_YESNO) == IDYES) {
		m_recipient->requestData(MMAgentRequest::Single,
			ModemMessage::tMMKillMission,-1);
	}	
}

void CMissionControlDlg::setHeading(double heading)
{
	receiveData();
	UpdateData(TRUE);
	m_heading = heading;
	m_yawIndicator = heading;
	UpdateData(FALSE);
}

void CMissionControlDlg::setAttitude(double pitch, double roll)
{
	receiveData();
	UpdateData(TRUE);
	m_pitch = pitch;
	m_pitchIndicator = pitch;
	m_roll = roll;
	m_rollIndicator = roll;
	UpdateData(FALSE);
}

void CMissionControlDlg::setPosition(double latitude, double longitude)
{
	receiveData();
	UpdateData(TRUE);
	m_latitude = latitude;
	m_longitude = longitude;
	UpdateData(FALSE);
}

void CMissionControlDlg::setSpeed(double speed)
{
	receiveData();
	UpdateData(TRUE);
	m_speedIndicator = speed;
	UpdateData(FALSE);
}

void CMissionControlDlg::setAltitude(double altitude)
{
	receiveData();
	UpdateData(TRUE);
	m_altitude = altitude;
	UpdateData(FALSE);
}

void CMissionControlDlg::setDepth(double depth)
{
	receiveData();
	UpdateData(TRUE);
	m_depth.SetValue(COleVariant(depth));
	m_depthIndicator = depth;
	UpdateData(FALSE);
}

void CMissionControlDlg::setMissionTime(int time)
{
	receiveData();
	UpdateData(TRUE);
	m_timer = time;
	UpdateData(FALSE);
}

void CMissionControlDlg::setWaterAlarm(int number, bool value)
{
	receiveData();
	UpdateData(TRUE);
	switch (number) {
	case 0:
		m_water1 = value;
		break;
	case 1:
		m_water2 = value;
		break;
	case 2:
		m_water3 = value;
		break;
	case 3:
		m_water4 = value;
		break;
	default:
		Assert(false);
		break;
	}		
	UpdateData(FALSE);
}

void CMissionControlDlg::setUnderway(int value)
{
	UpdateData(TRUE);
	m_underway = ((value != 0) ? 1 : 0);
	UpdateData(FALSE);	
}

void CMissionControlDlg::setCurrentBehavior(int curS, int curB, int misRunning)
{
	receiveData();
	setUnderway(misRunning);
}

void CMissionControlDlg::setGroundFaultCurrent(int number, double value)
{
	receiveData();
	UpdateData(TRUE);
	switch (number) {
	case (0):
		m_gfcurrent1 = value;
		break;
	case (1):
		m_gfcurrent2 = value;
		break;
	case (2):
		m_gfcurrent3 = value;
		break;
	case (3):
		m_gfcurrent4 = value;
		break;
	default:
		Assert(false);
		break;
	}
	UpdateData(FALSE);
}

void CMissionControlDlg::setBatteryInfo(int num, double voltage, double amps, double minV, 
		double maxV, double temp, double capacity, char state, char errorState, int comms,
		int errorLevel)
{
	switch(num) {
	case 0:
		m_batVolt1 = voltage;
		m_batAmp1 = amps;
		break;
	case 1:	
		m_batVolt2 = voltage;
		m_batAmp2 = amps;
		break;
	case 2:	
		m_batVolt3 = voltage;
		m_batAmp3 = amps;
		break;
	}

	UpdateData(False);
}


void CMissionControlDlg::setLogDirName(CString str)
{
	m_logDirLabel.SetWindowText(str.GetBuffer(0));
}

void CMissionControlDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch (nIDEvent) {
	case (MISSION_TIMER):
		SetWindowText(m_title);	
		break;
	}

	CDialog::OnTimer(nIDEvent);
}

void CMissionControlDlg::receiveData()
{
	SetWindowText(m_title + " Received New Data...");
}

void CMissionControlDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	stopRequests();
	CDialog::OnClose();
}

void CMissionControlDlg::OnDropweight() 
{
	// TODO: Add your control notification handler code here
	Assert(m_recipient);
	if (MessageBox("Are you sure you want to drop the drop weight?",
		"Confirm",MB_YESNO) == IDYES) {
		m_recipient->releaseDropWeight(MMDropWeightRelease::Emergency,True);
	}
}

void CMissionControlDlg::OnStartMission() 
{
	//m_recipient->setMission("","",1);

	m_dd->showFileManager();
}

void CMissionControlDlg::OnHeadconInit()
{
	if (!m_headingCon) {
		m_headingCon = new CHeadingControlDlg(this);
		m_recipient->addDataRecipient(m_headingCon);
		m_headingCon->setRecipient(m_recipient);
		m_headingCon->Create(IDD_HEADINGCONTROL_DLG);
		m_headingCon->ShowWindow(SW_SHOWNORMAL);
	} else {
		m_headingCon->onReinit();
		m_headingCon->ShowWindow(SW_SHOWNORMAL);
	}
}

void CMissionControlDlg::OnWayconInit()
{
	if(!m_waypointCon) {
		m_waypointCon = new CWaypointControlDlg(this);
		m_recipient->addDataRecipient(m_waypointCon);
		m_waypointCon->setRecipient(m_recipient);
		m_waypointCon->Create(IDD_WAYPOINTCONTROL_DLG);
		m_waypointCon->ShowWindow(SW_SHOWNORMAL);
	} else {
		m_waypointCon->onReinit();
		m_waypointCon->ShowWindow(SW_SHOWNORMAL);
	}
}

