/*****************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/
// X25Settings.cpp : implementation file
// allow user to specify the various settings for X.25 protocol 

#include "stdafx.h"
#include "x25def.h"
#include "X25Settings.h"

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


extern MGX25DS gMgX25_data;

/////////////////////////////////////////////////////////////////////////////
// CX25Settings property page

IMPLEMENT_DYNCREATE(CX25Settings, CPropertyPage)

CX25Settings::CX25Settings() : CPropertyPage(CX25Settings::IDD)
{
	//{{AFX_DATA_INIT(CX25Settings)
	m_NUAAddress = _T("");
	m_RangeOutgoing = _T("");
	m_RangePVC = _T("");
	m_RangeIncoming = _T("");
	m_RangeTwoWay = _T("");
	m_DataRateHigh = -1;
	m_EncodingNRZ = -1;
	m_bFilter = FALSE;
	m_bReverse = FALSE;
	m_bStandby = FALSE;
	m_bStartup = FALSE;
	m_N2RetryLimit = 0;
	m_T1Timeout = 0;
	//}}AFX_DATA_INIT
}

CX25Settings::~CX25Settings()
{
}

void CX25Settings::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CX25Settings)
	DDX_Control(pDX, IDC_L3Window, m_L3Window);
	DDX_Control(pDX, IDC_L3Packet, m_L3Packet);
	DDX_Control(pDX, IDC_L2Window, m_L2Window);
	DDX_Text(pDX, IDC_NUAAddress, m_NUAAddress);
	DDV_MaxChars(pDX, m_NUAAddress, 15);
	DDX_Text(pDX, IDC_Outgoing, m_RangeOutgoing);
	DDV_MaxChars(pDX, m_RangeOutgoing, 9);
	DDX_Text(pDX, IDC_Pvc, m_RangePVC);
	DDV_MaxChars(pDX, m_RangePVC, 9);
	DDX_Text(pDX, IDC_Incoming, m_RangeIncoming);
	DDV_MaxChars(pDX, m_RangeIncoming, 9);
	DDX_Text(pDX, IDC_TwoWay, m_RangeTwoWay);
	DDV_MaxChars(pDX, m_RangeTwoWay, 9);
	DDX_Check(pDX, IDC_Filter, m_bFilter);
	DDX_Check(pDX, IDC_Reverse, m_bReverse);
	DDX_Check(pDX, IDC_Standby, m_bStandby);
	DDX_Check(pDX, IDC_Startup, m_bStartup);
	DDX_Text(pDX, IDC_N2, m_N2RetryLimit);
	DDV_MinMaxInt(pDX, m_N2RetryLimit, 1, 100);
	DDX_Text(pDX, IDC_T1, m_T1Timeout);
	DDV_MinMaxInt(pDX, m_T1Timeout, 1, 100);
	DDX_Radio(pDX, IDC_DataRateLow, m_DataRateHigh);
	DDX_Radio(pDX, IDC_EncodingNRZ, m_EncodingNRZ);
	//}}AFX_DATA_MAP
	if (pDX->m_bSaveAndValidate)
	{
		// validate the 4 ranges. To be fancy, we could supply our
		// DDV routine.
		if (!ValidateRange(m_RangeOutgoing,_T("Outgoing")))
		{
			pDX->PrepareEditCtrl(IDC_Outgoing);
			pDX->Fail();
		}
		if (!ValidateRange(m_RangeIncoming,_T("Incoming")))
		{
			pDX->PrepareEditCtrl(IDC_Incoming);
			pDX->Fail();
		}
		if (!ValidateRange(m_RangePVC,_T("PVC")))
		{
			pDX->PrepareEditCtrl(IDC_Pvc);
			pDX->Fail();
		}
		if (!ValidateRange(m_RangeTwoWay,_T("Two Way")))
		{
			pDX->PrepareEditCtrl(IDC_TwoWay);
			pDX->Fail();
		}
	}
}


BEGIN_MESSAGE_MAP(CX25Settings, CPropertyPage)
	//{{AFX_MSG_MAP(CX25Settings)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CX25Settings message handlers

BOOL CX25Settings::OnInitDialog() 
{
	m_NUAAddress =		gMgX25_data.szNUAAddress;
	m_RangeOutgoing =	gMgX25_data.szRangeOutgoing;
	m_RangeIncoming =	gMgX25_data.szRangeIncoming;
	m_RangePVC =		gMgX25_data.szRangePVC;
	m_RangeTwoWay =		gMgX25_data.szRangeTwoWay;
	m_DataRateHigh =	gMgX25_data.bDataRate;
	m_EncodingNRZ =		gMgX25_data.bEncodingNRZ;
	m_bFilter =			gMgX25_data.bFilter;
	m_bReverse =		gMgX25_data.bReverse;
	m_bStandby =		gMgX25_data.bStandby;
	m_bStartup =		gMgX25_data.bStartup;
	m_T1Timeout =		(short)gMgX25_data.dT1Timeout;
	m_N2RetryLimit =	(short)gMgX25_data.dN2RetryLimit;

	CPropertyPage::OnInitDialog();

	CString sztmp;
	sztmp.Format("%d",gMgX25_data.dL2Window);
	m_L2Window.SelectString(-1,sztmp);
	
	sztmp.Format("%d",gMgX25_data.dL3Window);
	m_L3Window.SelectString(-1,sztmp);
		
	sztmp.Format("%d",gMgX25_data.dL3PacketSize);
	m_L3Packet.SelectString(-1,sztmp);

	
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CX25Settings::OnOK() 
{
	gMgX25_data.szNUAAddress =		m_NUAAddress;
	gMgX25_data.szRangeOutgoing =	m_RangeOutgoing; 
	gMgX25_data.szRangeIncoming =	m_RangeIncoming; 
	gMgX25_data.szRangePVC =		m_RangePVC;		
	gMgX25_data.szRangeTwoWay =		m_RangeTwoWay;	
	gMgX25_data.bDataRate =			m_DataRateHigh;	
	gMgX25_data.bEncodingNRZ =		m_EncodingNRZ;	
	gMgX25_data.bFilter =			m_bFilter;		
	gMgX25_data.bReverse =			m_bReverse;		
	gMgX25_data.bStandby =			m_bStandby;		
	gMgX25_data.bStartup =			m_bStartup;		
	gMgX25_data.dT1Timeout =		m_T1Timeout;		
	gMgX25_data.dN2RetryLimit =		m_N2RetryLimit;	

	CString sztmp;
	m_L2Window.GetLBText(m_L2Window.GetCurSel(),sztmp);
	gMgX25_data.dL2Window =			atoi(sztmp);
	m_L3Packet.GetLBText(m_L3Packet.GetCurSel(),sztmp);
	gMgX25_data.dL3PacketSize =		atoi(sztmp);
	m_L3Window.GetLBText(m_L3Window.GetCurSel(),sztmp);
	gMgX25_data.dL3Window =			atoi(sztmp);

	CPropertyPage::OnOK();
}

// looking for the format xxxx-yyyy where xxxx & yyyy are positive integers
// and range from 1-9999 and xxxx < yyyy
BOOL CX25Settings::ValidateRange(CString & szRange,LPCTSTR lpszTarget)
{
	ASSERT(szRange);
	BOOL bRetCode = TRUE;
	try
	{
		// empty strings are ok
		if (!szRange.IsEmpty())
		{
			int pos = szRange.Find('-');
			if (pos == -1)
				throw lpszTarget;
			// extract the xxxx part of the range
			CString szleft(szRange.Left(pos));
			// need to extract the yyyy part.
			pos = szRange.GetLength() - 1 - pos;
			if (pos <= 0)
				throw lpszTarget;
			CString szright(szRange.Right(pos));
			int nRangeStart = Convert(szleft);
			int nRangeEnd = Convert(szright);
			if (nRangeStart == -1 || nRangeEnd == -1 || 
				nRangeStart > nRangeEnd)
				throw lpszTarget;
			szRange.Format("%4.4d-%4.4d",nRangeStart,nRangeEnd);
		}
	}
	catch(LPCTSTR szMsg)
	{
		bRetCode = FALSE;
		CString sztmp;
		sztmp.LoadString(IDS_RANGEERROR);
		CString sztmp2;
		sztmp2.Format(sztmp,szMsg);
		AfxMessageBox(sztmp2);
	}
	
	return bRetCode;
}

int CX25Settings::Convert(CString& szRange)
{
	szRange.TrimLeft();szRange.TrimRight();
	CString sztemp(szRange.SpanIncluding(_T("0123456789")));
	if (sztemp.GetLength() != szRange.GetLength())
		return -1;
	return (atoi(sztemp));
}

