// ReceiveAll.cpp : implementation file
//

#include "stdafx.h"

#include "AVDSNetworkTest.h"
#include "ReceiveAll.h"
	//These are the formal declarations of the static variables from the class CReceiveAll
	int CReceiveAll::m_iCurrentCraftId[NUM_BLANKS];
	DWORD CReceiveAll::dwCurrentTimeMs[NUM_BLANKS];
	DWORD CReceiveAll::dwLastTimeMs[NUM_BLANKS];
	DWORD CReceiveAll::dwElapsedTimeMs[NUM_BLANKS];
	double CReceiveAll::m_dTotalTimeSec;

	int CReceiveAll::m_iCraftID[NUM_BLANKS];
	CString CReceiveAll::m_strHandle[NUM_BLANKS];
	float CReceiveAll::m_fReceiveRate[NUM_BLANKS];
	int CReceiveAll::m_iPosX[NUM_BLANKS];
	int CReceiveAll::m_iPosY[NUM_BLANKS];
	int CReceiveAll::m_iPosZ[NUM_BLANKS];

#define CRAFT_ID_NOT_USED 999999		//this is a dummy host id that 'probably' won't be in use	
void CALLBACK PacketHandler(Aircraft *);




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

#define TIME_RECEIVE_HZ 25	// check for packets at the rate of 25 times a second
#define TIMER_RECEIVE 1

/////////////////////////////////////////////////////////////////////////////
// CReceiveAll property page

IMPLEMENT_DYNCREATE(CReceiveAll, CPropertyPage)

CReceiveAll::CReceiveAll() : CPropertyPage(CReceiveAll::IDD)
{
	//{{AFX_DATA_INIT(CReceiveAll)
	//}}AFX_DATA_INIT

	m_iCraftIdIds[0] = IDC_STATIC_CRAFT_ID1;
	m_iHandleIds[0] = IDC_STATIC_HANDLE1;
	m_iRateIds[0] = IDC_STATIC_RATE1;
	m_iXPosIds[0] = IDC_STATIC_XPOS1;
	m_iYPosIds[0] = IDC_STATIC_YPOS1;
	m_iZPosIds[0] = IDC_STATIC_ZPOS1;

	m_iCraftIdIds[1] = IDC_STATIC_CRAFT_ID2;
	m_iHandleIds[1] = IDC_STATIC_HANDLE2;
	m_iRateIds[1] = IDC_STATIC_RATE2;
	m_iXPosIds[1] = IDC_STATIC_XPOS2;
	m_iYPosIds[1] = IDC_STATIC_YPOS2;
	m_iZPosIds[1] = IDC_STATIC_ZPOS2;

	m_iCraftIdIds[2] = IDC_STATIC_CRAFT_ID3;
	m_iHandleIds[2] = IDC_STATIC_HANDLE3;
	m_iRateIds[2] = IDC_STATIC_RATE3;
	m_iXPosIds[2] = IDC_STATIC_XPOS3;
	m_iYPosIds[2] = IDC_STATIC_YPOS3;
	m_iZPosIds[2] = IDC_STATIC_ZPOS3;

	m_iCraftIdIds[3] = IDC_STATIC_CRAFT_ID4;
	m_iHandleIds[3] = IDC_STATIC_HANDLE4;
	m_iRateIds[3] = IDC_STATIC_RATE4;
	m_iXPosIds[3] = IDC_STATIC_XPOS4;
	m_iYPosIds[3] = IDC_STATIC_YPOS4;
	m_iZPosIds[3] = IDC_STATIC_ZPOS4;

	m_iCraftIdIds[4] = IDC_STATIC_CRAFT_ID5;
	m_iHandleIds[4] = IDC_STATIC_HANDLE5;
	m_iRateIds[4] = IDC_STATIC_RATE5;
	m_iXPosIds[4] = IDC_STATIC_XPOS5;
	m_iYPosIds[4] = IDC_STATIC_YPOS5;
	m_iZPosIds[4] = IDC_STATIC_ZPOS5;

	m_iCraftIdIds[5] = IDC_STATIC_CRAFT_ID6;
	m_iHandleIds[5] = IDC_STATIC_HANDLE6;
	m_iRateIds[5] = IDC_STATIC_RATE6;
	m_iXPosIds[5] = IDC_STATIC_XPOS6;
	m_iYPosIds[5] = IDC_STATIC_YPOS6;
	m_iZPosIds[5] = IDC_STATIC_ZPOS6;

	m_iCraftIdIds[6] = IDC_STATIC_CRAFT_ID7;
	m_iHandleIds[6] = IDC_STATIC_HANDLE7;
	m_iRateIds[6] = IDC_STATIC_RATE7;
	m_iXPosIds[6] = IDC_STATIC_XPOS7;
	m_iYPosIds[6] = IDC_STATIC_YPOS7;
	m_iZPosIds[6] = IDC_STATIC_ZPOS7;

	m_iCraftIdIds[7] = IDC_STATIC_CRAFT_ID8;
	m_iHandleIds[7] = IDC_STATIC_HANDLE8;
	m_iRateIds[7] = IDC_STATIC_RATE8;
	m_iXPosIds[7] = IDC_STATIC_XPOS8;
	m_iYPosIds[7] = IDC_STATIC_YPOS8;
	m_iZPosIds[7] = IDC_STATIC_ZPOS8;

	m_iCraftIdIds[8] = IDC_STATIC_CRAFT_ID9;
	m_iHandleIds[8] = IDC_STATIC_HANDLE9;
	m_iRateIds[8] = IDC_STATIC_RATE9;
	m_iXPosIds[8] = IDC_STATIC_XPOS9;
	m_iYPosIds[8] = IDC_STATIC_YPOS9;
	m_iZPosIds[8] = IDC_STATIC_ZPOS9;

	m_iCraftIdIds[9] = IDC_STATIC_CRAFT_ID10;
	m_iHandleIds[9] = IDC_STATIC_HANDLE10;
	m_iRateIds[9] = IDC_STATIC_RATE10;
	m_iXPosIds[9] = IDC_STATIC_XPOS10;
	m_iYPosIds[9] = IDC_STATIC_YPOS10;
	m_iZPosIds[9] = IDC_STATIC_ZPOS10;

	for(int i=0;i<NUM_BLANKS;i++){	
		m_iCurrentCraftId[i] = CRAFT_ID_NOT_USED;
		m_dTotalTimeSec = 0.0;
	}
}

CReceiveAll::~CReceiveAll()
{
}

void CReceiveAll::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CReceiveAll)
	DDX_Control(pDX, IDC_CHECK_STOP, m_ctrlButtonStop);
	DDX_Control(pDX, IDC_CHECK_START, m_ctrlButtonStart);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CReceiveAll, CPropertyPage)
	//{{AFX_MSG_MAP(CReceiveAll)
	ON_BN_CLICKED(IDC_CHECK_START, OnCheckStart)
	ON_BN_CLICKED(IDC_CHECK_STOP, OnCheckStop)
	ON_WM_TIMER()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReceiveAll message handlers

void CReceiveAll::OnCheckStart() 
{
	if (m_ctrlButtonStart.GetCheck()){
		int iCount = 1;
		char* strAddress[1];
		strAddress[0] = strdup("224.0.5.20:2267");/* this is the default AVDS multicast address*/
		OpenAVDSNetwork(iCount,strAddress);

#ifdef STEVETEST
		for(i=0;i<NUM_BLANKS;i++){	
			dwLastTimeMs[i] = GetTickCount();
		}
#else	//STEVETEST
#define TIME_UPDATE 10
		SetTimer(TIMER_RECEIVE, (int)(1000.0/(float)TIME_RECEIVE_HZ), NULL);
		MMSetCallbackTimer(&m_uiTimerID,TIME_UPDATE);
		m_uiTotalTimeID = iStartElapsedTimer();
		for(int i=0;i<NUM_BLANKS;i++){	
			dwLastTimeMs[i] = 0.0;
		}
#endif	//STEVETEST

	}
	m_ctrlButtonStart.SetCheck(TRUE);
	m_ctrlButtonStop.SetCheck(FALSE);
	m_SetBlanksNull();
}

void CReceiveAll::OnCheckStop() 
{
	if (m_ctrlButtonStop.GetCheck()){
#ifdef STEVETEST
#else	//STEVETEST
		KillTimer(TIMER_RECEIVE);
		MMDestroyTimer(m_uiTimerID);
#endif	//STEVETEST
//		CloseAVDSNetwork();
	}
	m_ctrlButtonStart.SetCheck(FALSE);
	m_ctrlButtonStop.SetCheck(TRUE);
	m_SetBlanksNull();
	
}

BOOL CReceiveAll::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	

	m_SetBlanksNull();

	m_ctrlButtonStart.SetCheck(FALSE);
	m_ctrlButtonStop.SetCheck(TRUE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CReceiveAll::OnTimer(UINT nIDEvent) 
{
	switch (nIDEvent)
	{
		case TIMER_RECEIVE:
#ifdef STEVETEST
			m_ReceivePackets();
#endif	//STEVETEST
			OnPaint();
			break;
	}
	CPropertyPage::OnTimer(nIDEvent);
}

void CReceiveAll::m_SetBlanksNull()
{
	CString strTextTmp;

	strTextTmp="";

	for(int i=0;i<NUM_BLANKS;i++){	
		SetDlgItemText(m_iCraftIdIds[i],strTextTmp);
		SetDlgItemText(m_iHandleIds[i],strTextTmp);
		SetDlgItemText(m_iRateIds[i],strTextTmp);
		SetDlgItemText(m_iXPosIds[i],strTextTmp);
		SetDlgItemText(m_iYPosIds[i],strTextTmp);
		SetDlgItemText(m_iZPosIds[i],strTextTmp);

		m_iCurrentCraftId[i]=CRAFT_ID_NOT_USED;

		m_iCraftID[i] = 0;
		m_strHandle[i] = "";
		m_fReceiveRate[i] = 0;
		m_iPosX[i] = 0;
		m_iPosY[i] = 0;
		m_iPosZ[i] = 0;

	}


}

void CReceiveAll::m_ReceivePackets()
{
	Get_Aircraft(StaticPacketHandler,&acftReceived);
}


void CReceiveAll::WorkFunction(UINT uiTimerID)
{
	m_dTotalTimeSec = dGetTimeSinceStartSec(m_uiTotalTimeID);
	Get_Aircraft(StaticPacketHandler,&acftReceived);
}


void CALLBACK CReceiveAll::StaticPacketHandler(Aircraft *aP)
{

	int iChoice = NUM_BLANKS;	//intitialize to not a choice


	for(int i=0;i<NUM_BLANKS;i++){	
		if (aP->packet.craftid == m_iCurrentCraftId[i]){
			iChoice = i;
			break;
		}else if (m_iCurrentCraftId[i] == CRAFT_ID_NOT_USED){	
			iChoice = i;
			m_iCurrentCraftId[i] = aP->packet.craftid;
			break;
		}
	}
	if (iChoice<NUM_BLANKS){
		dwCurrentTimeMs[iChoice] = m_dTotalTimeSec * 1000.0;
		dwElapsedTimeMs[iChoice] = dwCurrentTimeMs[iChoice]-dwLastTimeMs[iChoice];
		dwLastTimeMs[iChoice] = dwCurrentTimeMs[iChoice];
		m_fReceiveRate[iChoice] = (float)(1000.0/dwElapsedTimeMs[iChoice]);

		m_iCraftID[iChoice] = aP->packet.craftid;
		m_strHandle[iChoice] = aP->packet.handle;
		m_iPosX[iChoice] = (int)aP->pos_X;
		m_iPosY[iChoice] = (int)aP->pos_Y;
		m_iPosZ[iChoice] = (int)aP->pos_Z;

	}
}

void CReceiveAll::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	CString strTextTmp;
	for(int i=0;i<NUM_BLANKS;i++){	
		strTextTmp.Format("%i",m_iCraftID[i]);
		SetDlgItemText(m_iCraftIdIds[i],strTextTmp);
		strTextTmp.Format("%s",m_strHandle[i]);
		SetDlgItemText(m_iHandleIds[i],strTextTmp);
		strTextTmp.Format("%3.2f",m_fReceiveRate[i]);
		SetDlgItemText(m_iRateIds[i],strTextTmp);
		strTextTmp.Format("%i",m_iPosX[i]);
		SetDlgItemText(m_iXPosIds[i],strTextTmp);
		strTextTmp.Format("%i",m_iPosY[i]);
		SetDlgItemText(m_iYPosIds[i],strTextTmp);
		strTextTmp.Format("%i",m_iPosZ[i]);
		SetDlgItemText(m_iZPosIds[i],strTextTmp);
	}
	
	// Do not call CPropertyPage::OnPaint() for painting messages
}

