// CDashboardRecipient.cpp: implementation of the CDashboardRecipient class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Dashboard.h"
#include "DashboardDlg.h"
#include "DashboardRecipient.h"
#include <remote/MMAhrs.h>
#include <remote/MMDepthSensor.h>
#include <remote/MMNavigation.h>
#include <remote/MMTailcone.h>
#include <remote/MMAlarm.h>
#include <remote/MMHoming.h>
#include <remote/MMGps.h>
#include <remote/MMPower.h>
#include <remote/MMDeviceInfo.h>
#include <remote/MMDvl.h>
#include <remote/MMDynamicControl.h>
#include <remote/MMThalesBattery.h>
#include <remote/MMDropWeight.h>
#include <remote/MMString.h>
#include <remote/MMNmea.h>
#include <remote/MMRtcm.h>
#include <remote/MMServer.h>
#include <remote/MMMissionInfo.h>
#include <remote/MMBehavior.h>
#include <remote/MMActiveBehavior.h>
#include <remote/MMDriver.h>
#include <remote/MMOas.h>
#include <remote/MMSvs.h>
#include <remote/MMLN250.h>
#include <remote/MMMissionName.h>
#include <remote/MMUSBL.h>
#include <remote/ModemBroker.h>
#include <remote/ModemSocket.h>
#include <remote/ModemSerial.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define CONNECT_REMOTE		1
#define POPUP_BOXES			0

#define MIN_CIRCUITS		14

CDashboardRecipient* CDashboardRecipient::_gpDashboardRecipient = 0;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDashboardRecipient::CDashboardRecipient(CDashboardDlg *dialog)
{
	_gpDashboardRecipient = this;
	m_dialog = dialog;
	m_requestList = new CList<MMAgentRequest*,MMAgentRequest*>;

	// Default array sizes
	m_numCircuits = 14;
	m_numCurrents = 8;
	m_numGroundFaults = 2;
	m_numTemperatures = 2;
	m_numWaterAlarms = 4;
	m_numBatteryPacks = 2;

	_lastBehaviorArray = NULL;
	_lastBehavior = NULL;

	m_requestBlock = 0;
	m_MessageManager = NULL;
}

CDashboardRecipient::~CDashboardRecipient()
{

	while(!m_requestList->IsEmpty()) {
		MMAgentRequest* h = m_requestList->RemoveHead();
		//delete h;
	}
	delete m_requestList;
	if(_lastBehaviorArray != NULL) 
		delete _lastBehaviorArray;
	if(_lastBehavior != NULL) 
		delete _lastBehavior;

	//fclose(debuglog);
}

CDashboardRecipient * CDashboardRecipient::getDashboardRecipient() {
	return _gpDashboardRecipient;
}

////////////////////////////////////////////////////
void CDashboardRecipient::receive(const ModemMessage* pMM)
{
	char str[256];
	int j;
	//ModemMessage::Type t = pMM->getType();

	//TRACE("Type: %d OurType: %d\n", pMM->getType(), ModemMessage::tMMBehavior);

	for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->gotMessage(pMM);
	switch (pMM->getType()) {
		case (ModemMessage::tMMAgentRequest):
		{
			MMAgentRequest message(pMM);
			if (message.getRequestType() == ModemMessage::tACK) {
				if (POPUP_BOXES) m_dialog->MessageBox("Got ack.");
			} else {
				if (POPUP_BOXES) m_dialog->MessageBox("Got a request");
			}
			break;
		}
		case (ModemMessage::tMMNavigationAttitude):
		{
			MMNavigationAttitude att(pMM);
			att.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setAttitude(MMUtil::radToDeg(att.getPitch()),
				MMUtil::radToDeg(att.getRoll()));
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setHeading(MMUtil::radToDeg(att.getYaw()));
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setMissionTime(att.getUpdateTime());
			break;
		}
		case (ModemMessage::tMMNavigationPosition):
		{
			MMNavigationPosition pos(pMM);
			pos.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setSpeed(pos.getSpeed());
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setAltitude(pos.getAltitude());
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDepth(pos.getDepth());
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setPosition(pos.getLatitude(),pos.getLongitude());
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setMissionTime(pos.getUpdateTime());
			break;
		}
		case (ModemMessage::tMMTailcone):
		{
			MMTailcone message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			double rpm = message.getPropellerRpm();
			double elevator = MMUtil::radToDeg(message.getElevatorAngle());
			double rudder = MMUtil::radToDeg(message.getRudderAngle());
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setTailcone(rpm,elevator,rudder);
			break;
		}
		case (ModemMessage::tMMTailconeRaw):
		{
			MMTailconeRaw message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setTailconeRaw(message.getPropeller(),
				message.getElevator(),message.getRudder(),message.getThrottle());
			break;
		}
		case (ModemMessage::tMMCircuit):
		{
			MMCircuit message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			bool value = message.getValue() ? true : false;
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setCircuit(message.getNumber(),value);
			break;
		}
		case (ModemMessage::tMMCircuitBatch):
		{
			MMCircuitBatch message(pMM);
			m_numCircuits = min(MIN_CIRCUITS,message.getNumber());
			for (int i=0; i<message.getNumber(); i++) {
				message.toString(str,i);
				if (POPUP_BOXES) m_dialog->MessageBox(str);
				bool value = message.getValue(i) ? true : false;
				for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setCircuit(i,value);
			}
			break;
		}
		case (ModemMessage::tMMCircuitCurrent):
		{
			MMCircuitCurrent message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setCircuitCurrent(message.getNumber(),message.getValue());
			break;
		}
		case (ModemMessage::tMMCircuitCurrentBatch):
		{
			MMCircuitCurrentBatch message(pMM);
			m_numCurrents = message.getNumber();
			for (int i=0; i<m_numCurrents; i++) {
				message.toString(str,i);
				if (POPUP_BOXES) m_dialog->MessageBox(str);
				for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setCircuitCurrent(i,message.getValue(i));
			}
			break;
		}
		case (ModemMessage::tMMCircuitInfo):
		{
			MMCircuitInfo message(pMM);
			for (j=0;j<m_recips.GetSize();j++) m_recips[j]->setCircuitInfo(message.getNum(), message.getName());
			break;
		}
		case (ModemMessage::tMMGroundFaultCurrent):
		{
			MMGroundFaultCurrent message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setGroundFaultCurrent(message.getNumber(),message.getValue());
			break;
		}
		case (ModemMessage::tMMGroundFaultCurrentBatch):
		{
			MMGroundFaultCurrentBatch message(pMM);
			for (int i=0; i<message.getNumber(); i++) {
				message.toString(str,i);
				if (POPUP_BOXES) m_dialog->MessageBox(str);
				for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setGroundFaultCurrent(i,message.getValue(i));
			}
			break;
		}
		case (ModemMessage::tMMTemperature):
		{
			MMTemperature message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setTemperature(message.getNumber(),message.getValue());
			break;
		}
		case (ModemMessage::tMMTemperatureBatch):
		{
			MMTemperatureBatch message(pMM);
			for (int i=0; i<message.getNumber(); i++) {
				message.toString(str,i);
				if (POPUP_BOXES) m_dialog->MessageBox(str);
				for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setTemperature(i,message.getValue(i));
			}
			break;
		}
		case (ModemMessage::tMMWaterAlarm):
		{
			MMWaterAlarm message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			bool value = message.getValue() ? true : false;
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setWaterAlarm(message.getNumber(),value);
			break;
		}
		case (ModemMessage::tMMWaterAlarmBatch):
		{
			MMWaterAlarmBatch message(pMM);
			for (int i=0; i<message.getNumber(); i++) {
				message.toString(str,i);
				if (POPUP_BOXES) m_dialog->MessageBox(str);
				bool value = message.getValue(i) ? true : false;
				for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setWaterAlarm(i,value);
			}
			break;
		}
		case (ModemMessage::tMMServerAlarm):
		{
			MMServerAlarm message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			bool value = message.getValue() ? true : false;
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setServerAlarm(message.getNumber(),value);
			break;
		}
		case (ModemMessage::tMMServerAlarmBatch):
		{
			MMServerAlarmBatch message(pMM);
			for (int i=0; i<message.getNumber(); i++) {
				message.toString(str,i);
				if (POPUP_BOXES) m_dialog->MessageBox(str);
				bool value = message.getValue(i) ? true : false;
				for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setServerAlarm(i,value);
			}
			break;
		}
		case (ModemMessage::tMMDropWeightRelease):
		{
			MMDropWeightRelease message(pMM);
			message.toString(str);
			m_dialog->MessageBox(str);
			break;
		}
		case (ModemMessage::tMMDropWeightReleaseBatch):
		{
			MMDropWeightReleaseBatch message(pMM);
			//message.toString(str,i);
			//m_dialog->MessageBox(str);
			//0 is descend, 1 is ascend, 2 is emergency
			bool descendStat = ((message.getValue(0) == 0) ? 0 : 1);
			bool ascendStat = ((message.getValue(1) == 0) ? 0 : 1);
			bool emerStat = ((message.getValue(2) == 0) ? 0 : 1);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDropWeightStatus(descendStat,ascendStat,
				emerStat);
			break;
		}
		case (ModemMessage::tMMDynamicControlCommand):
		{
			MMDynamicControlCommand message(pMM);
			message.toString(str);
			m_dialog->MessageBox(str);
			break;
		}
		case (ModemMessage::tMMDeviceInfo):
		{
			MMDeviceInfo message(pMM);
			message.toString(str);
			if (POPUP_BOXES)	m_dialog->MessageBox(str);
			int port = port2int(message.getPort());
			//so what comes through in the getDriver portion of the message is up to RemoteAgentServer
			//currently the server
			if (port > 0) for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDevice(port,message.getName(),
				message.getPowerCircuit());
			break;
		}
		case (ModemMessage::tMMLN250):
		{
			MMLN250 message(pMM);
			int ln250type = message.getLN250type();
			double roll = MMUtil::radToDeg(message.getRoll());
			double pitch = MMUtil::radToDeg(message.getPitch());
			double yaw = MMUtil::radToDeg(message.getYaw());
			double rollRate = MMUtil::radToDeg(message.getRollRate());
			double pitchRate = MMUtil::radToDeg(message.getPitchRate());
			double yawRate = MMUtil::radToDeg(message.getYawRate());
			double biasX = message.getBiasX();
			double biasY = message.getBiasY();
			float systime = message.getSysTime();
			char valid = message.getValid();
			float lat = MMUtil::radToDeg(message.getLat());
			float lon = MMUtil::radToDeg(message.getLon());
			float alt = message.getAlt();
			float nvel = message.getNvel();
			float evel = message.getEvel();
			float vvel = message.getVvel();
			short mode = (short)message.getMode();
			short type = (short)message.getType();
			for (j = 0;j<m_recips.GetSize();j++)  
					m_recips[j]->setLn250(ln250type, systime, valid,lat,lon,alt,
										  nvel, evel, vvel, biasX, biasY, pitch, roll, yaw, 
										  pitchRate, rollRate, yawRate, mode, type);

			break;
		}
		case (ModemMessage::tMMAhrs):
		{
			MMAhrs message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			double roll = MMUtil::radToDeg(message.getRoll());
			double pitch = MMUtil::radToDeg(message.getPitch());
			double yaw = MMUtil::radToDeg(message.getYaw());
			double rollRate = MMUtil::radToDeg(message.getRollRate());
			double pitchRate = MMUtil::radToDeg(message.getPitchRate());
			double yawRate = MMUtil::radToDeg(message.getYawRate());
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setAttitude(roll, pitch, yaw, rollRate, pitchRate, yawRate);
			break;
		}
		case (ModemMessage::tMMBehavior):
		{
			MMBehavior message(pMM);
			short suc = message.getSuccess();
			TRACE("Success: %d\n",suc);
			short state = _lastBehavior->getStateNum();
			short pri = _lastBehavior->getPriorityNum();
			char n[128];
			memset(n,0,128);
			_lastBehavior->getName(n);
			CString s;
			if(suc) {
				s = "Single attribute change made successfully";
				for(j = 0; j < m_recips.GetSize(); j++) {
					if(m_recips[j] != NULL)
						m_recips[j]->setAttributeAck(False, True, state, pri, n);
				}	
			} else {
				s = "Single attribute change failed on vehicle";
				for(j = 0; j < m_recips.GetSize(); j++) {
					if(m_recips[j] != NULL)
						m_recips[j]->setAttributeAck(False,False, state, pri, n);
				}
			}
			m_dialog->MessageBox(s);
			delete _lastBehavior;
			_lastBehavior = NULL;
			break;
		}
		case (ModemMessage::tMMBehaviorArray):
		{
			MMBehaviorArray message(pMM);

			bool allGood = True;
			CString allF;
			char t_name[128];
			for(int i = 0;i<message.getNumSuccesses(); i++){
					_lastBehaviorArray->getSingleName(i,t_name);
					if(!message.getSingleSuccess(i)){
					allGood = False;
					CString tn;
					tn.Format("%d",_lastBehaviorArray->getSinglePriority(i)+1);
					CString s;
					s.Format("%d", _lastBehaviorArray->getSingleState(i)+1);
					CString failed = "Change to state  priority "+tn+" name "+t_name+ " failed on vehicle.\n";
					allF = allF+failed;
				
					for(j = 0; j < m_recips.GetSize(); j++) {
						if(m_recips[j] != NULL)
							m_recips[j]->setAttributeAck(True, False, _lastBehaviorArray->getSingleState(i),
								_lastBehaviorArray->getSinglePriority(i),t_name);
					}
				} else {
					for(j = 0; j < m_recips.GetSize(); j++) {
						if(m_recips[j] != NULL)
							m_recips[j]->setAttributeAck(True, True, _lastBehaviorArray->getSingleState(i),
								_lastBehaviorArray->getSinglePriority(i),t_name);
					}
				}
			}

			delete _lastBehaviorArray;
			_lastBehaviorArray = NULL;

			if(allGood){
				CString s = "All attribute changes made successfully";
				m_dialog->MessageBox(s);
			}else{
				m_dialog->MessageBox(allF);
			}

			break;
		}
		case (ModemMessage::tMMMissionName):
		{
			
			MMMissionName message(pMM);
			if(message.getMissionType() == MMMissionName::Normal) {
				CString f;
				if(message.getSuccess())
					f = "Normal mission change successful";
				else
					f = "Normal mission change not successful";
					
				m_dialog->MessageBox(f);
			} else if(message.getMissionType() == MMMissionName::Abort) {
				CString t;
				if(message.getSuccess())
					t = "Abort mission change successful";
				else
					t = "Abort mission change not successful";
					
				m_dialog->MessageBox(t);
			}
			break;
		}
		case (ModemMessage::tMMActiveBehavior):
		{
			MMActiveBehavior message(pMM);
			for (j = 0;j<m_recips.GetSize();j++) {
				if(m_recips[j] != NULL)
					m_recips[j]->setCurrentBehavior(message.getStateNum(), message.getBehavior(), message.getMissionRunning());
			}
			break;
		}
		case (ModemMessage::tMMOas):
		{
			MMOas message(pMM);
			for(j = 0; j <m_recips.GetSize();j++) {
				if(m_recips[j] != NULL)
					m_recips[j]->setOas(message.getRawRange(), message.getMeanRange(), message.getMaxRange());
			}
			break;
		}
		case (ModemMessage::tMMSvs):
		{
			MMSvs message(pMM);
			for(j = 0; j < m_recips.GetSize(); j++) {
				if(m_recips[j] != NULL)
					m_recips[j]->setSvs(message.getRawTOF(), message.getSpeedM(), message.getSpeedMm());
			}
			break;
		}
		case (ModemMessage::tMMDepthSensor):
		{
			MMDepthSensor message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDepthSensor(message.getDepth(),message.getTemperature(),
				message.getPressure());
			break;
		}
		case (ModemMessage::tMMThalesBatteryGlobal):
		{
			MMThalesBatteryGlobal message(pMM);
			int nb = message.getNumBat();
			int no = message.getNumOn();
			int na = message.getNumAlive();
			double v = message.getVolts();
			double a = message.getAmps();
			double c = message.getCapacity();
			int e = message.getErrorLevel();
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setBatteryGlobal(v,a,c,e,nb,no,na);
			break;
		}
		case (ModemMessage::tMMThalesBatteryInfo):
		{
			MMThalesBatteryInfo message(pMM);
			int n = message.getNum();
			double v = message.getVolts();
			double a = message.getAmps();
			double c = message.getCapacity();
			double maxv = message.getMaxVolts();
			double minv = message.getMinVolts();
			double t = message.getTemp();
			char s = message.getState();
			char es = message.getErrorState();
			int co = message.getCommsFailures();
			int el = message.getErrorLevel();
			for (j = 0;j<m_recips.GetSize();j++)m_recips[j]->setBatteryInfo(n,v,a,minv,maxv,t,c,s,es,co,el);
			break;
		}	
		case (ModemMessage::tMMDvl):
		{
			MMDvl message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDvl(message.getVx(),message.getVy(),message.getVz(),
				message.getRange());
			break;
		}
		case (ModemMessage::tMMDvlBeamVelocities):
		{
			MMDvlBeamVelocities message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDvlBeamVelocities(message.getVelocity1(),message.getVelocity2(),
				message.getVelocity3(),message.getVelocity4());
			break;
		}
		case (ModemMessage::tMMDvlBeamRanges):
		{
			MMDvlBeamRanges message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDvlBeamRanges(message.getRange1(),message.getRange2(),
				message.getRange3(),message.getRange4());
			break;
		}
		case (ModemMessage::tMMDvlAttTemp):
		{
			MMDvlAttTemp message(pMM);
			for (j = 0;j <m_recips.GetSize();j++)m_recips[j]->setDvlAttTemp(MMUtil::radToDeg(message.getRoll()), 
				MMUtil::radToDeg(message.getPitch()),MMUtil::radToDeg(message.getYaw()), message.getTemp());
			break;
		}
		case (ModemMessage::tMMHoming):
		{
			MMHoming message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setHoming(message.getAzimuth(),message.getRangeRate());
			break;
		}
		case (ModemMessage::tMMGps):
		{
			MMGps message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setGps(MMUtil::radToDeg(message.getLatitude()),
				MMUtil::radToDeg(message.getLongitude()),
				message.getDifferential() ? true : false,
				message.getNumSatellites(),message.getHdop(),
				message.getUpdateTime());
			break;
		}
		case (ModemMessage::tMMString):
		{
			MMString message(pMM);
			char hold[256];
			message.getString(hold);
			handleString(hold);
			break;
		}
		case (ModemMessage::tMMNmea):
		{
			MMNmea message(pMM);
			message.toString(str);
			if (POPUP_BOXES) m_dialog->MessageBox(str);
			message.getString(str);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setNmeaPos(str);
			break;
		}
		case (ModemMessage::tMMDriver):
		{
			MMDriver message(pMM);
			char buf[256];
			message.getDriverName(buf);
			for (j = 0;j<m_recips.GetSize();j++) m_recips[j]->setDriverStatus(buf,message.getDriverStatus());
			break;
		}
	}
}


void CDashboardRecipient::send(ModemMessage *message) {
	//	TRACE("Sending message length: %d type: %d\n",message->nBinaryBytes(), message->getType());
	if (ModemBroker::getModemBroker() && ModemBroker::getModemBroker()->hasConnection()){
		ModemBroker::getModemBroker()->addMessage(message);
	} else {
		delete message;
		return;
	}
	for (int j = 0;j<m_recips.GetSize();j++) m_recips[j]->sentMessage(message);
}


void CDashboardRecipient::setRequestBlock(bool b)
{
	m_requestBlock = b;
}


////////////////////////////////////////////////////
void CDashboardRecipient::requestData(MMAgentRequest::Request request,
	ModemMessage::Type type, int period, bool blockOverride)
{
	Assert(m_MessageManager);
	if (m_MessageManager->checkRequest(&request, 
											type,
											&period,
											blockOverride)) {
		MMAgentRequest agentRequest(request,type,period);
		ModemMessage * dummy = new ModemMessage(&agentRequest);
		send( dummy );
		addRequest(&agentRequest);
	}
}

////////////////////////////////////////////////////
void CDashboardRecipient::addRequest(MMAgentRequest *request)
{
	POSITION pos = m_requestList->GetHeadPosition();
	while( pos != NULL )
	{
		MMAgentRequest *agentRequest = m_requestList->GetNext( pos );
		if (agentRequest->getRequestType() == request->getRequestType()) {
			agentRequest->setRequest(request->getRequest());
			agentRequest->setPeriod(request->getPeriod());
			return;
		}
	}
	m_requestList->AddTail(request);
}

////////////////////////////////////////////////////////////////////
void CDashboardRecipient::removeDataRecipient(CDataRecipient *recip)
{			
	for(int i = 0; i < m_recips.GetSize(); i++){
		if(m_recips[i]->myIdent() == recip->myIdent() &&
		   m_recips[i]->myIdent().GetBuffer(0) != "not_defined"){
			m_recips.RemoveAt(i);
		}
	}
}

////////////////////////////////////////////////////
void CDashboardRecipient::stopAllRequests()
{
//	if (!CONNECT_REMOTE || !m_pBroker) return;
	POSITION pos = m_requestList->GetHeadPosition();
	while( pos != NULL )
	{
		MMAgentRequest *agentRequest = m_requestList->GetNext( pos );
		agentRequest->setRequest(MMAgentRequest::Stop);
		//agentRequest->sendRemote();
		send( new ModemMessage(agentRequest) );
	}
	m_requestList->RemoveAll();
}

////////////////////////////////////////////////////
void CDashboardRecipient::setTailcone(double propRpm, double elevDeg,
	double rudderDeg)
{
//	if (!CONNECT_REMOTE || !m_pBroker) return;
	double elevRad = MMUtil::degToRad(elevDeg);
	double rudderRad = MMUtil::degToRad(rudderDeg);
	MMTailcone message(propRpm,elevRad,rudderRad,0);
	//message.sendRemote();
	send( new ModemMessage(&message) );

}

////////////////////////////////////////////////////
void CDashboardRecipient::setCircuit(int number, bool value)
{
//	if (!CONNECT_REMOTE || !m_pBroker) return;
	MMCircuit message(number,value);
	//message.sendRemote();
	send( new ModemMessage(&message) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::setAllCircuits(bool values[])
{
//	if (!CONNECT_REMOTE || !m_pBroker) return;
	Assert(m_numCircuits > 0);
	MMCircuitBatch message(m_numCircuits);
	for (int i=0; i<message.getNumber(); i++)
		message.setValue(i,values[i]);
	//message.sendRemote();
	send( new ModemMessage(&message) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::releaseDropWeight(int weight, bool fire)
{
	// if (!CONNECT_REMOTE || !m_pBroker) return;
	MMDropWeightRelease message(weight,fire);
	//message.sendRemote();
	send( new ModemMessage(&message) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::setCommand(double propRpm, double elevAngle,
	double rudderAngle)
{
	// if (!CONNECT_REMOTE || !m_pBroker) return;
	MMDynamicControlCommand command(propRpm,elevAngle,rudderAngle,-1);
	//command.sendRemote();
	send( new ModemMessage(&command) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::setCommand(double propSpeed, double elevAngle,
	double rudderAngle, int speedMode, int verticalMode, int horizontalMode)
{
	// if (!CONNECT_REMOTE || !m_pBroker) return;
	MMDynamicControlCommandFull command(propSpeed,elevAngle,rudderAngle,
		speedMode,verticalMode,horizontalMode,-1);
	//command.sendRemote();
	send( new ModemMessage(&command) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::setBatteryPower(int pack, bool value)
{
	// if (!CONNECT_REMOTE || !m_pBroker) return;
	//MMBatteryPower message(pack,value);
	//message.sendRemote();
//	send( new ModemMessage(&message) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::setBatteryPower(bool value)
{
	// if (!CONNECT_REMOTE || !m_pBroker) return;
//	MMBatteryPowerBatch message(m_numBatteryPacks);
//	for (int i=0; i<m_numBatteryPacks; i++) {
//		message.setValue(i,value);
//	}
	//message.sendRemote();
//	send( new ModemMessage(&message) );
}

////////////////////////////////////////////////////
void CDashboardRecipient::setWatchdog(int watchdog, bool value)
{
	// if (!CONNECT_REMOTE || !m_pBroker) return;
	MMWatchdog message(watchdog,value);
	//message.sendRemote();
	send( new ModemMessage(&message) );
}

////////////////////////////////////////////////////
int CDashboardRecipient::port2int(const char *port)
{
	CString s = port;
	int val = 0; 
	char temp[128];

	if(s.IsEmpty()) return -1;
	if(s.Find("/dev/ser") == -1 ) return -1;

	if(s.Find("node2") > -1) {
		val = 10;
	}
	s = s.Right(s.GetLength() - s.ReverseFind('/')-1);
	try {
		strcpy(temp,s.GetBuffer(0));
		return(val + atoi(&temp[3]));
	} catch(...){}
	
	return -1;	
}


void CDashboardRecipient::setNmeaString(char* str)
{
	if (strlen(str) > 0) {
		MMNmea message(str);
		//message.sendRemote();
		send( new ModemMessage(&message) );
		//double la, lo;
		//int sec, nan;
		//message.parseNmea(&la, &lo, &sec, &nan);
	}
}

void CDashboardRecipient::setRtcmString(char* str, int len)
{
	if (len > 0) {
		MMRtcm message(str,len);
		//message.sendRemote();
/*
		ModemMessage * test = new ModemMessage(&message);

		MMRtcm r(test);

		char buf[256];
		int l = r.getRtcm(buf);
*/
		send( new ModemMessage(&message) );
	}
}

void CDashboardRecipient::setServer(int port, int val)
{
	MMServer message(port,val);
	//message.sendRemote();
	send( new ModemMessage(&message) );
}

void CDashboardRecipient::setMission(char * missionFile, char * abortFile, short startMission)
{
	MMMissionInfo message(missionFile, abortFile, startMission);
	//message.sendRemote();
	send( new ModemMessage(&message) );
}

void CDashboardRecipient::setBehavior(short stateNum, short priorityNum,
									  short nameSize, char* name,
									  short dataSize, char* data)
{
	_lastBehavior = new MMBehavior(stateNum, priorityNum, nameSize, name,
					   dataSize, data);

	send( new ModemMessage(_lastBehavior) );
}

void CDashboardRecipient::setBehaviorArray(short numChanges, short* states,
										   short* priorities, short *nameSizes,
										   char**names, short* dataSizes, char** data)
{	
	_lastBehaviorArray = new MMBehaviorArray(numChanges, states, priorities,
											 nameSizes, names, dataSizes, data);
	/*
	char* temp;
	char* temp2;

	temp = new char[64];
	temp2 = new char[64];

	_lastBehaviorArray->getSingleName(0, temp);
	_lastBehaviorArray->getSingleData(0, temp2);

	TRACE("numChanges: %d first name: %s data: %s\n", _lastBehaviorArray->getNumChanges(),
			temp,temp2); 

	*/
	send( new ModemMessage(_lastBehaviorArray) );
}

void CDashboardRecipient::setNormalMissionName(char* name, int jump)
{
	int ll = strlen(name);

	MMMissionName* message = new MMMissionName(ll, name, MMMissionName::Normal, jump);
	send(new ModemMessage(message) );

	char n[64]; 
	message->getMissionName(n);
	TRACE("More: %s %d\n",n, message->getMissionNameSize());
	delete message;
}

void CDashboardRecipient::setAbortMissionName(char* name, int jump)
{
	int ll = strlen(name);
	MMMissionName* message = new MMMissionName(ll, name, MMMissionName::Abort, jump);

	send(new ModemMessage(message) );

	delete message;
}

void CDashboardRecipient::setDriverCommand(char* name, Boolean turnOn)
{
	MMDriver* message = new MMDriver(name, turnOn);

	send(new ModemMessage(message) );
	delete message;
}

void CDashboardRecipient::setString(char* str)
{
	MMString* message = new MMString(str);
	send(new ModemMessage(message) );
	delete message;
}

void CDashboardRecipient::setJumpBehavior(int s)
{ 
	MMJumpBehavior* message = new MMJumpBehavior(s);
	send(new ModemMessage(message) );
	delete message;
}

void CDashboardRecipient::sendUSBLFix(long fixNum, float rxPitch, float rxRoll, float rxHeading, float dcl, float dcm, float eastings, float northings, Boolean reset) 
{
	// 1. Send usbl fix
	MMUSBLFix* message = new MMUSBLFix(fixNum, rxPitch, rxRoll, rxHeading, dcl, dcm, eastings, northings, reset);
	send(new ModemMessage(message));
	
	// 2. Send any pending requests, info, etc.
	
	Assert(m_MessageManager);
	m_MessageManager->sendNavMessages();

}

void CDashboardRecipient::handleString(char* str)
{
	//first we have to parse it
	//commas should seperate arguments
	CStringArray rec;
	

	CString whole = str;
	int place;

	while((place = whole.Find(",")) != -1) {
		CString arg = whole.Left(place);
		whole = whole.Right(whole.GetLength() - place - 1);
		whole.TrimLeft();
		rec.Add(arg);
	}

	//add everything left
	rec.Add(whole);

	//now actually do something with this
	if(rec[0] == "SupervisorLogDir") {
		for (int j = 0;j <m_recips.GetSize();j++)m_recips[j]->setLogDirName(rec[1]);
	} else if(rec[0] == "controlExecute") {
		for (int j = 0;j <m_recips.GetSize();j++)m_recips[j]->setControlExecute(rec[1]);
	}
}	
	


////////////////////////////////////////////////////
void CDashboardRecipient::test()
{
//	MMBatteryPackStatus message(1,1,1);
	//message.sendLocal();

}

