// ArcViewDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ArcView.h"
#include "ArcViewDlg.h"
#include "LocalDlg.h"
#include "SrvrDlg.h"
#include "RxDlg.h"
#include "TxDlg.h"
//
#include "Globals.h"

#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()

/////////////////////////////////////////////////////////////////////////////
// CArcViewDlg dialog

CArcViewDlg::CArcViewDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CArcViewDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CArcViewDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CArcViewDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CArcViewDlg)
	DDX_Control(pDX, IDC_SRVR, m_SRVR);
	DDX_Control(pDX, IDC_PCI20, m_PCI20);
	DDX_Control(pDX, IDC_USB22, m_USB22);
	DDX_Control(pDX, IDC_NODEID, m_NodeID);
	DDX_Control(pDX, IDC_STATUS, m_Status);
	DDX_Control(pDX, IDC_TRANSMIT, m_Transmit);
	DDX_Control(pDX, IDC_SETTINGS, m_Settings);
	DDX_Control(pDX, IDC_REGISTERS, m_Registers);
	DDX_Control(pDX, IDC_RECEIVE, m_Receive);
	DDX_Control(pDX, IDC_CONNECT, m_Connect);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CArcViewDlg, CDialog)
	//{{AFX_MSG_MAP(CArcViewDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_CONNECT, OnConnect)
	ON_BN_CLICKED(IDC_SETTINGS, OnSettings)
	ON_BN_CLICKED(IDC_RECEIVE, OnReceive)
	ON_BN_CLICKED(IDC_TRANSMIT, OnTransmit)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CArcViewDlg message handlers

BOOL CArcViewDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 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);
		}
	}

	// 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
	
	// TODO: Add extra initialization here
	m_Status.SetWindowText( "Status: OFFLINE" );
	m_NodeID.EnableWindow( FALSE );
	CheckRadioButton( IDC_USB22 , IDC_SRVR , IDC_PCI20 );
	//
	// Initial values for arcnet configuration structures.
	//
	gCfg.bCom20020_128NAKs = FALSE;
	gCfg.bCom20020ReceiveAll = FALSE;
	gCfg.bCom20020ReceiveBroadcasts = TRUE;
	gCfg.bCom20020SlowArbitration = FALSE;
	gCfg.byCom20020ClockPrescaler = SPEED_2500KHZ;
	gCfg.byCom20020InterruptLevel = 0;
	gCfg.byCom20020NodeID = 5;
	gCfg.byCom20020Timeout = STANDARD_TIMEOUT;
	gCfg.uiCom20020BaseIOAddress = 0;
	//
	gSrvrCfg.hostname = NULL;
	gSrvrCfg.port = 5001;
	//
	gDeviceNumber = 0;
	gDataRate = 4;
	//
	gHostname = "";
	gHostPort = 5001;
	//
	gInitialized = FALSE;
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CArcViewDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 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.

void CArcViewDlg::OnPaint() 
{
	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
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CArcViewDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CArcViewDlg::OnConnect() 
{
	char		buffer[1024];
	int			result;
	HOSTENT		*hostent;

	// If we're already initialized.
	if ( gInitialized == TRUE )
	{
		// Shut down the device.
		Com20020Exit();

		// Show we're offline.
		m_Status.SetWindowText( "Status: OFFLINE" );

		// No node ID anymore.
		m_NodeID.SetWindowText( "Node ID:" );
		m_NodeID.EnableWindow( FALSE );

		// New button text.
		m_Connect.SetWindowText( "Connect" );

		// Disable tx/rx/register buttons.
		m_Transmit.EnableWindow( FALSE );
		m_Receive.EnableWindow( FALSE );
		m_Registers.EnableWindow( FALSE );

		// Enable Settings, and the radio buttons.
		m_Settings.EnableWindow( TRUE );
		m_USB22.EnableWindow( TRUE );
		m_PCI20.EnableWindow( TRUE );
		m_SRVR.EnableWindow( TRUE );

		// Reset the flag.
		gInitialized = FALSE;
		
		// And just return.
		return;
	}

	// If we're working with a CI-RG.
	if ( m_SRVR.GetCheck() )
	{
		// If there has been a hostname assigned.
		if ( gHostname.GetLength() != 0 )
		{
			// Assign host name and port.
			gSrvrCfg.hostname = (char *)((LPCTSTR)gHostname);
			gSrvrCfg.port = gHostPort;
		}
		else
		{
			// NULL hostname and port.
			gSrvrCfg.hostname = 0;
			gSrvrCfg.port = 0;
		}
		// Try to connect to the server.
		result = Com20020Init( (COM20020_CONFIG *)&gSrvrCfg , 0 , CI_RG );
		// If result is ok.
		if ( result == 0 )
		{
			// Create node id string.
			sprintf( buffer , "Node ID: %d" , gSrvrCfg.cf_node );
			// Show node ID.
			m_NodeID.SetWindowText( buffer );
			// Set our global node id.
			gNodeID = gSrvrCfg.cf_node;
		}
	}
	// Else we're either PCI20 or USB22
	else
	{
		// Assume slower speed.
		gCfg.bCom20020SlowArbitration = FALSE;
		// Set data rate.
		switch( gDataRate )
		{
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
			gCfg.byCom20020ClockPrescaler = 4 - gDataRate;
			break;
		case 5:
			gCfg.byCom20020ClockPrescaler = SPEED_5MHZ;
			break;
		case 6:
			gCfg.byCom20020ClockPrescaler = SPEED_7MHZ;
			gCfg.bCom20020SlowArbitration = TRUE;
			break;
		case 7:
			gCfg.byCom20020ClockPrescaler = SPEED_10MHZ;
			gCfg.bCom20020SlowArbitration = TRUE;
			break;
		default:
			gCfg.byCom20020ClockPrescaler = 0;
			break;
		}

		// Set extended timeouts.
		switch( gTimeouts )
		{
		case 0:
			gCfg.byCom20020Timeout = STANDARD_TIMEOUT;
			break;
		case 1:
			gCfg.byCom20020Timeout = QUAD_TIMEOUT;
			break;
		case 2:
			gCfg.byCom20020Timeout = EIGHT_TIMEOUT;
			break;
		case 3:
			gCfg.byCom20020Timeout = SIXTEEN_TIMEOUT;
			break;
		default:
			gCfg.byCom20020Timeout = STANDARD_TIMEOUT;
			break;
		}

		// If USB22.
		if ( m_USB22.GetCheck() )
			result = Com20020Init( &gCfg , gDeviceNumber , USB22 );
		// Else must be PCI20.
		else
			result = Com20020Init( &gCfg , gDeviceNumber , PCI20 );

		// If result is ok.
		if ( result == 0 )
		{
			// Create node id string.
			sprintf( buffer , "Node ID: %d" , gCfg.byCom20020NodeID );
			// Show node ID.
			m_NodeID.SetWindowText( buffer );
			// Set our global node id.
			gNodeID = gCfg.byCom20020NodeID;

		}
	}

	// Throw a message box and return if we weren't successful.
	if ( result != 0 )
	{
		MessageBox( "Unable to initialize" , "Connect Failure" , MB_OK | MB_ICONEXCLAMATION );
		return;
	}

	// Get our hostname.
	result = gethostname( buffer , sizeof( buffer ) );
	// Get structure.
	hostent = gethostbyname( buffer );
	// Get our ip address.
	// The last byte of the dotted address is:
	//		host_ip_address.S_un.S_un_b.s_b4
	host_ip_address.S_un.S_addr = *(unsigned long *)hostent->h_addr_list[0];

	// Success, enable tx/rx/register buttons.
	m_Transmit.EnableWindow( TRUE );
	m_Receive.EnableWindow( TRUE );
	m_NodeID.EnableWindow( TRUE );

	// Disable Settings, and the radio buttons.
	m_Settings.EnableWindow( FALSE );
	m_USB22.EnableWindow( FALSE );
	m_PCI20.EnableWindow( FALSE );
	m_SRVR.EnableWindow( FALSE );

	// Show we're online.
	m_Status.SetWindowText( "Status: ONLINE" );

	// Change button text.
	m_Connect.SetWindowText( "Disconnect" );

	// And set flag.
	gInitialized = TRUE;
}

void CArcViewDlg::OnSettings() 
{
	CDialog		*hDlg;

	switch( GetCheckedRadioButton( IDC_USB22 , IDC_SRVR ) )
	{
	case IDC_USB22:
	case IDC_PCI20:
		hDlg = new CLocalDlg;
		hDlg->DoModal();
		break;
	case IDC_SRVR:
		hDlg = new CSrvrDlg;
		hDlg->DoModal();
		break;
	default:
		break;
	}
}

void CArcViewDlg::OnOK() 
{
	// If we are initialized.
	if ( gInitialized == TRUE )
	{
		// Shut down our device.
		Com20020Exit();
	}

	CDialog::OnOK();
}

void CArcViewDlg::OnReceive() 
{
	CRxDlg		*hDlg = new CRxDlg;

	hDlg->DoModal();
}

void CArcViewDlg::OnTransmit() 
{
	CTxDlg		*hDlg = new CTxDlg;

	hDlg->DoModal();
}
