// PowerBoardDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Dashboard.h"
#include "PowerBoardDlg.h"
#include "DashboardRecipient.h"
#include <remote/MMPower.h>
#include <remote/MMDropWeight.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define POWER_TIMER 1
#define POWER_TIMER_ELAPSE 2000

/////////////////////////////////////////////////////////////////////////////
// CPowerBoardDlg dialog


CPowerBoardDlg::CPowerBoardDlg(CWnd* pParent /*=NULL*/)
	: CTestDlg(CPowerBoardDlg::IDD, pParent, IDC_POWER_STATUS)
{
	m_circuitLock = 0;
	//{{AFX_DATA_INIT(CPowerBoardDlg)
	m_water1 = FALSE;
	m_water2 = FALSE;
	m_water3 = FALSE;
	m_water4 = FALSE;
	m_descendBurning = FALSE;
	m_ascendBurning = FALSE;
	m_emerBurning = FALSE;
	m_gfBatMinus = 0.0f;
	m_gfBatPlus = 0.0f;
	m_gfIsoMinus = 0.0f;
	m_gfIsoPlus = 0.0f;
	//}}AFX_DATA_INIT
}


void CPowerBoardDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPowerBoardDlg)
	DDX_Control(pDX, IDC_CIRCUITLIST, m_circuitList);
	DDX_Control(pDX, IDC_TEMPERATURE1, m_temperature1);
	DDX_Control(pDX, IDC_TEMPERATURE2, m_temperature2);
	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_OCBool(pDX, IDC_ASCEND_BURNING, DISPID(2), m_descendBurning);
	DDX_OCBool(pDX, IDC_DESCEND_BURNING, DISPID(2), m_ascendBurning);
	DDX_OCBool(pDX, IDC_EMER_BURNING, DISPID(2), m_emerBurning);
	DDX_OCFloat(pDX, IDC_GF_BATBUS_MINUS, DISPID(7), m_gfBatMinus);
	DDX_OCFloat(pDX, IDC_GF_BATBUS_PLUS, DISPID(7), m_gfBatPlus);
	DDX_OCFloat(pDX, IDC_GF_ISO_MINUS, DISPID(7), m_gfIsoMinus);
	DDX_OCFloat(pDX, IDC_GF_ISO_PLUS, DISPID(7), m_gfIsoPlus);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CPowerBoardDlg, CTestDlg)
	//{{AFX_MSG_MAP(CPowerBoardDlg)
	ON_BN_CLICKED(IDC_CIRCUITOFF, OnCircuitoff)
	ON_BN_CLICKED(IDC_CIRCUITON, OnCircuiton)
	ON_NOTIFY(NM_RCLICK, IDC_CIRCUITLIST, OnRclickCircuitlist)
	ON_BN_CLICKED(IDC_FIRE_DESCEND, OnFireDescend)
	ON_BN_CLICKED(IDC_FIRE_ASCEND, OnFireAscend)
	ON_BN_CLICKED(IDC_FIRE_EMER, OnFireEmer)
	ON_BN_CLICKED(IDC_UNFIRE_ASCEND, OnUnfireAscend)
	ON_BN_CLICKED(IDC_UNFIRE_DESCEND, OnUnfireDescend)
	ON_BN_CLICKED(IDC_UNFIRE_EMER, OnUnfireEmer)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CPowerBoardDlg::initSubClassDlg()
{
	CRect           rect;
	SetTimer(POWER_TIMER,POWER_TIMER_ELAPSE,0);

	CImageList* pImageList = new CImageList();
	pImageList->Create(16,16,TRUE,4,4);

	pImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON1));
	pImageList->Add(AfxGetApp()->LoadIcon(IDI_ICON2));

	m_circuitList.SetImageList(pImageList, LVSIL_SMALL);
	m_circuitList.SetExtendedStyle(LVS_EX_FULLROWSELECT);

	m_circuitList.GetWindowRect(&rect);
	m_circuitList.InsertColumn(0,"Status/Num",LVCFMT_LEFT,rect.Width() * 1.2/5, 0);
	m_circuitList.InsertColumn(1,"Name",LVCFMT_LEFT,rect.Width() * 2/5, 1);
	m_circuitList.InsertColumn(2,"Current(A)",LVCFMT_CENTER,rect.Width() * 1.75/5, 2);

	CString hold;
	for(int i=0; i < NUM_CIRCUITS; i++) {
		hold.Empty();
		if(i == 10) 
			hold.Format("10(A).");
		else if(i == 11)
			hold.Format("11(B).");
		else if(i == 12)
			hold.Format("12(C).");
		else if(i == 13)
			hold.Format("13(D).");
		else if(i == 14)
			hold.Format("14(E).");
		else if(i == 15)
			hold.Format("15(F).");
		else
			hold.Format("%d.",i);

		m_circuitList.InsertItem(i,hold.GetBuffer(0),0);
	}
	resetDialog();
	m_powerDriverRunning = False;
//	requestUpdate();
	UpdateData(FALSE);
}

void CPowerBoardDlg::requestUpdate()
{
	Assert(m_recipient);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMCircuitBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMCircuitCurrentBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMGroundFaultCurrentBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMCircuitInfo,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMWaterAlarmBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMTemperatureBatch,3);
	m_recipient->requestData(MMAgentRequest::Start,
		ModemMessage::tMMDropWeightReleaseBatch,3);

	m_powerDriverRunning = True;
}

void CPowerBoardDlg::stopRequests()
{
	Assert(m_recipient);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMCircuitBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMCircuitCurrentBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMGroundFaultCurrentBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMCircuitInfo,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMWaterAlarmBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMTemperatureBatch,-1);
	m_recipient->requestData(MMAgentRequest::Stop,
		ModemMessage::tMMDropWeightReleaseBatch,-1);

	m_powerDriverRunning = False;
	resetDialog();
}

void CPowerBoardDlg::resetDialog()
{

	for(int i=0; i < NUM_CIRCUITS; i++) {
		circuitNames[i].Empty();
		circuitStatus[i] = False;
		nameChanged[i] = True;
		statusChanged[i] = True;
		currents[i] = 0.0;
		//m_circuitList.SetItemText(i,1,"");
		m_circuitList.SetItemText(i,2,"");
	}
	
	m_water1 = FALSE;
	m_water2 = FALSE;
	m_water3 = FALSE;
	m_water4 = FALSE;
	m_descendBurning = FALSE;
	m_ascendBurning = FALSE;
	m_emerBurning = FALSE;
	m_gfBatMinus = 0.0f;
	m_gfBatPlus = 0.0f;
	m_gfIsoMinus = 0.0f;
	m_gfIsoPlus = 0.0f;
	
	UpdateData(False);
	ReloadList();
}

void CPowerBoardDlg::ReloadList()
{
	CString hold;
	CString comp;
	for(int i=0; i < NUM_CIRCUITS; i++) {
		if(nameChanged[i]) {
			
			comp.Empty();
			comp = circuitNames[i];
			hold = m_circuitList.GetItemText(i,1);
			if(comp != hold || comp.IsEmpty())
				m_circuitList.SetItemText(i,1,comp.GetBuffer(0));
			nameChanged[i] = 0;
		}
		if(statusChanged[i]) {
			hold.Empty();
			hold = m_circuitList.GetItemText(i,0);
			LVITEM temp;
			temp.mask = LVIF_TEXT | LVIF_IMAGE;
			temp.iItem = i;
			temp.iSubItem = 0;
			temp.pszText = hold.GetBuffer(0);
			temp.iImage = ((circuitStatus[i]) ? 0 : 1);
			m_circuitList.SetItem(&temp);
			statusChanged[i] = 0;
		}
	}

	UpdateData(FALSE);
}		
			
void CPowerBoardDlg::setDevice(int number, const char *name, int circuit)
{
	if(m_powerDriverRunning) {
		receiveData();
		if(circuit >= 0 && circuit < NUM_CIRCUITS) {
			if(strcmp(name, circuitNames[circuit].GetBuffer(0))) {
				circuitNames[circuit] = name;	
				nameChanged[circuit] = 1;
				ReloadList();
			}
		}
	}
}

void CPowerBoardDlg::setCircuitInfo(int circuit,const char *name)
{
	if(m_powerDriverRunning) {
		receiveData();
		//for fake circuit 17
		if(circuit >= 0 && circuit < NUM_CIRCUITS) {
			if(circuitNames[circuit].IsEmpty()) {
				circuitNames[circuit] = name;
				nameChanged[circuit] = 1;
				ReloadList();
			}
		}
	}
}

void CPowerBoardDlg::setCircuit(int number, bool value)
{
	if(m_powerDriverRunning) {
		receiveData();
		//TRACE("Recieving circuit %d on %d\n", number, value);
		//for fake circuit 17
		if(number >= 0 && number < NUM_CIRCUITS) {
			if(value != circuitStatus[number]) {
				circuitStatus[number] = value;
				statusChanged[number] = 1;
				ReloadList();
			}
		}
	}
}


void CPowerBoardDlg::setWaterAlarm(int number, bool value)
{
	if(m_powerDriverRunning) {
		receiveData();
		switch (number) {
		UpdateData(TRUE);
		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 CPowerBoardDlg::setTemperature(int number, double value)
{
	if(m_powerDriverRunning) {
		receiveData();
		UpdateData(TRUE);
		switch (number) {
		case (0):
			m_temperature1.SetValue(COleVariant(value));
			break;
		case (1):
			m_temperature2.SetValue(COleVariant(value));
			break;
		}
		UpdateData(FALSE);
	}
}

void CPowerBoardDlg::setCircuitCurrent(int number, double value)
{
	if(m_powerDriverRunning) {
		CString hold;
		receiveData();
		if(number >= 0 && number < NUM_CIRCUITS) {
			if(currents[number] != value || currents[number] == 0.0) {
				currents[number] = value;
				if(currents[number] == 0.0)
					hold.Empty();
				else 
					hold.Format("%.3f", value);
				m_circuitList.SetItemText(number,2,hold.GetBuffer(0));
			}
		}
	}
}

void CPowerBoardDlg::setGroundFaultCurrent(int number, double value)
{
	if(m_powerDriverRunning) {
		receiveData();
		UpdateData(TRUE);
		switch (number) {
		case (0):
			m_gfBatPlus = value;
			break;
		case (1):
			m_gfBatMinus = value;
			break;
		case (2):
			m_gfIsoPlus = value;
			break;
		case (3):
			m_gfIsoMinus = value;
			break;
		default:
			Assert(false);
			break;
		}
		UpdateData(FALSE);
	}
}

void CPowerBoardDlg::setDropWeightStatus(bool descend, bool ascend, bool emer)
{
	m_descendBurning = descend;
	m_ascendBurning = ascend;
	m_emerBurning = emer;
	UpdateData(False);
}

/////////////////////////////////////////////////////////////////////////////
// CPowerBoardDlg message handlers


BEGIN_EVENTSINK_MAP(CPowerBoardDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CPowerBoardDlg)
	ON_EVENT(CPowerBoardDlg, IDC_MVC_WATCHDOG_ENABLE, 1 /* ValueChanged */, OnValueChangedMvcWatchdogEnable, VTS_BOOL)
	ON_EVENT(CPowerBoardDlg, IDC_TC_WATCHDOG_ENABLE, 1 /* ValueChanged */, OnValueChangedTcWatchdogEnable, VTS_BOOL)
	//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

void CPowerBoardDlg::OnValueChangedMvcWatchdogEnable(BOOL Value) 
{
	// TODO: Add your control notification handler code here
	Assert(m_recipient);
	if (Value==0) m_recipient->setWatchdog(MMWatchdog::MVC,((Value == 0) ? 0 : 1));
}

void CPowerBoardDlg::OnValueChangedTcWatchdogEnable(BOOL Value) 
{
	// TODO: Add your control notification handler code here
	Assert(m_recipient);
	if (Value==0) m_recipient->setWatchdog(MMWatchdog::Tailcone,((Value == 0) ? 0 : 1));
}


void CPowerBoardDlg::OnCircuitoff() 
{
	POSITION pos = m_circuitList.GetFirstSelectedItemPosition();
	int nItem;
	while (pos != NULL) {
		nItem = m_circuitList.GetNextSelectedItem(pos);
		if(circuitNames[nItem] == "Ethernet" || circuitNames[nItem] == "ethernet"){
			CString n;
			n.Format("%d", nItem);
			CString t = "Ethernet is on circuit "+n+". Do you really want to turn it off?";
			if(MessageBox(t.GetBuffer(0), "Confirm Ethernet Circuit Off", MB_YESNO) != IDYES) continue;
		}
		if(circuitNames[nItem] == "MVC_NAVC"){
			CString n;
			n.Format("%d", nItem);
			CString t = "MVC is on circuit "+n+". You cannot turn it off.";
			MessageBox(t.GetBuffer(0), "MVC Circuit Off", MB_OK);
			continue;
		}	
		m_recipient->setCircuit(nItem,False);
	}
	m_circuitList.SetFocus();
}

void CPowerBoardDlg::OnCircuiton() 
{
	POSITION pos = m_circuitList.GetFirstSelectedItemPosition();
	int nItem;
	while (pos != NULL) {
		nItem = m_circuitList.GetNextSelectedItem(pos);
		m_recipient->setCircuit(nItem,True);
	}	
	m_circuitList.SetFocus();
}

void CPowerBoardDlg::OnPowerFail() 
{
	CDialog::OnOK();
	stopRequests();		
}

void CPowerBoardDlg::OnRclickCircuitlist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	POINT temp = pNMListView->ptAction;
	int  index = m_circuitList.HitTest( temp, NULL );
	if (index != -1) {
		if(circuitStatus[index] == False) 
			m_recipient->setCircuit(index,True);
		else {
			if(circuitNames[index] == "Ethernet" || circuitNames[index] == "ethernet") {
				CString n;
				n.Format("%d", index);
				CString t = "Ethernet is on circuit "+n+". Do you really want to turn it off?";
				if(MessageBox(t.GetBuffer(0), "Confirm Ethernet Circuit Off", MB_YESNO) != IDYES) return;
			}	
			m_recipient->setCircuit(index,False);
		}
    }
	*pResult = 0;
}

void CPowerBoardDlg::OnFireDescend() 
{
	m_recipient->releaseDropWeight(MMDropWeightRelease::Descend, True);	
}

void CPowerBoardDlg::OnFireAscend() 
{
	m_recipient->releaseDropWeight(MMDropWeightRelease::Ascend, True);	
}

void CPowerBoardDlg::OnFireEmer() 
{
	m_recipient->releaseDropWeight(MMDropWeightRelease::Emergency, True);	
}

void CPowerBoardDlg::OnUnfireAscend() 
{
	m_recipient->releaseDropWeight(MMDropWeightRelease::Ascend, False);	
}

void CPowerBoardDlg::OnUnfireDescend() 
{
	m_recipient->releaseDropWeight(MMDropWeightRelease::Descend, False);	
}

void CPowerBoardDlg::OnUnfireEmer() 
{

	m_recipient->releaseDropWeight(MMDropWeightRelease::Emergency, False);
}
