//
//  Copyright (c) 2001, Reson, Inc. All Rights Reserved.
//
//  Filename:   6046DryEndDlg.cpp : implementation file
//
//  Project:    6046DryEnd
//
//  Author(s):  J. Marcus    
//
//  Purpose:    Defines the main window of the application, as well as most of the processing
//			
//
//  Notes:      
//              
//
//
//
//
//
//
//
#include "stdafx.h"
#include "6046DryEndDlg.h"
#include "Mmsystem.h"

#pragma comment( lib, "Winmm.lib" )

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMy6046DryEndDlg dialog

void CMy6046DryEndDlg::SimulateXMLMsg()
{
	CFile file;
	if(file.Open("C:\\7kSim\\7k_0.xml", CFile::modeRead, 0))
	{
		ULONG size = file.GetLength();

		char *buffer = new char[size+ 250];

		file.Read(buffer, size);

		file.Close();

		m_xmlParsor.Set7001Info(buffer);

		delete [] buffer;
		buffer = NULL;
	}
}


CMy6046DryEndDlg::CMy6046DryEndDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMy6046DryEndDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMy6046DryEndDlg)
	m_strSysTime = _T("");
	m_strRecTime = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	////////////////////////////////////////////////
	//EXTRA INNITIALIZATIONS
	m_bSyncTime				= FALSE;
	m_bFolderPlay			= FALSE;
	m_bPlaying				= FALSE;
	m_bAllFilesPlayed		= FALSE;
	m_bLogging				= FALSE;
	m_bEOFReached			= FALSE;
	m_bWaterfallHIGH		= m_bWaterfallLOW = m_bWaterfallSBP = m_bBathy = m_bImagery = FALSE; 
	m_bAttitude				= m_bDepth = m_bHeading = m_bNav = m_bTextOnly = FALSE;

	m_ToggleState			= ALL;
	modeState				= COLLECT;
	
	bXTFPlayerInitialized	= FALSE;
	b7KPlayerInitialized	= FALSE;

	m_bRemoteConnected		= FALSE;
	
	m_dlgPopupReport		= NULL;
	m_bPopupReport			= FALSE;

	//Set last lit LED 
	m_pLedLastLit			= NULL;
	
	//Timer ID's
	m_uiTimeTimerID = m_uiAlarmTimerID = m_uiFileTimerID = m_uiPLCSyncTimerID = 0;

	//Init processing counters
	m_HFSSPingsProcessed	= 0;
	m_LFSSPingsProcessed	= 0;
	m_ulLastBeams			= 0;
	
	//Init Data extraction buffers
	m_ulMaxBuffer			= sizeof( RECORDHEADER7K ) + sizeof( SIDESCANRECORDTYPEHEADER ) + 
							  2 * ( sizeof( CHANNELINFO ) + (512*1024*2) ) + sizeof( unsigned long );
	
	Data16Bit				= new short[m_ulMaxBuffer];
	Data8Bit				= new BYTE[m_ulMaxBuffer];

	m_recReuseRecord.data	= new BYTE[m_ulMaxBuffer];
	m_recReuseRecord.lBytes = 0;

	//Init history buffer
	m_buff7kDataRecords.Configure(m_ulMaxBuffer, 30);
	m_buff7kSysRecords.Configure(m_ulMaxBuffer,  30);

	// Initialize the critical section.
	InitializeCriticalSection(&CriticalSection); 	
}

void CMy6046DryEndDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMy6046DryEndDlg)
	DDX_Control(pDX, IDC_BUTTON_SHOWALL, m_ctrlViewAll);
	DDX_Control(pDX, IDC_MAIN_DSPLY_WEDGE, m_ctrlBtnWedge);
	DDX_Control(pDX, IDC_MAIN_DSPLY_2DBATHY, m_ctrlBtn2DBathy);
	DDX_Control(pDX, IDC_BUTTON_MUTE, m_ctrlMute);
	DDX_Control(pDX, IDC_QV_HEALTH, m_ctrlBtnHealth);
	DDX_Control(pDX, IDC_MAIN_DSPLY_TEXT, m_ctrlBtnTextOnly);
	DDX_Control(pDX, IDC_MAIN_DSPLY_SPEEDS, m_ctrlBtnSpeeds);
	DDX_Control(pDX, IDC_BTN_VIEWREPORT, m_ctrlViewReport);
	DDX_Control(pDX, IDC_QV_REFRESH, m_ctrlRefresh);
	DDX_Control(pDX, IDC_QV_MODULES, m_ctrlBtnModules);
	DDX_Control(pDX, IDC_MAIN_BTN_TOGGLE2, m_ctrlToggle2);
	DDX_Control(pDX, IDC_QV_SUMMARY, m_ctrlBtnSummary);
	DDX_Control(pDX, IDC_QV_GENERAL, m_ctrlBtnGeneral);
	DDX_Control(pDX, IDC_MAIN_DSPLY_SBP, m_ctrlBtnSBP);
	DDX_Control(pDX, IDC_MAIN_DSPLY_HFWF, m_ctrlBtnHFWF);
	DDX_Control(pDX, IDC_MAIN_DSPLY_LFWF, m_ctrlBtnLFWF);
	DDX_Control(pDX, IDC_MAIN_DSPLY_HEADING, m_ctrlBtnHeading);
	DDX_Control(pDX, IDC_MAIN_DSPLY_DEPTH, m_ctrlBtnDepth);
	DDX_Control(pDX, IDC_MAIN_DSPLY_ATTITUDE, m_ctrlBtnAttitude);
	DDX_Control(pDX, IDC_MAIN_BTN_TOGGLE, m_ctrlToggle);
	DDX_Control(pDX, IDC_MAIN_BTN_QUIT, m_ctrlQuit);
	DDX_Control(pDX, IDC_BTN_STOP, m_ctrlStop);
	DDX_Control(pDX, IDC_BTN_RECORD, m_ctrlRecord);
	DDX_Control(pDX, IDC_LED_HEALTH, m_ctrlLedHealth);
	DDX_Control(pDX, IDC_LED_RUNLIST, m_ctrlLedRunlist);
	DDX_Control(pDX, IDC_LED_REPORT, m_ctrlLedReport);
	DDX_Control(pDX, IDC_LED_MODULES, m_ctrlLedModules);
	DDX_Control(pDX, IDC_LED_GENERAL, m_ctrlLedGeneral);
	DDX_Control(pDX, IDC_LED1, m_Led1);
	DDX_Control(pDX, IDC_MAIN_MODE_COMBO, m_ctrlMode);
	DDX_Control(pDX, IDC_MAIN_TOGGLE_TOP, m_ctrlToggleTop);
	DDX_Control(pDX, IDC_MAIN_TOGGLE_MID, m_ctrlToggleMid);
	DDX_Control(pDX, IDC_MAIN_RECTIME, m_ctrlRecTime);
	DDX_Control(pDX, IDC_MAIN_SYSTIME, m_ctrlSysTime);
	DDX_Control(pDX, IDC_MAIN_QVWND, m_ctrlQVWnd);
	DDX_Control(pDX, IDC_MAIN_TABS, m_ctrlMainTabs);
	DDX_Text(pDX, IDC_MAIN_SYSTIME, m_strSysTime);
	DDX_Text(pDX, IDC_MAIN_RECTIME, m_strRecTime);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMy6046DryEndDlg, CDialog)
	//{{AFX_MSG_MAP(CMy6046DryEndDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_DESTROY()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_MAIN_BTN_QUIT, OnMainBtnQuit)
	ON_BN_CLICKED(IDC_MAIN_BTN_TOGGLE, OnMainBtnToggle)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_SBP, OnMainDsplySbp)
	ON_BN_CLICKED(IDC_BTN_RECORD, OnBtnRecord)
	ON_BN_CLICKED(IDC_BTN_STOP, OnBtnStop)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_HFWF, OnMainDsplyHfwf)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_LFWF, OnMainDsplyLfwf)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_ATTITUDE, OnMainDsplyAttitude)
	ON_CBN_SELCHANGE(IDC_MAIN_MODE_COMBO, OnSelchangeMainModeCombo)
	ON_WM_LBUTTONDOWN()
	ON_BN_CLICKED(IDC_MAIN_DSPLY_DEPTH, OnMainDsplyDepth)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_HEADING, OnMainDsplyHeading)
	ON_BN_CLICKED(IDC_MAIN_BTN_TOGGLE2, OnMainBtnToggle2)
	ON_BN_CLICKED(IDC_QV_GENERAL, OnQvGeneral)
	ON_BN_CLICKED(IDC_QV_MODULES, OnQvModules)
	ON_BN_CLICKED(IDC_QV_RUNLIST, OnQvRunlist)
	ON_BN_CLICKED(IDC_QV_REFRESH, OnQvRefresh)
	ON_BN_CLICKED(IDC_BTN_VIEWREPORT, OnBtnViewreport)
	ON_BN_CLICKED(IDC_BTN_ALTQUIT, OnBtnAltquit)
	ON_BN_CLICKED(IDC_BTN_MINIMIZE, OnBtnMinimize)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_SPEEDS, OnMainDsplyNavigation)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_TEXT, OnMainDsplyText)
	ON_BN_CLICKED(IDC_QV_HEALTH, OnQvHealth)
	ON_BN_CLICKED(IDC_BUTTON_MUTE, OnButtonMute)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_2DBATHY, OnMainDsply2dbathy)
	ON_BN_CLICKED(IDC_MAIN_DSPLY_WEDGE, OnMainDsplyWedge)
	ON_WM_CLOSE()
	ON_WM_CAPTURECHANGED()
	ON_WM_CANCELMODE()
	ON_BN_CLICKED(IDC_BUTTON_SHOWALL, OnButtonShowall)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//		CMy6046DryEndDlg GENERAL INITIALIZATION MESSAGES					//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
BOOL CMy6046DryEndDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	//This needs to be here if we want the list control 
	//to have the behavior of moving the parent window
	//when the user clicks and drags on the list
	m_ctrlQVWnd.pParent = this;

	m_7kReader.InitReader(this, &CMy6046DryEndDlg::CallbackData);

	// Add "About..." menu item to system menu.
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
		//SYS MENU - DISBALE THE CLOSE BUTTON BUT KEEP THE MINIMIZE ONE
		//pSysMenu->EnableMenuItem(SC_CLOSE,MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	//Init the config object ptr
	m_pConfig = &((CMy6046DryEndApp*)AfxGetApp())->m_SystemConfig;

	//Call out initialization helper functions
	LoadImages();
	InitCtrlBarItems();
	InitTabs();
	InitToggle();
	InitAlarmLeds();
	InitQVLeds();
	InitButtons();
	
	//Initialize the Quick View manager with the address of the QV List Ctrl object
	m_QVManager.SetDisplayPtr(&m_ctrlQVWnd, &m_ctrlMainTabs, this->m_hWnd);	
	OnQvGeneral(); //Start with General
	m_QVManager.DisplayNoSync();

	//Initialize the Display manager
	m_DspManager.LoadDisplays();

	//Setup File reader
	m_7kReader.SetParentHWND(this->m_hWnd);

	//Init popup report
	if (m_dlgPopupReport == NULL)
	{
		m_dlgPopupReport = new CDlgPopupReport ;
		m_dlgPopupReport->Create(IDD_DLG_POPUPREPORT, CWnd::GetDesktopWindow()) ;
	}

	//Begin the Clock timer
	m_uiTimeTimerID = SetTimer(TIME_EVENT, 1000, NULL);

	//Set window frame text
	m_str6046ON.LoadString(IDS_6046_ON);
	m_str6046OFF.LoadString(IDS_6046_OFF);
	SetWindowText(m_str6046OFF);
	
	//Now Load the settings and prepare the windows
	LoadSettings();

	m_uiInternalAlarmCount = 0;
	
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::LoadSettings()
{
	if(m_pConfig->Open(CSystemConfig::accessRead)){
		m_pConfig->Read();
		m_pConfig->Close();
	}
	m_ToggleState = (TOGGLESTATE)m_pConfig->MAINToggleState;
	
	switch(m_ToggleState)
	{
	case ALL:{break;}
	case MID:{m_ToggleState = ALL; OnMainBtnToggle(); break;}
	case TOP:{m_ToggleState = MID; OnMainBtnToggle(); break;}
	}

	this->SetWindowPos(NULL,m_pConfig->MAINWindowX, m_pConfig->MAINWindowY,
						0,0,SWP_NOSIZE);

	if(m_pConfig->bShowHFSS == TRUE)
	{
		m_bWaterfallHIGH = FALSE;
		OnMainDsplyHfwf();
	}
	if(m_pConfig->bShowLFSS == TRUE)
	{
		m_bWaterfallLOW = FALSE;
		OnMainDsplyLfwf();
	}
	if(m_pConfig->bShowSBP == TRUE)
	{
		m_bWaterfallSBP = FALSE;
		OnMainDsplySbp();
	}
	if(m_pConfig->bShowBathy == TRUE)
	{
		m_bTextOnly = FALSE;
		OnMainDsply2dbathy();
	}
	if(m_pConfig->bShowAttitude == TRUE)
	{
		m_bAttitude = FALSE;
		OnMainDsplyAttitude();
	}
	if(m_pConfig->bShowDepth == TRUE)
	{
		m_bDepth = FALSE;
		OnMainDsplyDepth();
	}
	if(m_pConfig->bShowHeading == TRUE)
	{
		m_bHeading = FALSE;
		OnMainDsplyHeading();
	}
	if(m_pConfig->bShowNav == TRUE)
	{
		m_bNav = FALSE;
		OnMainDsplyNavigation();
	}
	if(m_pConfig->bShowASCII == TRUE)
	{
		m_bTextOnly = FALSE;
		OnMainDsplyText();
	}
	if(m_pConfig->bShowImagery == TRUE)
	{
		m_bImagery = FALSE;
		OnMainDsplyWedge();
	}

}

void CMy6046DryEndDlg::SaveSettings()
{
	if(m_pConfig->Open(CSystemConfig::accessWrite))
	{
			m_pConfig->Save();
			m_pConfig->Close();
	}
}

void CMy6046DryEndDlg::LoadImages()
{
	CDC *dc = GetDC();

	bmreson.LoadBitmap(IDB_BMP_LOGO);
  	bmreson.GetBitmap(&bminfo);
	
		// Create the mask bitmap
	nWidth  = bminfo.bmWidth;
	nHeight = bminfo.bmHeight;
	
	bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL);
	
	// Create two memory dcs for the image and the mask
	dcImage.CreateCompatibleDC(dc);
	dcTrans.CreateCompatibleDC(dc);

	dcImage.SelectObject(&bmreson);

	this->ReleaseDC(dc);
}

void CMy6046DryEndDlg::InitCtrlBarItems()
{
	//TIME
	m_ctrlSysTime.SetBkColor(RGB(0,35,0));
	m_ctrlSysTime.SetTextColor(RGB(0,255,55));
	m_ctrlRecTime.SetBkColor(RGB(0,35,0));
	m_ctrlRecTime.SetTextColor(RGB(255,0,0));
	m_ctrlRecTime.SetWindowText("SYSTEM IDLE");
	
	//m_ctrlRecTime.ShowWindow(SW_HIDE);

	//MODE
	m_ctrlMode.SetCurSel(modeState);
		
	m_ctrlMode.SetCurSel(modeState);

}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::InitTabs()
{
  TCITEM tcItem;
  tcItem.mask = TCIF_TEXT;
  
  tcItem.pszText = _T("Setup");
  m_ctrlMainTabs.InsertItem(0, &tcItem);
 
  tcItem.pszText = _T("Displays");
  m_ctrlMainTabs.InsertItem(1, &tcItem);
  
  tcItem.pszText = _T("SSS HF");
  m_ctrlMainTabs.InsertItem(2, &tcItem);

  tcItem.pszText = _T("SSS LF");
  m_ctrlMainTabs.InsertItem(3, &tcItem);

  tcItem.pszText = _T("SBP");
  m_ctrlMainTabs.InsertItem(4, &tcItem);

  //7k DEPENDANT
  //
  tcItem.pszText = _T("7K System");
  m_ctrlMainTabs.InsertItem(5, &tcItem);

  //tcItem.pszText = _T("Trigger Control");
  //m_ctrlMainTabs.InsertItem(6, &tcItem);

  if(modeState == PLAYBACK)
  {
	 tcItem.pszText = _T("Playback");
     m_ctrlMainTabs.InsertItem(6, &tcItem);
  }
  m_ctrlMainTabs.Init();

}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::InitToggle()
{
	GetWindowRect(&m_rectAll);
	m_ctrlToggleTop.GetWindowRect(&m_rectTop);
	m_ctrlToggleMid.GetWindowRect(&m_rectMid);
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::InitAlarmLeds()
{
	m_Led1.SetLed(CLed::LED_COLOR_GREEN, CLed::LED_OFF , CLed::LED_SQUARE);
}


void CMy6046DryEndDlg::InitQVLeds()
{
	m_ctrlLedGeneral.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);
	m_ctrlLedReport.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);
	m_ctrlLedRunlist.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);
	m_ctrlLedModules.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);
	m_ctrlLedHealth.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);;
	
	//This one is lit by default
	m_ctrlLedGeneral.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);

}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::InitButtons()
{
	//See CxShadeButton for info on SetShade()

	//TOGGLE BUTTON
	m_ctrlToggle.SetShade	  (SHS_METAL,8,40,38,RGB(55,55,55));
	m_ctrlToggle2.SetShade	  (SHS_METAL,8,40,38,RGB(55,55,55));
	m_ctrlToggle.SetIcon	  (IDI_ICON_SHRINK, BS_CENTER, 0);
	m_ctrlToggle2.SetIcon	  (IDI_ICON_EXPAND, BS_CENTER, 0);

	//Alarm/Status Panel
	m_ctrlViewReport.SetShade (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlMute.SetShade		  (SHS_HBUMP,8,40,14,RGB(255,255,55));

	//QUIT/HELP ETC BUTTONS
	m_ctrlQuit.SetShade		  (SHS_HARDBUMP,8,40,12,RGB(55,55,55));

	//m_ctrlViewAll.SetIcon	  (IDI_ICON_VIEWALL, BS_CENTER, 0);
	m_ctrlViewAll.SetShade	  (SHS_HARDBUMP,8,40,12,RGB(55,55,55));

	//DISPLAY BUTTONS
	m_ctrlBtnHFWF.SetShade	  (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnLFWF.SetShade	  (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnSBP.SetShade	  (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtn2DBathy.SetShade (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnAttitude.SetShade(SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnDepth.SetShade	  (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnHeading.SetShade (SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnTextOnly.SetShade(SHS_HARDBUMP,8,40,4,RGB(55,55,255));
	m_ctrlBtnSpeeds.SetShade  (SHS_HARDBUMP,8,40,4,RGB(55,55,255));	
	m_ctrlBtnWedge.SetShade	  (SHS_HARDBUMP,8,40,4,RGB(55,55,255));	

	//QUICK VIEW BUTTONS
	m_ctrlBtnGeneral.SetShade (SHS_METAL,8,40,4,RGB(55,55,255));
	m_ctrlBtnSummary.SetShade (SHS_METAL,8,40,4,RGB(55,55,255));
	m_ctrlBtnModules.SetShade (SHS_METAL,8,40,4,RGB(55,55,255));
	m_ctrlBtnHealth.SetShade  (SHS_METAL,8,40,4,RGB(55,55,255));
	m_ctrlRefresh.SetShade    (SHS_METAL,8,60,8,RGB(155,155,0));

	//COMMAND BUTTONS
	m_ctrlRecord.SetShade	  (SHS_HBUMP,8,80,4,RGB(55,255,55));
	//m_ctrlRecord.SetIcon	  (IDI_ICON_RECORD, BS_CENTER, 0);

	m_ctrlStop.SetShade		  (SHS_HBUMP,8,80,4,RGB(255,0,0));
	//m_ctrlStop.SetIcon		  (IDI_ICON_STOP, BS_CENTER, 0);

	//MODE LABELS 
	if(modeState == COLLECT)
		m_ctrlRecord.SetWindowText("Record");
	else
		m_ctrlRecord.SetWindowText("Play");

}


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//		CMy6046DryEndDlg	WINDOWS MESSAGE HANDLERS						//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
		return;
	}
	if((nID & 0xFFF0) == SC_RESTORE)
	{
		//Tell the display Manager that we want all window brought to the top
		m_DspManager.BringToTop();

	}
	if((nID & 0xFFF0) == SC_MINIMIZE)
	{
		//Tell the display Manager that we want all window brought to the top
		m_DspManager.MinimizeAll();
	}
	
	CDialog::OnSysCommand(nID, lParam);

}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::OnDestroy()
{	
	KillTimer(m_uiTimeTimerID);
	
	// Release resources used by the critical section object.
    DeleteCriticalSection(&CriticalSection);
	
	m_ctrlRefresh.~CxShadeButton();
	m_ctrlBtnModules.~CxShadeButton();
	m_ctrlToggle2.~CxShadeButton();
	m_ctrlBtnSummary.~CxShadeButton();
	m_ctrlBtnGeneral.~CxShadeButton();
	m_ctrlBtnSBP.~CxShadeButton();
	m_ctrlBtnHFWF.~CxShadeButton();
	m_ctrlBtnLFWF.~CxShadeButton();
	m_ctrlBtnHeading.~CxShadeButton();
	m_ctrlBtnDepth.~CxShadeButton();
	m_ctrlBtnAttitude.~CxShadeButton();
	m_ctrlToggle.~CxShadeButton();
	m_ctrlQuit.~CxShadeButton();
	m_ctrlStop.~CxShadeButton();
	m_ctrlRecord.~CxShadeButton();
	m_ctrlBtnHeading.~CxShadeButton();
	m_ctrlViewReport.~CxShadeButton();
	
	m_ctrlLedReport.~CLed();
	m_ctrlLedModules.~CLed();
	m_ctrlLedGeneral.~CLed();
	
	m_Led1.~CLed();

	WinHelp(0L, HELP_QUIT);
	CDialog::OnDestroy();
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::OnPaint() 
{
	// If you add a minimize button to your dialog, you will need the code below
	//  to draw the icon.  For MFC applications using the document/view model,
	//  this is automatically done for you by the framework.
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDC *pDC = GetDC();
		CRect rect;
		if(this->m_hWnd)
		{
			GetClientRect(&rect);
			if(m_ToggleState == ALL)
				DrawLogo(pDC, rect.Width()-100,rect.Height()-40, RGB(192,192,192));
		}
		CDialog::OnPaint();
	}
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

HCURSOR CMy6046DryEndDlg::OnQueryDragIcon()
{
	
	// The system calls this to obtain the cursor to display while the user drags
	//  the minimized window.

	return (HCURSOR) m_hIcon;
}


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// OnTimer is used for displaying system time, playback and recording times,
// and Playback speed, which is set by user in Playback Dialog Tab
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void CMy6046DryEndDlg::OnTimer(UINT nIDEvent) 
{
  // BASIC TIME DISPLAY
	switch(nIDEvent)
	{
		case TIME_EVENT:{		time( &RealTime );
								CTime timeNow(RealTime);
								m_strSysTime.Format( "%d:%02d:%02d", timeNow.GetHour(),
																	 timeNow.GetMinute(),
																	 timeNow.GetSecond());  
								if(m_bPlaying == TRUE){
									elapsed = StartTime-RealTime;
									m_strRecTime.Format("%d:%02d:%02d",  abs(elapsed.GetHours()),
																		 abs(elapsed.GetMinutes()),
																		 abs(elapsed.GetSeconds()));
								}
								break;
		}

		case FILE_READ_EVENT:{	//Get data and send to display Manager
								
								if(m_bPlaying == FALSE)
									return;

								int size	 = m_xtfReader.GetSamples();
								BYTE *source = m_xtfReader.GetPing();
								if(source == NULL)
								{	//NULL PING
									return;
								}
								m_DspManager.AddWaterfallData(WFHIGH,source,size);
								//DWORD roll = m_xtfReader.GetRoll();
								//m_DspManager.AddRoll(roll);
								float head = m_xtfReader.GetHeading();
								m_DspManager.AddHeading(head);
								break;
		}

		case ALARM_EVENT:{
								HINSTANCE hModule = AfxGetResourceHandle();
								PlaySound(MAKEINTRESOURCE(IDR_WAVE1),hModule,SND_RESOURCE|SND_ASYNC);
								break;
		}

		case PLC_SYNC_EVENT:{	
								//Refresh all
								OnQvRefresh();	
								break;
		}

		default: break;
	}

	UpdateData(FALSE);
	CDialog::OnTimer(nIDEvent);
}

void CMy6046DryEndDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	//MAKE WINDOWS THINK WE CLICKED ON THE CAPTION BAR,
	//SO THE DIALOG CAN BE MOVED BY CLICKING ANYWHERE ON IT.
   PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));

   
}


BOOL CMy6046DryEndDlg::PreTranslateMessage(MSG* pMsg) 
{
	
	if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
	{
		OnMainBtnQuit();
		return TRUE ;
	}
	if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_CANCEL)
	{
		OnMainBtnQuit();
		return TRUE ;
	}
	if(pMsg->message==WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 && (pMsg->wParam == 'p' || pMsg->wParam == 'P'))
	{
		OnMainBtnQuit();		
	}
	//if(pMsg->message==WM_KEYDOWN && GetAsyncKeyState(VK_ALT) < 0 && (pMsg->wParam == 'p' || pMsg->wParam == 'P'))
	//{
	//	OnMainBtnQuit();		
	//}

	
	return CDialog::PreTranslateMessage(pMsg);
}


void CMy6046DryEndDlg::OnOK() 
{
	if(bXTFPlayerInitialized)
		m_xtfReader.Shutdown();
	if(b7KPlayerInitialized)
		m_7kReader.Shutdown();
	
	if(Data16Bit)
	{
		delete [] Data16Bit;
		Data16Bit = NULL;
	}
	if(Data8Bit)
	{
		delete [] Data8Bit;
		Data8Bit = NULL;
	}
	if(m_recReuseRecord.data)
	{
		delete [] m_recReuseRecord.data;
		m_recReuseRecord.data = NULL;
	}
	if(m_dlgPopupReport->DestroyWindow())
	{
		delete m_dlgPopupReport;
		m_dlgPopupReport = NULL;
	}
	else
		TRACE("ERROR ON DLG DESTROY\r\n");

	Data16Bit				= NULL; 
	Data8Bit				= NULL;
	m_recReuseRecord.data	= NULL;
	m_recReuseRecord.lBytes = 0;

	SaveSettings();
	
	m_DspManager.Cleanup();
	m_ctrlMainTabs.Cleanup();
	
	CDialog::OnOK();
}



LRESULT CMy6046DryEndDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	#pragma CompileMessage_m( "REMOVE HARD CODED TAB INDEX - REPLACE WITH ENUM?" )
	switch(message)
	{
	case FILE_READ_DONE: { m_bEOFReached = TRUE;
						   
						   OnBtnStop(); 
						   if(m_bFolderPlay)
							   m_ctrlMainTabs.NotifyTab(6, FILE_READ_DONE); 
						   else
							   AfxMessageBox("Playback Completed");
						   break; 
						 }	
	case ALL_FILES_PLAYED:{
							m_bAllFilesPlayed = TRUE;
							AfxMessageBox("Playback Completed - All Files");
							break;
						  }
	case SYS_DATA_READY: { SysDataHandler();  break; }
	case REAL_DATA_READY:{ RealTimeHandler(); break; }
	
	case LOGGING_ON:	 {  if(m_bPlaying == TRUE)
								return CDialog::WindowProc(message, wParam, lParam);
							SetWindowText(m_str6046ON);
							m_ctrlMainTabs.NotifyTab(0, LOGGING_ON);
							m_bLogging = TRUE;   

						
							break;
						 }
	
	case LOGGING_OFF:	 {  if(m_bPlaying == TRUE)
								return CDialog::WindowProc(message, wParam, lParam);
							SetWindowText(m_str6046OFF);
							m_ctrlMainTabs.NotifyTab(0, LOGGING_OFF);
							m_bLogging = FALSE; 

						
							break; 
						 }
	case WM_EXITSIZEMOVE:
						{
							//Save the window coordinates cause 
							//it was just moved
							CRect rect;
							this->GetWindowRect(rect);

							m_pConfig->MAINWindowX = rect.left;
							m_pConfig->MAINWindowY = rect.top;
							SaveSettings();
							break;
						}
	case 112358:
						{
							PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( wParam, lParam));
							break;
						}

	}

	return CDialog::WindowProc(message, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//		CMy6046DryEndDlg	DATA DISPLAY BUTTON HANDLERS					//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::OnMainBtnQuit() 
{
	//DO CLEAN UP
	if(AfxMessageBox("    Are you absolutely sure you want to quit?", MB_YESNO, NULL) == IDYES)
		this->OnOK();

}

void CMy6046DryEndDlg::OnMainDsplyHfwf() 
{
	m_DspType = WFHIGH;

	if(m_bWaterfallHIGH){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnHFWF.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnHFWF.Invalidate(TRUE);
	}
	else{
		m_DspManager.ShowDisplay(m_DspType);
		m_ctrlBtnHFWF.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
	}
	m_bWaterfallHIGH = !m_bWaterfallHIGH;
	
	m_pConfig->bShowHFSS = m_bWaterfallHIGH;
	SaveSettings();

}

void CMy6046DryEndDlg::OnMainDsplyLfwf() 
{
	m_DspType = WFLOW;

	if(m_bWaterfallLOW){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnLFWF.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnLFWF.Invalidate(TRUE);
	}
	else{
		m_DspManager.ShowDisplay(m_DspType);
		m_ctrlBtnLFWF.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
	}

	m_bWaterfallLOW = !m_bWaterfallLOW;
	m_pConfig->bShowLFSS = m_bWaterfallLOW;
	SaveSettings();
}

void CMy6046DryEndDlg::OnMainDsplySbp()
{
	m_DspType = WFSBP;
	
	if(m_bWaterfallSBP){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnSBP.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnSBP.Invalidate(TRUE);
	}
	else{
		m_DspManager.ShowDisplay(m_DspType);
		m_ctrlBtnSBP.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
	}

	m_bWaterfallSBP = !m_bWaterfallSBP;
	m_pConfig->bShowSBP = m_bWaterfallSBP;
	SaveSettings();
}



void CMy6046DryEndDlg::OnMainDsply2dbathy() 
{
	// TODO: Add your control notification handler code here
	m_DspType = DSPBATHY;

	if(m_bBathy){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtn2DBathy.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtn2DBathy.Invalidate(TRUE);
	}
	else{
		m_ctrlBtn2DBathy.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);
	}

	m_bBathy = !m_bBathy;
	m_pConfig->bShowBathy = m_bBathy;
	SaveSettings();

}


void CMy6046DryEndDlg::OnMainDsplyAttitude() 
{
	m_DspType = DSPATT;

	if(m_bAttitude){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnAttitude.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnAttitude.Invalidate(TRUE);
	}
	else{
		m_ctrlBtnAttitude.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);
	}

	m_bAttitude = !m_bAttitude;
	m_pConfig->bShowAttitude = m_bAttitude;
	SaveSettings();
	
}


void CMy6046DryEndDlg::OnMainDsplyDepth() 
{
	m_DspType = DSPDEPTH;

	if(m_bDepth){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnDepth.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnDepth.Invalidate(TRUE);
	}
	else{
		m_ctrlBtnDepth.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);	
	}

	m_bDepth = !m_bDepth;
	m_pConfig->bShowDepth = m_bDepth;
	SaveSettings();
}

void CMy6046DryEndDlg::OnMainDsplyHeading() 
{
	m_DspType = DSPCOMPASS;

	if(m_bHeading){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnHeading.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnHeading.Invalidate(TRUE);
	}
	else{
		m_ctrlBtnHeading.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);	
	}

	m_bHeading = !m_bHeading;
	m_pConfig->bShowHeading = m_bHeading;
	SaveSettings();
	
}

//changed to ascii display
void CMy6046DryEndDlg::OnMainDsplyNavigation() 
{
	m_DspType = DSPNAV;
	if(m_bNav){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnSpeeds.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnSpeeds.Invalidate(TRUE);
	}
	else{
		m_ctrlBtnSpeeds.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);	
	}

	m_bNav = !m_bNav;
	m_pConfig->bShowNav = m_bNav;
	SaveSettings();
	
}

void CMy6046DryEndDlg::OnMainDsplyText() 
{
	m_DspType = DSPASCII;
	if(m_bTextOnly){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnTextOnly.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnTextOnly.Invalidate(TRUE);
	}
	else{
		m_ctrlBtnTextOnly.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);	
	}

	m_bTextOnly = !m_bTextOnly;
	m_pConfig->bShowASCII = m_bTextOnly;
	SaveSettings();
	
}

void CMy6046DryEndDlg::OnMainDsplyWedge() 
{
	// TODO: Add your control notification handler code here
	m_DspType = DSPIMAGERY;
	if(m_bImagery){
		m_DspManager.HideDisplay(m_DspType);
		m_ctrlBtnWedge.SetShade(SHS_HARDBUMP,8,20,4,RGB(55,55,255));
		m_ctrlBtnWedge.Invalidate(TRUE);
	}
	else{
		m_ctrlBtnWedge.SetShade(SHS_HARDBUMP,8,20,14,RGB(0,80,244));
		m_DspManager.ShowDisplay(m_DspType);	
	}

	m_bImagery = !m_bImagery;
	m_pConfig->bShowImagery = m_bImagery;
	SaveSettings();
}


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//		CMy6046DryEndDlg	QUICK VIEW DISPLAY BUTTON HANDLERS				//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
//	ONLY THE FIRST FUNCTION COMMENTED, THEY ARE ALL IDENTICAL
//

void CMy6046DryEndDlg::OnQvRefresh() 
{
	// TODO: Add your control notification handler code here
	EMESSAGETYPE temp = m_QVManager.GetDisplayedType();

	RemoteReport();
	RemoteRunList();
	RemoteModules();
	RemoteHealth();
	
	/*
	switch(temp)
	{
	case general: {RemoteReport();break;}
	case modules: {break;}
	case runlist: {break;}
	case health:  {RemoteHealth();break;}
	default: break;
	}
	*/
}


//Just Intercept and display
void CMy6046DryEndDlg::OnQvGeneral() 
{
	if(m_pLedLastLit == &m_ctrlLedGeneral){
		//RemoteReport();
		return;
	}

	m_ctrlLedGeneral.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_ON , CLed::LED_ROUND);
	if(m_pLedLastLit != NULL)
		m_pLedLastLit->SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);


	m_QVManager.DisplayData(general);

	m_pLedLastLit = &m_ctrlLedGeneral;
}

//Actually Solicit and then Display/store
void CMy6046DryEndDlg::OnQvModules() 
{
	if((m_pLedLastLit == &m_ctrlLedModules) || !m_bRemoteConnected){
		return;
	}

	m_ctrlLedModules.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_ON , CLed::LED_ROUND);
	if(m_pLedLastLit != NULL)
		m_pLedLastLit->SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);


	m_QVManager.DisplayData(modules);

	m_pLedLastLit = &m_ctrlLedModules;
	
}

void CMy6046DryEndDlg::OnQvRunlist() 
{
	if((m_pLedLastLit == &m_ctrlLedRunlist) || !m_bRemoteConnected){
		return;
	}
	
	m_ctrlLedRunlist.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_ON , CLed::LED_ROUND);
	if(m_pLedLastLit != NULL)
		m_pLedLastLit->SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);

	//Send runlist CMD
	//RemoteRunList();
	//Display data
	m_QVManager.DisplayData(runlist);

	m_pLedLastLit = &m_ctrlLedRunlist;
}


void CMy6046DryEndDlg::OnQvHealth() 
{
	if((m_pLedLastLit == &m_ctrlLedHealth) || !m_bRemoteConnected){
		return;
	}
	
	m_ctrlLedHealth.SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_ON , CLed::LED_ROUND);
	if(m_pLedLastLit != NULL)
		m_pLedLastLit->SetLed(CLed::LED_COLOR_YELLOW, CLed::LED_OFF , CLed::LED_ROUND);


	//Display data
	m_QVManager.DisplayData(health);

	m_pLedLastLit = &m_ctrlLedHealth;
	
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//		CMy6046DryEndDlg	CONTROL BAR BUTTON HANDLERS						//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::OnMainBtnToggle() 
{
	switch(m_ToggleState)
	{	
		case ALL:{this->SetWindowPos(NULL, NULL, NULL, m_rectAll.Width(),m_rectMid.Height(), SWP_NOMOVE | SWP_NOZORDER); m_ToggleState = MID; break;} 
		case MID:{this->SetWindowPos(NULL, NULL, NULL, m_rectAll.Width(),m_rectTop.Height(), SWP_NOMOVE | SWP_NOZORDER); m_ToggleState = TOP; break;}
		case TOP:{return;}
	}

	m_pConfig->MAINToggleState = m_ToggleState;
	SaveSettings();
}

void CMy6046DryEndDlg::OnMainBtnToggle2() 
{
	switch(m_ToggleState)
	{	
		case TOP:{this->SetWindowPos(NULL, NULL, NULL, m_rectAll.Width(),m_rectMid.Height(), SWP_NOMOVE | SWP_NOZORDER); m_ToggleState = MID; break;}	
		case MID:{this->SetWindowPos(NULL, NULL, NULL, m_rectAll.Width(),m_rectAll.Height(), SWP_NOMOVE | SWP_NOZORDER); m_ToggleState = ALL; break;}
		case ALL:{return;} 
	}
	
	m_pConfig->MAINToggleState = m_ToggleState;
	SaveSettings();
}

void CMy6046DryEndDlg::OnBtnRecord() 
{
	
	if(modeState == PLAYBACK)
	{
		if(m_bPlaying == TRUE)
			return;
		
		if((bXTFPlayerInitialized == FALSE) && (b7KPlayerInitialized == FALSE))
			return;
			
		if(m_bFolderPlay && m_bAllFilesPlayed)
		{
			m_ctrlMainTabs.NotifyTab(5,RESTART_FLDR_PLAY);
			m_bAllFilesPlayed = FALSE;
			return;
		}

		if(bXTFPlayerInitialized)
		{	
			m_bPlaying = true;
			m_uiFileTimerID = SetTimer(FILE_READ_EVENT, requestedPlaySpeed, NULL);
			time(&StartTime);		
			SetWindowText("Playing XTF File...");
		}
		else if(b7KPlayerInitialized)
		{
			time(&StartTime);	
			m_bPlaying = true;
			m_7kReader.Start(requestedPlaySpeed);
			SetWindowText("Playing 7K File...");
		}
		else
			return;
	}
	else
	{
		if((m_bRemoteConnected == FALSE) || (m_bLogging ==  TRUE))
			return;

		//Call directly
		if(m_6046RemoteClient.Logging(true))
		{
			RemoteReport();
			m_bLogging = TRUE;
			SetWindowText(m_str6046ON);
		}
		//Error should be handled by ACK in main dlg or elsewhere
	}
}

void CMy6046DryEndDlg::OnBtnStop() 
{
	
	if((modeState == PLAYBACK) && (m_bPlaying == TRUE))
	{
		KillPlay();	
	}
	else if(modeState == COLLECT)
	{
		if(m_bLogging == FALSE || m_bRemoteConnected == FALSE)
			return;

		if(AfxMessageBox("Really stop logging?", MB_YESNO,0) == IDYES)
		{
			//call directly
			if(m_6046RemoteClient.Logging(false))
			{
				m_bLogging = FALSE;
				SetWindowText(m_str6046OFF);
				RemoteReport();
			}
		}
		else
			return;
	}
	
	
}

void CMy6046DryEndDlg::OnBtnViewreport() 
{
	// TODO: Add your command handler code here
	
	if (m_bPopupReport == TRUE)
	{
		m_dlgPopupReport->ShowWindow (SW_HIDE) ;
		m_ctrlViewReport.SetShade (SHS_METAL,8,20,4,RGB(55,55,255));
	}
	else
	{
		m_dlgPopupReport->ShowWindow (SW_SHOW) ;
		m_dlgPopupReport->Invalidate (TRUE) ;
		m_ctrlViewReport.SetShade (SHS_METAL,8,20,14,RGB(0,80,244));
	}
	
	m_bPopupReport = !m_bPopupReport ;

	m_ctrlViewReport.Invalidate(TRUE);
	
}

void CMy6046DryEndDlg::ToggleAlarmsDisplay()
{
	OnBtnViewreport();
}

void CMy6046DryEndDlg::OnButtonMute() 
{
	MuteCurrentAlarm();	
}


void CMy6046DryEndDlg::OnSelchangeMainModeCombo() 
{
	MODE_STATE lastMode = modeState;
	modeState = (MODE_STATE)m_ctrlMode.GetCurSel();	

	//Save Settings
	m_pConfig->dSysMode = modeState;
	SaveSettings();
	
	if(lastMode == modeState)
		return;
	
	if(modeState == COLLECT){
		
		if(m_bPlaying)
			KillPlay();
		
		//m_ctrlRecTime.ShowWindow(SW_HIDE);

		//Remove thePlayback Tab
		m_ctrlMainTabs.DeleteItem(6);
		//Display the new last tab
		m_ctrlMainTabs.GoBack();
		//Change Button Label
		m_ctrlRecord.SetWindowText("Record");
		//m_ctrlRecord.SetIcon(IDI_ICON_RECORD, BS_CENTER, 0);
		
		//Update everybody of mode change
		m_ctrlMainTabs.ReplaceLastSensors();
	}
	else if(modeState == PLAYBACK)
	{	
		//m_ctrlRecTime.ShowWindow(SW_SHOW);
		//Insert new tab
		TCITEM tcItem;
		tcItem.mask = TCIF_TEXT;
		tcItem.pszText = _T("Playback");
		m_ctrlMainTabs.InsertItem(6, &tcItem);
		//Change button text
		m_ctrlRecord.SetWindowText("Play");
		//m_ctrlRecord.SetIcon(IDI_ICON_PLAY, BS_CENTER, 0);
		
		//Update mode change
		m_ctrlMainTabs.ClearAllSensors();
	}

	OnQvRefresh();
}


void CMy6046DryEndDlg::OnBtnAltquit() 
{
	OnMainBtnQuit();	
}

void CMy6046DryEndDlg::OnBtnMinimize() 
{
	ShowWindow(SW_SHOWMINIMIZED);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//FILE PLAY CONTROL FUNCTIONS BEGIN HERE
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void CMy6046DryEndDlg::BeginPlay(BOOL folder, CString name, int playSpeed)
{

	//determine file type
	CString temp = name;
	temp.MakeUpper();
		
	
	if(temp.Find("XTF") >= 0) 
	{
		//If the 7k reader is active, shutdown
		if(b7KPlayerInitialized)
		{
			m_7kReader.Shutdown();
			b7KPlayerInitialized = FALSE;
		}
		//try to Init the XTF reader
		if(m_xtfReader.InitReader(name, this->GetSafeHwnd()) == FALSE)
			AfxMessageBox("File could not be opened for reading");
		else
		{
			bXTFPlayerInitialized = TRUE;
			requestedPlaySpeed = playSpeed;
		}
	}
	else if(temp.Find("S7K") >= 0)
	{
		//If XTF Reader Initialized, shutdown
		if(bXTFPlayerInitialized)
		{
			m_xtfReader.Shutdown();
			bXTFPlayerInitialized = FALSE;
		}
		
		if(m_7kReader.FileOpen())
			m_7kReader.CloseFile();
			
		if(m_7kReader.Open7KFile(name) == FALSE)
			AfxMessageBox("Error opening 7K file");
		else
		{
			b7KPlayerInitialized = TRUE;
			requestedPlaySpeed   = playSpeed;
		}
	}
	else
	{
		AfxMessageBox("File Type Not Recognized");
	}

	//Set Folder play flag so we notify the tab manager when next file is needed
	m_bFolderPlay = folder;
}

void CMy6046DryEndDlg::KillPlay()
{
	m_bPlaying = FALSE;
	
	if(bXTFPlayerInitialized)
	{	 
		KillTimer(m_uiFileTimerID);
		Sleep(200);
		if(m_bEOFReached)
		{
			m_xtfReader.ResetFile();
		}
	}
	else if(b7KPlayerInitialized)
	{
		m_7kReader.Stop();
		m_7kReader.RewindFile();
	}
	SetWindowText(m_str6046OFF);	
}

void CMy6046DryEndDlg::ModifyPlaySpeed(int newSpeed)
{
	requestedPlaySpeed = newSpeed;
	
	if((bXTFPlayerInitialized == FALSE) && (b7KPlayerInitialized == FALSE))
		return;

	//Check for Initialization
	if((bXTFPlayerInitialized == TRUE) && m_bPlaying)
	{
		KillTimer(m_uiFileTimerID);
		m_uiFileTimerID = SetTimer(FILE_READ_EVENT, newSpeed, NULL);
	}
	else if((b7KPlayerInitialized == TRUE) && m_bPlaying)
	{	
		m_7kReader.Stop();
		m_7kReader.Start(requestedPlaySpeed);	
	}
	else
		return;
}

void CMy6046DryEndDlg::CloseAllOpenFiles()
{
	if(b7KPlayerInitialized == TRUE)
	{
		m_7kReader.CloseFile();
	}
	if(bXTFPlayerInitialized == TRUE)
	{
		m_xtfReader.CloseFile();
	}

}

void CMy6046DryEndDlg::SetTimeSync(BOOL bEnable)
{
	m_bSyncTime = bEnable;
}

void CMy6046DryEndDlg::AutoPLCSync(BOOL start, UINT seconds)
{
	if(start == TRUE)
	{
		if(m_uiPLCSyncTimerID)
			KillTimer(m_uiPLCSyncTimerID);

		m_uiPLCSyncTimerID = SetTimer(PLC_SYNC_EVENT, seconds*1000, NULL);

	}
	else
	{
		if(m_uiPLCSyncTimerID)
			KillTimer(m_uiPLCSyncTimerID);

	}

}

void CMy6046DryEndDlg::GetSyncedInfo( QV_GENERAL *info )
{

	m_QVManager.GetSyncInfo(info);

}

void CMy6046DryEndDlg::FlipOrientation( BOOL bFlip )
{
	m_DspManager.FlipDisplayedData(bFlip);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//GENERAL HELPERS
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void CMy6046DryEndDlg::AddAlarm()
{
	if(m_uiInternalAlarmCount == 0)
	{
		//Play Sound
		m_uiAlarmTimerID = SetTimer(ALARM_EVENT, 2000, NULL);
		m_Led1.SetLed(CLed::LED_COLOR_RED, CLed::LED_ON, CLed::LED_SQUARE);
		m_Led1.Ping(50);
		
	}

	//Restore window if minimized
	if(this->IsIconic())
		ShowWindow(SW_RESTORE);
	
	m_uiInternalAlarmCount++;
}

void CMy6046DryEndDlg::SubtractAlarm()
{

	if(m_uiInternalAlarmCount == 0)
	{
		m_Led1.SetLed(CLed::LED_COLOR_GREEN, CLed::LED_ON , CLed::LED_SQUARE);
		return;
	}

	m_uiInternalAlarmCount--;

	if(m_uiInternalAlarmCount == 0)
	{
		m_Led1.KillPing();
		KillTimer(m_uiAlarmTimerID);
		m_Led1.SetLed(CLed::LED_COLOR_GREEN, CLed::LED_ON, CLed::LED_SQUARE);
	}
}

void CMy6046DryEndDlg::ClearAllAlarms()
{
	if(m_uiInternalAlarmCount == 0)
	{
		m_Led1.SetLed(CLed::LED_COLOR_GREEN, CLed::LED_ON , CLed::LED_SQUARE);
		return;
	}
	else
	{
		m_uiInternalAlarmCount = 0;

		m_Led1.KillPing();
		
		if(m_uiAlarmTimerID)
			KillTimer(m_uiAlarmTimerID);
		
		m_Led1.SetLed(CLed::LED_COLOR_GREEN, CLed::LED_ON, CLed::LED_ROUND);
	}
}

void CMy6046DryEndDlg::MuteCurrentAlarm()
{
	if(m_uiAlarmTimerID)
		KillTimer(m_uiAlarmTimerID);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//CALLBACKS FROM THE WET END START HERE
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

//Receive System and Alarm messages
void CMy6046DryEndDlg::CallbackSystem(void *pvParam, unsigned char *pbyData, unsigned long ulBytes)
{	

	//TRACE("\r\nSYSTEM DATA RECEIVED : bytes = %d \r\n\r\n", ulBytes);
	if((pbyData == NULL) || (ulBytes == 0))
		return;

	//Cast our this pointer
	CMy6046DryEndDlg* myPtr = (CMy6046DryEndDlg*)pvParam;

	// Request ownership of the critical section.
	EnterCriticalSection(&myPtr->CriticalSection); 
	
	//Add sys data to history buffer
	myPtr->m_buff7kSysRecords.AddData(pbyData, ulBytes);

	//POST SYSTEM DATA READY MESSAGE  
	::PostMessage(myPtr->m_hWnd, SYS_DATA_READY, 0,0);
	
	//Release ownership of the critical section.
	LeaveCriticalSection(&myPtr->CriticalSection);

}

//Receive High frequency Waterfall Data
void CMy6046DryEndDlg::CallbackData(void *pvParam, unsigned char *pbyData, unsigned long ulBytes)
{
	
	//TRACE("CALLBACK DATA RECEIVED : bytes = %d \r\n", ulBytes);
	if((pbyData == NULL) || (ulBytes == 0))
		return;

	//Cast our this pointer
	CMy6046DryEndDlg* myPtr = (CMy6046DryEndDlg*)pvParam;
	
	__try 
	{
		// Request ownership of the critical section.
		EnterCriticalSection(&myPtr->CriticalSection); 
		  
		myPtr->m_buff7kDataRecords.AddData(pbyData, ulBytes);
		
	}
	//End Critical Section
	__finally 
    {
		//POST SENSOR DATA READY MESSAGE 
		::PostMessage(myPtr->m_hWnd, REAL_DATA_READY, 0,0);
		
		// Release ownership of the critical section.
		LeaveCriticalSection(&myPtr->CriticalSection);
	}

	
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//HANDLERS FOR CALLBACKS FROM THE WET END START HERE
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

//Deliver data to Display Manager
void CMy6046DryEndDlg::RealTimeHandler()
{
	
	
	UINT	uiMaxSamples;		//The max samples for current ping port/stbd
	UINT	sampleInterval;

	// Request ownership of the critical section.	
	EnterCriticalSection(&CriticalSection); 
		
	//Get record from front of Q
	RECORD *prec = m_buff7kDataRecords.GetNextRecord();
	if(prec == NULL)
	{
		TRACE("NULL DATA RECORD RETURNED");
		LeaveCriticalSection(&CriticalSection);
		return;
	}
	
	m_recReuseRecord.lBytes = prec->lBytes;
	memcpy(m_recReuseRecord.data, prec->data, prec->lBytes);
	
	// Release ownership of the critical section.
	LeaveCriticalSection(&CriticalSection);

	//Decode the header / validate
	if(m_7kProtocol.DecodeRecord(m_recReuseRecord.data, m_recReuseRecord.lBytes, false, m_p7kHeader, pDynamicBytes, dynSize) == false)
	{
		TRACE("FAILED TO DECODE RECORD!\r\n");
		return;
	}
	if(m_bSyncTime)
	{	
#pragma CompileMessage_m( "TODO: TEST SYS TIME SYNC USING TWO MACHINES" )											
		GetSystemTime(&m_SYSTIME);
		m_SYSTIME.wHour	 = m_p7kHeader->m_sTime7k.m_ucHours;
		m_SYSTIME.wMinute = m_p7kHeader->m_sTime7k.m_ucMinutes;
		m_SYSTIME.wSecond = (UINT)floor(m_p7kHeader->m_sTime7k.m_fSeconds);
		SetSystemTime(&m_SYSTIME);			
	}	

	//TRACE("BEGIN REAL TIME DATA HANDLER RECORD ID: %d\r\n", m_p7kHeader->m_ulRecordType);

	switch(m_p7kHeader->m_ulRecordType)
	{
		ZeroMemory(Data16Bit, m_ulMaxBuffer);
		ZeroMemory(Data8Bit,  m_ulMaxBuffer);

		////////////////////////////////////////////////////////////////////////////////////
		// Handle Both Side Scan types almost the same
		case 3000: 
		{  
			//TRACE("PARSING SS DATA type 3000\r\n"); 
			//Sidescan Type Header
			psRTH				= (PSIDESCANRECORDTYPEHEADER)pDynamicBytes;
			psPortChanInfo		= (PCHANNELINFO)(((BYTE*)psRTH) + sizeof(SIDESCANRECORDTYPEHEADER));
			
			//Channel Port
			psPortChanInfo      = (PCHANNELINFO)psPortChanInfo;
			pbyPortImagery		= ((BYTE*)psPortChanInfo) + sizeof(CHANNELINFO);
			
			//Channel Starboard
			psStbdChanInfo		= (PCHANNELINFO)(pbyPortImagery + (psPortChanInfo->m_ucBytesPerSample*psPortChanInfo->m_ulNumberOfSamples));
			pbyStbdImagery		= ((BYTE*)psStbdChanInfo) + sizeof(CHANNELINFO);
		
			//Get ptrs to EdgeTEch Headers
			psETSSHeaderPort	= (SidescanHeaderType*)(pbyStbdImagery  + (psPortChanInfo->m_ucBytesPerSample*psPortChanInfo->m_ulNumberOfSamples));
			psETSSHeaderStbd	= (SidescanHeaderType*)(((BYTE*)psETSSHeaderPort) + sizeof(SidescanHeaderType));

			//Scale The Channels within the record
			if(m_p7kHeader->m_ulDeviceId == 11001)
			{	
				m_ChanScaleLFSSPort.ScaleChannelData(psETSSHeaderPort->weightingFactor, (short*)pbyPortImagery, psPortChanInfo->m_ulNumberOfSamples);
				m_ChanScaleLFSSStbd.ScaleChannelData(psETSSHeaderStbd->weightingFactor, (short*)pbyStbdImagery, psStbdChanInfo->m_ulNumberOfSamples);
			}
			else if(m_p7kHeader->m_ulDeviceId == 11002)
			{
				m_ChanScaleHFSSPort.ScaleChannelData(psETSSHeaderPort->weightingFactor, (short*)pbyPortImagery, psPortChanInfo->m_ulNumberOfSamples);
				m_ChanScaleHFSSStbd.ScaleChannelData(psETSSHeaderStbd->weightingFactor, (short*)pbyStbdImagery, psStbdChanInfo->m_ulNumberOfSamples);
			}
			//DebugPingData((short*)pbyPortImagery,(short*)pbyStbdImagery);
			
			//Assemble Channels into one buffer
			UINT portSamples = psPortChanInfo->m_ulNumberOfSamples;
			UINT stbdSamples = psStbdChanInfo->m_ulNumberOfSamples;
			//Calc total samples
			int  sampleTotal = portSamples + stbdSamples; 
			
			//Calc the max channel samples for this ping
			if(portSamples > stbdSamples)
				uiMaxSamples = portSamples;
			else
				uiMaxSamples = stbdSamples;
		

			//recast
			short *portData = (short*)pbyPortImagery;
			//Get Ptr to end of data
			short *portIndex = portData + psPortChanInfo->m_ulNumberOfSamples;
			//reverse port channel data
			for(int i = 0; i < psPortChanInfo->m_ulNumberOfSamples; i++)
			{
				     Data16Bit[i] = *portIndex;
				     portIndex--;
			}

			//add stbd channel data in same order
			memcpy(Data16Bit+psPortChanInfo->m_ulNumberOfSamples, pbyStbdImagery, psStbdChanInfo->m_ulNumberOfSamples*psStbdChanInfo->m_ucBytesPerSample);
			
			//Now scale to 8bit
			for(int j=0; j<sampleTotal; j++)
			{
				Data8Bit[j] = (BYTE)((0x0FF0 & Data16Bit[j]) >> 4);
			}
			
			
			/////////////////////////////////////////////////////////////
			//SEND OUT THE DATA
			if(m_p7kHeader->m_ulDeviceId == 11001)
			{
				//Send To Display Manager - LFSS	
				m_DspManager.AddWaterfallData(WFLOW, Data8Bit, sampleTotal);
				m_LFSSPingsProcessed++;
				
				if(m_LFSSPingsProcessed == 2)
				{
					if(psETSSHeaderPort->sampleInterval >= psETSSHeaderStbd->sampleInterval)
						sampleInterval = psETSSHeaderPort->sampleInterval;
					else
						sampleInterval = psETSSHeaderStbd->sampleInterval;

					long slant = 750 * (sampleInterval*pow(10,-9)) * uiMaxSamples;
					//Init a setting struct to pass to Display Manager
					SETTINGS set;
					set.range = (int)floor(slant-.5);
					//set.power = 
					
					m_DspManager.SetWaterfallParams(WFLOW, &set);
					//m_ctrlMainTabs.UpdateRange(EDGE_LFSS, set.range);  /need to get these vals from PLC
					//m_ctrlMainTabs.UpdatePower(EDGE_LFSS, set.power);

					m_LFSSPingsProcessed = 0;
				}

			}
			else if(m_p7kHeader->m_ulDeviceId == 11002)
			{
				//Send To Display Manager - HFSS
				m_DspManager.AddWaterfallData(WFHIGH, Data8Bit, sampleTotal);
				
				m_HFSSPingsProcessed++;
				
				if(m_HFSSPingsProcessed == 2)
				{
					if(psETSSHeaderPort->sampleInterval >= psETSSHeaderStbd->sampleInterval)
						sampleInterval = psETSSHeaderPort->sampleInterval;
					else
						sampleInterval = psETSSHeaderStbd->sampleInterval;

					long slant = 750 * (sampleInterval*pow(10,-9)) * uiMaxSamples;
					//Init a setting struct to pass to Display Manager
					SETTINGS set;
					set.range = (int)floor(slant-.5);
					//set.power = 
					
					m_DspManager.SetWaterfallParams(WFHIGH, &set);
					//m_ctrlMainTabs.UpdateRange(EDGE_HFSS, set.range);//need to get these vals from PLC
					//m_ctrlMainTabs.UpdatePower(EDGE_HFSS, set.power);

					m_HFSSPingsProcessed = 0;
				}

			}
			else;

			break;
	
		}
		////////////////////////////////////////////////////////////////////////////////////
		//Sub bottom profiler data
		case 3001: 
		{
			psRTH				= (PSUBBOTTOMRECORDTYPEHEADER)pDynamicBytes;
			psSBPChanInfo		= (PCHANNELINFO)(((BYTE*)psRTH) + sizeof(SUBBOTTOMRECORDTYPEHEADER));
			pbySBPImagery		= (BYTE*)(((BYTE*)psSBPChanInfo) + sizeof(CHANNELINFO));
			psETSBPHeader	    = (SegyDataType*)(pbySBPImagery + (psSBPChanInfo->m_ucBytesPerSample*psSBPChanInfo->m_ulNumberOfSamples));

			m_ChanScaleSBP.ScaleChannelData(psETSBPHeader->weightingFactor, (short*)pbySBPImagery,psSBPChanInfo->m_ulNumberOfSamples*2);

			
			short *pImagery	   = (short*)pbySBPImagery;
			short I,Q;
			short fin;
			for(int start=0; start < psSBPChanInfo->m_ulNumberOfSamples*2; start += 2)
			{
				I = pImagery[start];	
				Q = pImagery[start+1];
				fin = (short)sqrt((I*I)+(Q*Q));
				
				Data16Bit[start/2] = fin;
			}
			
			for(int j=0; j < psSBPChanInfo->m_ulNumberOfSamples; j++)
			{
				Data8Bit[j] = (BYTE)((0x0FF0 & Data16Bit[j]) >> 4);
			}

			//Send To Display Manager - HFSS
			m_DspManager.AddWaterfallData(WFSBP, Data8Bit, psSBPChanInfo->m_ulNumberOfSamples);

			break;
		}
		/////////////////////////////////////////////////////////////////////////////////////
		//Blue Fin NAV/ENV Data 
		case 3100: 
		{
			psBlueFinHeader	= (NBlueFin7kMessages::PBLUEFINRECORDTYPEHEADER)pDynamicBytes;
			psBlueFinNet	= (NBlueFin7kMessages::PBLUEFINNETWORKHEADER)((BYTE*)psBlueFinHeader + sizeof(NBlueFin7kMessages::BLUEFINRECORDTYPEHEADER));

			switch(psBlueFinHeader->m_ulDataFormat)
			{
			//////////////////////////////////////////////////////////
			//BLUE FIN NAV FRAME
			case 0:{  
					psBlueFinNAV = (NBlueFin7kMessages::PBLUEFINNAVIGATIONMESSAGE)((BYTE*)psBlueFinNet + sizeof(NBlueFin7kMessages::BLUEFINNETWORKHEADER));	
					//psBlueFinNAV = SimulateBlueFin();
					m_DspManager.AddGroupData(psBlueFinHeader, psBlueFinNet, psBlueFinNAV);	
					break;
				   }
			//////////////////////////////////////////////////////////
			//BlUE FIN ENV FRAME
			case 1:{  
					psBlueFinENV = (NBlueFin7kMessages::PBLUEFINENVIRONMENTMESSAGE)(pDynamicBytes + sizeof(NBlueFin7kMessages::BLUEFINRECORDTYPEHEADER));					
					TRACE("Blue Fin ENV Frame Rec'd\r\n");
					//m_DspManager.AddGroupData(psBlueFinHeader, psBlueFinNAV);	
					break;
				   }
			}
			break;
		}
		//BEGIN THE 7K SYSTEM HANDELRS
		case 7006:
		{
			R7006 *temp = (R7006*)pDynamicBytes;
			m_DspManager.AddBathyData(pDynamicBytes);
			break;
		}
		case 7000:
		{
			m_DspManager.Add7000Data(pDynamicBytes);
			break;
		}
		case 7001:
		{
			m_xmlParsor.Set7001Info((char*)pDynamicBytes /*+ sizeof(RECORD_FRAME)*/ + sizeof(R7001) + sizeof(R7001MODULEINFO));
			//Now send a mesage to the 7k UI tab to parse the settings values 
			
			float spacing;
			BOOL  uniform;
			m_xmlParsor.GetRxBeamSpacing(&spacing, &uniform);
			m_DspManager.SetBeamSpacing(spacing*180/PI);
			m_ctrlMainTabs.NotifyTab(5, XML_DATA_READY);

			break;
		}
		case 7004:
		{
			R7004* pRec  = (R7004*)pDynamicBytes;
					
			float* pData = (float*)(pDynamicBytes + sizeof(R7004) + sizeof(float)*pRec->beams);
			float  temp;
				
			m_ulLastBeams = pRec->beams;

			//First Modify the data so it is in correct polar coordinates for display
			for(int i =0; i<pRec->beams;i++)
			{
				temp = pData[i];		
				pData[i] = 3.0f * PI * 0.5f + (-1.0f * temp);
			}

			//Now relay the info
			m_DspManager.RelayBeamGeometry(pDynamicBytes);
			break;
		}
		
		case 7011:
		{
			m_DspManager.AddImageryData(pDynamicBytes);
			break;
		}
		case 7500:
		{
			R7500* dataHeader = (R7500*)(pDynamicBytes);
			
			BYTE *data = (BYTE*)(dataHeader + sizeof(R7500));

			switch(dataHeader->rc_id)
			{

			case 1003:
			  m_ctrlMainTabs.UpdateRange(SEABAT_7K, *((float*)data));
			  break;
			case 1004:
			  m_ctrlMainTabs.UpdateMaxRate(SEABAT_7K,*((float*)data));
			  break;
			case 1005:
			  m_ctrlMainTabs.UpdatePower(SEABAT_7K, *((float*)data));
			  break;
			case 1006:
			  m_ctrlMainTabs.UpdatePulse(SEABAT_7K,*((float*)data));
			  break;
			case 1008:
			  m_ctrlMainTabs.UpdateGain(SEABAT_7K,*((float*)data));
			  break;	
			default:
			  break;
		  
			}

			break;
		}
		case 7503: //Sonar settings
		{
			R7503 *data7503 = (R7503*)(pDynamicBytes);
			m_ctrlMainTabs.UpdateRange(SEABAT_7K,data7503->range);
			m_ctrlMainTabs.UpdatePower(SEABAT_7K,data7503->power);
			m_ctrlMainTabs.UpdatePulse(SEABAT_7K,data7503->pulse_width);
			m_ctrlMainTabs.UpdateMaxRate(SEABAT_7K,data7503->max_ping_rate);
			m_ctrlMainTabs.UpdateGain(SEABAT_7K,data7503->gain);

			BOOL state = FALSE;
			if(data7503->control_flags == 768)
				state = TRUE;
			m_ctrlMainTabs.UpdateFilters(data7503->bottom_detection_info1,data7503->bottom_detection_info2,
										 data7503->bottom_detection_info3,data7503->bottom_detection_info4,
										 state);

			m_ctrlMainTabs.UpdatePingState(SEABAT_7K,(BOOL)data7503->ping_on_off_state);

			break;
		}
		default: TRACE("GOT A NEW TYPE OF RECORD : %d!!!!\r\n",m_p7kHeader->m_ulRecordType);break;
	}
}

NBlueFin7kMessages::PBLUEFINNAVIGATIONMESSAGE CMy6046DryEndDlg::SimulateBlueFin()
{
	m_BFSimMsg.m_dLatitude		=	.74;       
    m_BFSimMsg.m_dLongitude		=   -1.3;	  // f64          Radians
    
	m_BFSimMsg.m_fSpeed			=	25;       // f32          Meters / Second
    m_BFSimMsg.m_fNorthingRate	=	20;        // f32          Meters / Second
    m_BFSimMsg.m_fEastingRate	=	15;        // f32          Meters / Second
    m_BFSimMsg.m_fDepthRate		=	5;        // f32          Meters / Second
    m_BFSimMsg.m_fAltitudeRate	=	30;        // f32          Meters / Second
	
	m_BFSimMsg.m_dDepth			=	30;       // f64          Meters
    m_BFSimMsg.m_dAltitude		=	400;      // f64          Meters
    
//	m_BFSimMsg.m_fRoll			=	5*PI/180;        // f32          Radians
//  m_BFSimMsg.m_fPitch			=   15*PI/180;        // f32          Radians
//  m_BFSimMsg.m_fYaw			=	120*PI/180;        // f32          Radians
    
    m_BFSimMsg.m_fRollRate		=   0;        // f32          Radians / Second
    m_BFSimMsg.m_fPitchRate		=	0;        // f32          Radians / Second
    m_BFSimMsg.m_fYawRate		=	0;        // f32          Radians / Second
    
	m_BFSimMsg.m_dPositionTime	=	0;        // f64          Seconds
    m_BFSimMsg.m_dAtitudeTime	=   0;        // f64          Seconds

	return &m_BFSimMsg;
}

//Deliver data to Quick View Manager
void CMy6046DryEndDlg::SysDataHandler()
{		
	EnterCriticalSection(&CriticalSection);
	
	//Get header from front of Q
	RECORD *prec = m_buff7kSysRecords.GetNextRecord();
	if(prec == NULL)
	{
		TRACE("Invalid Record returned in Sys Handler\r\n");
		LeaveCriticalSection(&CriticalSection);
		return;
	}
	m_recReuseRecord.lBytes = prec->lBytes;
	memcpy(m_recReuseRecord.data, prec->data, prec->lBytes);	
	
	// Release ownership of the critical section.
	LeaveCriticalSection(&CriticalSection);

	//Peek at the header
	RECORDHEADER7K *psHeader = reinterpret_cast< RECORDHEADER7K *>( m_recReuseRecord.data );

	switch(psHeader->m_ulRecordType)
	{

	case 11000UL: 
		{
				TRACE("ACK/NACK REC'D\r\n");
				C7kAcknowlege::ESTATUS	ackStatus;
				ULONG					cmdID;
				int						sensorID;

				if(!m_7kAckNack.Decode(m_recReuseRecord.data, m_recReuseRecord.lBytes, false, ackStatus, cmdID, sensorID))
					break;

				if(/*cmdID == C6046RemoteClient::messageTypeAckNak && */ackStatus == C7kAcknowlege::statusRejected)
				{
					
					m_bRemoteConnected = FALSE;
					m_ctrlMainTabs.NotifyTab(0, TCP_DISCONNECT); 
					m_ctrlMainTabs.NotifyTab(1, TCP_DISCONNECT); 
					Sleep(200);
					if(AfxMessageBox("PLC Connection Lost!  Click 'OK' To Reconnect....") == IDOK)
						m_ctrlMainTabs.NotifyTab(0, TCP_RECONNECT); 
				}
				else
					TRACE("NEW TYPE OF ACK/NACK REC'D\r\n");

				break;
		}
	case 11002UL:
	
		{
				//setup decoding vars
				C7kStatus::EMESSAGETYPE		e7kMsgType;
				C7kStatus::EMODE			e7kStatus;
				int							iMsgID;

				//decode record 
				m_7kStatus.Decode(m_recReuseRecord.data, m_recReuseRecord.lBytes, false, e7kMsgType, e7kStatus,iMsgID);
				m_7kStatus.DecodeRecord(m_recReuseRecord.data, m_recReuseRecord.lBytes, false, m_p7kHeader, pDynamicBytes, dynSize);
		
		
				//
				//TRACE("HANDLING SYS DATA...MSG Type: %d  ID: %d\r\n", e7kMsgType, iMsgID);

				//handle the record
				if(e7kMsgType == C7kStatus::messageTypeStatus)
				{
			
					switch(iMsgID)
					{
						case C7kStatus::messageIdVersion:	 {	m_QVMsgType = general;
																m_QVManager.AddData(m_QVMsgType, m_7kStatus.Message());
																break;}
		
						case C7kStatus::messageIdModules:	 { m_QVMsgType = modules;
															   m_QVManager.AddData(m_QVMsgType, m_7kStatus.Message());
															   break;}
		
						case C7kStatus::messageIdRunList:	 { m_QVMsgType = runlist;
															   m_QVManager.AddData(m_QVMsgType, m_7kStatus.Message());
															   break;}
		
						case C7kStatus::messageIdFileDetails:{ m_QVMsgType = report;
															   m_QVManager.AddData(m_QVMsgType, m_7kStatus.Message());
															   break;}
						case C7kStatus::messageIdSensorReply:{ 
															   ULONG subsystemID = m_p7kHeader->m_ulDeviceId;
																														
															   switch(subsystemID)
															   {
															   case 11000: {//TRACE("ADDING SBP PULSE FILES\r\n");
																		m_QVManager.AddPulseFiles(SBPSS, m_7kStatus.Message());
																		break;
																	   }
															   case 11001:{//TRACE("ADDING LFSS PULSE FILES\r\n");
																		m_QVManager.AddPulseFiles(LFSS, m_7kStatus.Message());
																		break;
																	   }
															   case 11002:{//TRACE("ADDING HFSS PULSE FILES\r\n");
																		m_QVManager.AddPulseFiles(HFSS, m_7kStatus.Message());
																		break;
																	   }
															   }
													   
															   //TRACE("****GOT SENSOR REPLY DEVICE ID: %d\r\n", subsystemID);
													   
															   break;
																
															 }

						case C7kStatus::messageIdLoggingSetup:{
																m_QVMsgType = logging;
																m_QVManager.AddData(m_QVMsgType, m_7kStatus.Message());
																break;
															   }
						case C7kStatus::messageIdHealth:	{
																m_QVMsgType = health;
																m_QVManager.AddData(m_QVMsgType, m_7kStatus.Message());
																break;
															}
						case C7kStatus::messageIdShutdown:	{
																AfxMessageBox("The PLC has shutdown, you will be disconnected.");
																m_ctrlMainTabs.NotifyTab(0, TCP_DISCONNECT); 
																m_ctrlMainTabs.NotifyTab(1, TCP_DISCONNECT); 
																break;
															}
						default:							{	TRACE("UNKNOWN (ACK/NACK?) RX'd");break;}
			
					}
				}
					else if(e7kMsgType == C7kStatus::messageTypeAlarm)
					{
						//TRACE("Handling Alarm MEssage...\r\n");
						//Add the alarm to the popup report
						m_dlgPopupReport->AddNewMessage(m_7kStatus.Message(), ALARM, e7kStatus, iMsgID, m_p7kHeader->m_sTime7k); 

						//Increment alarm counter (Begin flash/beep) as long as its not an ALL CLEAR msg
						if((m_7kStatus.Message() == "")&&(iMsgID == 0))
							//this is an ALL CLEAR signal, so don;t AddAlarm()
							return;

						if(e7kStatus == C7kStatus::modeAlarmClear)
							return; //This is an alarm clear which will be handled by the popup report dlg
			
						//TRACE("RECEIVED ALARM: %s\r\n", m_7kStatus.Message());
					}
				}
		
		}

}

void CMy6046DryEndDlg::EnableEdgetechScaling(UINT type, BOOL bEnable)
{
	bool temp = false;
	if(bEnable == TRUE)
		temp = true;

	switch(type)
	{
	case HFSS: { 	m_ChanScaleHFSSPort.EnableScaling(temp);m_ChanScaleHFSSStbd.EnableScaling(temp);   break;}
	case LFSS: { 	m_ChanScaleLFSSPort.EnableScaling(temp);m_ChanScaleLFSSStbd.EnableScaling(temp);   break;}
	case SBPSS:{ 	m_ChanScaleSBP.EnableScaling(temp);break;}
	}

}

void CMy6046DryEndDlg::ResetScaling(UINT type)
{
	switch(type)
	{
	case HFSS: { 	m_ChanScaleHFSSPort.Reset();m_ChanScaleHFSSStbd.Reset();   break;}
	case LFSS: { 	m_ChanScaleLFSSPort.Reset();m_ChanScaleLFSSStbd.Reset();   break;}
	case SBPSS:{ 	m_ChanScaleSBP.Reset();    break;}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/*****************************************************************************/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//					REMOTE CLIENT WRAPPER FXNS START HERE
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/*****************************************************************************/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

BOOL CMy6046DryEndDlg::RemoteConnect(char *pszremoteAddress, unsigned int port)
{
	if(m_bRemoteConnected == TRUE)
	{	AfxMessageBox("You're Already Connected.");
		return FALSE;
	}

	//if(port == 0)
	//	return FALSE;

	if(m_6046RemoteClient.Connect(&CMy6046DryEndDlg::CallbackSystem, this, 
							      &CMy6046DryEndDlg::CallbackData, this,
							      pszremoteAddress , port))
	{
		//OK we connected....
		m_bRemoteConnected = TRUE;
		
		m_ctrlMainTabs.ReplaceLastSensors();


		if(m_pConfig->bQueryOnConnect)
			RemoteReportAlarms();
		
		
		//Ask for sensor (id's), version info etc...
		if(m_pConfig->bAutoSyncStartup || (m_pConfig->uiSyncIntervalTime > 0) )
		{
			
			RemoteRunList();
			RemoteModules();
			RemoteVersion();
			RemoteReport();
			RemoteHealth();
		}

		RemoteAliveMonitor(TRUE);
		
		if(m_pConfig->bAutoHealth)
			RemoteAutoHealthCheck(m_pConfig->bAutoHealth, m_pConfig->ulHealthInterval);	
	
//#pragma CompileMessage_m( "REMOVE THIS SIMULATOR CALL!!!" )

		//SimulateXMLMsg();
		//m_ctrlMainTabs.Init7kControlTab();

		m_ctrlMode.EnableWindow(FALSE);

		return TRUE;
	}
	else
		return FALSE;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CMy6046DryEndDlg::RemoteDisconnect()
{
	//KillTimer(QV_DISPLAY_UPDATE);
	if(m_bRemoteConnected == FALSE)
		return FALSE;

	if(!m_6046RemoteClient.Disconnect())
	{
		AfxMessageBox("Failed to Disconnect!");
		return FALSE;
	}
	
	m_ctrlMode.EnableWindow(TRUE);

	m_bRemoteConnected = FALSE;
	
	m_ctrlMainTabs.ClearAllSensors();
	
	m_QVManager.ClearLists();
	OnQvGeneral();
	m_QVManager.DisplayNoSync();
	m_QVManager.bSensorIdSet = FALSE;

	m_ctrlMainTabs.NotifyTab(1, TCP_DISCONNECT); 

	SetWindowText(m_str6046OFF);
	
	return TRUE;

}

BOOL CMy6046DryEndDlg::RemoteSubscribe(UINT sensorIndex, ULONG recordType)
{
	if(m_bRemoteConnected == FALSE)
		return FALSE;
		
	if(!m_6046RemoteClient.Subscribe(sensorIndex, recordType))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
		return FALSE;
	}
	return TRUE;
}

BOOL CMy6046DryEndDlg::RemoteUnsubscribe(UINT sensorIndex, ULONG recordType)
{
	if(m_bRemoteConnected == FALSE)
		return FALSE;

	if(!m_6046RemoteClient.Unsubscribe(sensorIndex, recordType))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
		return FALSE;
	}
	return TRUE;
}

void CMy6046DryEndDlg::RemotePingEnable(UINT sensorIndex, BOOL bEnable)
{
	if(m_bRemoteConnected == FALSE)
		return;

	//convert BOOL to bool, lame but oh well
	bool temp = true;
	if(bEnable == FALSE)
		temp = false;

	if(!m_6046RemoteClient.PingEnable(sensorIndex, temp))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSetRange(UINT sensorIndex,	float value)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.SetRange(sensorIndex, value))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSetPower(UINT sensorIndex, float value)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.TxPower(sensorIndex, value))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSetPulse(UINT sensorIndex, CString file)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.SetPulse(sensorIndex, file))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}


void CMy6046DryEndDlg::RemoteSetPulseWidth(UINT sensorIndex, float pulseWidth)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.PulseWidth(sensorIndex, pulseWidth))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSetGain(UINT sensorIndex, int value)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.RxGain(sensorIndex, value))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSetMaxRate(UINT sensorIndex, float value )
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.MaxPingRate(sensorIndex, value))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

void CMy6046DryEndDlg::RemoteSetDuration(UINT sensorIndex, float value)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.SetDuration(sensorIndex, value))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}

}	

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteGetPulseFiles(int riSensorIndex)
{
	if(m_bRemoteConnected == FALSE)
		return;

	TRACE("GET PULSE FILES %d\r\n",riSensorIndex);
	
	if(!m_6046RemoteClient.GetPulseFiles(riSensorIndex))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}

}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteLogging(bool rEnable)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Logging(rEnable))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSwitchFileName(char *pszFileName)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.SwitchFileName(pszFileName))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

BOOL CMy6046DryEndDlg::RemoteSetPath(char *pszPath)
{
	if(m_bRemoteConnected == FALSE)
		return FALSE;

	if(!m_6046RemoteClient.SetPath(pszPath))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteAlarm(int alarmID, C6046RemoteClient::EALARMACTION reAlarmAction )
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Alarm(alarmID, reAlarmAction))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteReportAlarms()
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.ReportAlarms())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}


}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteLoggingSetup()
{
	if(m_bRemoteConnected == FALSE)
		return;


	if(!m_6046RemoteClient.LoggingSetup())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteLoggingSetup( ULONG fileMaxSize, ULONG maxOverlapRecords)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.LoggingSetup(fileMaxSize, maxOverlapRecords))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteVersion()
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Version())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteLoad()
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Load())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteSave()
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Save())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteStatus(int riSensorIndex)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Status(riSensorIndex))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteVerbose(bool rbEnable)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Verbose(rbEnable))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteReset(int riSensorIndex)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Reset(riSensorIndex))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteShutdown(int riMode)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Shutdown(riMode))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteModules()
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Modules())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteRunList()
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.RunList())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

BOOL CMy6046DryEndDlg::RemoteAdd(int		riModuleNumber,
                                 int		riSubsystemId,
                                 int		riPortNumber,
                                 LPCTSTR    pszName  )
{
	if(m_bRemoteConnected == FALSE)
		return FALSE;

	bool send = m_6046RemoteClient.Add(riModuleNumber, riSubsystemId, riPortNumber, pszName);  
	if(!send)
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
	return send;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CMy6046DryEndDlg::RemoteRemove(int riSensorIndex)
{
	if(m_bRemoteConnected == FALSE)
		return FALSE;

	bool value = m_6046RemoteClient.Remove(riSensorIndex);	
	if(!value)
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}

	return value;
	
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteReport()
{
	if(m_bRemoteConnected == FALSE)
		return;
	//TRACE("REPORT REQUEST");
	if(!m_6046RemoteClient.Report())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemotePort(int riSensorIndex, int riPort)
{
	if(m_bRemoteConnected == FALSE)
		return;

	if(!m_6046RemoteClient.Port(riSensorIndex, riPort))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteAutoHealthCheck(bool enable, ULONG secs)
{
	if(m_bRemoteConnected == FALSE)
		return;

	TRACE("Enabling Auto Health Check...state = %d, milli = %d", (int)enable, secs*1000); 

	if(!m_6046RemoteClient.AutoHealthCheck(enable, secs*1000))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
	}
}

///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::RemoteHealth()
{
	if(m_bRemoteConnected == FALSE)
		return;

	#pragma CompileMessage_m( "TEST THIS RECONNECTION IDEA, THEN DUPLICATE FOR ALL REMOTE CMDS" )
	if(!m_6046RemoteClient.Health())
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
		if(m_6046RemoteClient.GetLastError() == C6046RemoteClient::errorCodeNotConnected)
		{
			AfxMessageBox("PLC Connection Lost!  Trying Reconnect....");
			m_bRemoteConnected = FALSE;
			m_ctrlMainTabs.NotifyTab(0, TCP_DISCONNECT); 
			m_ctrlMainTabs.NotifyTab(1, TCP_DISCONNECT); 
			Sleep(150);
			m_ctrlMainTabs.NotifyTab(0, TCP_RECONNECT); 
		}

	}

}

void CMy6046DryEndDlg::RemoteAliveMonitor( bool enable )
{
	if(m_bRemoteConnected == FALSE)
		return;

	
	if(!m_6046RemoteClient.AliveMonitor(enable))
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
		if(m_6046RemoteClient.GetLastError() == C6046RemoteClient::errorCodeNotConnected)
		{
			AfxMessageBox("PLC Connection Lost!  Trying Reconnect....");
			m_bRemoteConnected = FALSE;
			m_ctrlMainTabs.NotifyTab(0, TCP_DISCONNECT); 
			Sleep(150);
			m_ctrlMainTabs.NotifyTab(0, TCP_RECONNECT); 
		}

	}
	
}

void CMy6046DryEndDlg::RemoteGetConfigInfo(int sensorIndex)
{

	if(m_6046RemoteClient.QueryCapabilities(sensorIndex))
	{
		m_6046RemoteClient.QueryParameters(sensorIndex);
		m_6046RemoteClient.QueryRemoteSettings(sensorIndex);
	}
	else
	{
		TRACE("FAILED TO SEND MESSAGE THOURGH REMOTECLIENT");
		if(m_6046RemoteClient.GetLastError() == C6046RemoteClient::errorCodeNotConnected)
		{
			//AfxMessageBox("PLC Connection Lost!  Trying Reconnect....");
			//m_bRemoteConnected = FALSE;
			//m_ctrlMainTabs.NotifyTab(0, TCP_DISCONNECT); 
			//Sleep(150);
			//m_ctrlMainTabs.NotifyTab(0, TCP_RECONNECT); 
		}
	}
}

void CMy6046DryEndDlg::RemoteGetCurrentSettings( int sensorIndex )
{
	if(m_bRemoteConnected == FALSE)
		return;

	m_6046RemoteClient.QueryRemoteSettings(sensorIndex);
}

void  CMy6046DryEndDlg::RemoteGetParameters(int sensorIndex )
{
	if(m_bRemoteConnected == FALSE)
		return;

	m_6046RemoteClient.QueryParameters(sensorIndex);
}

void CMy6046DryEndDlg::RemoteRangeDepthFilters(int sensorIndex, float minRange,float maxRange,
																  float minDepth,float maxDepth )
{
	if(m_bRemoteConnected == FALSE)
		return;
	
	
	m_6046RemoteClient.RangeDepthFilters(sensorIndex,minRange,maxRange,minDepth,maxDepth);
	
}

void CMy6046DryEndDlg::RemoteBottomDetectFlag(int	sensorIndex,ULONG flags )
{
	if(m_bRemoteConnected == FALSE)
		return;

	m_6046RemoteClient.BottomDetectFlags(sensorIndex,flags);

}


///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//BEGIN OF OBSCURE HELPER FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void CMy6046DryEndDlg::ForceClose( DISPLAY_TYPE type )
{
	switch(type)
	{
	case WFHIGH:	{OnMainDsplyHfwf();			break;}
	case WFLOW:		{OnMainDsplyLfwf();			break;}
	case WFSBP:		{OnMainDsplySbp();			break;}
	case DSPATT:	{OnMainDsplyAttitude();		break;}
	case DSPDEPTH:	{OnMainDsplyDepth();		break;}
	case DSPCOMPASS:{OnMainDsplyHeading();		break;}
	case DSPNAV:	{OnMainDsplyNavigation();	break;}
	case DSPASCII:	{OnMainDsplyText();			break;}
	case DSPBATHY:	{OnMainDsply2dbathy();		break;}
	case DSPIMAGERY:{OnMainDsplyWedge();		break;}
	}
}


void CMy6046DryEndDlg::DrawLogo(CDC *pDC, int x, int y, COLORREF crColour)
{

	COLORREF crOldBack = pDC->SetBkColor(RGB(255,255,255));
	COLORREF crOldText = pDC->SetTextColor(RGB(0,0,0));
		
	// Select the image into the appropriate dc
	CBitmap* pOldBitmapImage = (CBitmap*)dcImage.SelectObject(this);
	// Select the mask bitmap into the appropriate dc
	CBitmap* pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans);

	// Build mask based on transparent colour
	dcImage.SetBkColor(crColour);
	dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY);

	// Do the work - True Mask method - cool if not actual display
	pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);
	pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND);
	pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);

	// Restore settings
	dcImage.SelectObject(pOldBitmapImage);
	dcTrans.SelectObject(pOldBitmapTrans);
	pDC->SetBkColor(crOldBack);
	pDC->SetTextColor(crOldText);
}



void CMy6046DryEndDlg::OnClose() 
{
	OnMainBtnQuit();
	//CDialog::OnClose();
}

void CMy6046DryEndDlg::OnCaptureChanged(CWnd *pWnd) 
{
	TRACE("***  capture changed \r\n");

	CDialog::OnCaptureChanged(pWnd);
}

void CMy6046DryEndDlg::OnButtonShowall() 
{
	m_DspManager.BringToTop();	
}
