/*****************************************************************************
* 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
*
*****************************************************************************/
// Wan.cpp: implementation of the CLineWan class.
//
//////////////////////////////////////////////////////////////////////
// This is a support class that has all the line charactersistics related data
// handles the dialog that allows user to enter relevant data
// Line classes for adapters supporting the WAN physical interface must derive
// from this class. Currently, the derived class must include this CPP file
// and WanConfig.CPP file in its project. Also the linewan.rc and linewanres.h
// files must be included.

#include "stdafx.h"
#include "LineWan.h"
#include "ObjectFactory.h"
#include "wanreg.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CLineWan,CLine)

#define	WAN_EXTBAUD		_T("Ext_Baud")

#define WAN_ELECVAL3			0x80000000
#define WAN_ELEC3				3
CLineWan::CLineWan(HKEY const hKeyRoot, CString const strRegPath, CConfigObject const * const pParent) :
			CLine(hKeyRoot,strRegPath,pParent)
{
	// set for external clocking.
	m_WAN.ext_baud = DXB_REGVAL_WAN_BAUD_DEFAULT;
	m_WAN.wan_baud = 0;
	m_WAN.wan_interface = DXB_REGVAL_WAN_INTERFACE_DEFAULT;
	m_WAN.wan_maxframe = DXB_REGVAL_WAN_MAXFRAME_DEFAULT;

	m_WanAbilities = WANINTERFACE | WANLINESPEED;
	m_pwpLineSpeed = NULL;
	m_pwpElecInterface = NULL;
	m_pwpClocking = NULL;
	m_pwpWanConfig = NULL;
	m_pwsSheet = NULL;
	// set this in the parent object
	m_dwLineSpeed = GetBaudRate();
	SetLineClocking(m_WAN.ext_baud);
/*	try
	{
		AffirmThrow(GetParameters());
	}
	catch(CAffirmException ae)
	{
	}
*/
}

CLineWan::~CLineWan()
{
	delete m_pwpLineSpeed;
	delete m_pwpElecInterface;
	delete m_pwpClocking;
	delete m_pwpWanConfig;
}


// write FrameRelay protocol params to registry
BOOL CLineWan::SetParameters()
{
	BOOL bSuccess = FALSE;
	try
	{
		AffirmThrow(CLine::SetParameters());
		AffirmThrow(ReadWriteWanParams(FALSE));
		bSuccess = TRUE;
	}
	catch(CAffirmException ae)
	{
	}
	return bSuccess;
}


// read frame relay protocol params from registry
BOOL CLineWan::GetParameters()
{
	BOOL bSuccess = FALSE;
	try
	{
		AffirmThrow(CLine::GetParameters());
		AffirmThrow(ReadWriteWanParams(TRUE));
		bSuccess = TRUE;
	}
	catch(CAffirmException ae)
	{
	}
	return bSuccess;

}

BOOL CLineWan::RemoveParameters(BOOL fRemoveKey)
{

    BOOL fSuccess = FALSE;

    try
	{
		// remove the WAN and FR keys.
		RegDelKey(m_hKey,DXB_REGKEY_WAN);
		AffirmThrow(CLine::RemoveParameters(fRemoveKey));
		fSuccess = TRUE;
	}
	catch (CAffirmException ae)
	{
	}

	return fSuccess;
}

// Use WizComboBox pages to ask line speed & electrical interface
// Use WizRadioPage to ask for electrical interface.
BOOL CLineWan::AddWizardPages(CConfigWizSheet * const pSheet)
{
	BOOL bSuccess = FALSE;
	try
	{
		AffirmThrow(pSheet != NULL);
		m_pwsSheet = pSheet;
		// if we can ask for Electrical Interface
		CString strTitle,strInstructions;
		BOOL bPageInserted = FALSE;
		
		if (m_WanAbilities & WANINTERFACE)
		{
			if (!m_pwpElecInterface) 
			{
				strTitle.LoadString(IDS_TITLEWAN_INTERFACE);
				strInstructions.LoadString(IDS_INTERFACE_INSTR);
				m_pwpElecInterface = new CWizPageComboBox(this,WP_INTERFACE,strTitle,strInstructions);
				AffirmThrow((m_pwpElecInterface != NULL));
				m_pwpElecInterface->SetHelpID(IDH_WIZ_ELECINTERFACE);
			}
			CStringArray astrInterfaces;
			int vals[]={11,24,35,36};
			for(int i=0;i<sizeof(vals);i++)
			{
				strInstructions.Format("V.%d",vals[i]);
				astrInterfaces.SetAtGrow(i,strInstructions);
			}
			m_pwpElecInterface->SetValues(astrInterfaces,0);
			pSheet->InsertPage(m_pwpElecInterface);
			bPageInserted = TRUE;
		}

		// only if didn't add an interface wizard page
		if (!bPageInserted)
		{
			AffirmThrow(AddWizClockingPage());
		}	

		bSuccess = TRUE;
	}
	catch (CAffirmException ae)
	{
	}
	return bSuccess;
}

BOOL CLineWan::AddWizClockingPage()
{
	BOOL bSuccess = FALSE;
	try
	{
		// if we can ask for linespeed
		if (m_WanAbilities & WANLINESPEED)
		{
			if (!m_pwpClocking)
			{
				CString strTitle,strInstructions;
				strTitle.LoadString(IDS_TITLEWAN_CLOCKING);
				strInstructions.LoadString(IDS_CLOCKING_INSTR);
				m_pwpClocking = new CWizPageRadioButtons(this,WP_CLOCKING,strTitle,strInstructions);
				AffirmThrow(m_pwpClocking != NULL);
				m_pwpClocking->SetHelpID(IDH_WIZ_CLOCKING);
			}
			CStringArray astrValues;
			astrValues.SetAtGrow(0,_T("External"));
			astrValues.SetAtGrow(1,_T("Internal"));
			int choice = (m_WAN.ext_baud != 0)?0:1;
			m_pwpClocking->SetValues(astrValues,choice);
			m_pwsSheet->InsertPage(m_pwpClocking);
		}
		bSuccess = TRUE;
	}
	catch(CAffirmException ae)
	{
	}
	return bSuccess;
}

BOOL CLineWan::AddWizLineSpeedPage()
{
	BOOL bSuccess = FALSE;
	try
	{
		if (!m_pwpLineSpeed)
		{
			m_pwpLineSpeed = new CWizLineSpeed(this,WP_LINESPEED);
			AffirmThrow((m_pwpLineSpeed != NULL));
		}
		m_pwpLineSpeed->m_nLineSpeed = GetBaudRate();
		m_pwsSheet->InsertPage(m_pwpLineSpeed);
		bSuccess = TRUE;
	}
	catch(CAffirmException ae)
	{
	}
	return bSuccess;
}

// No handling of NextWizardPage
BOOL CLineWan::NextWizardPage(int const State)
{
	BOOL bSuccess = FALSE;
	try
	{
		switch(State)
		{
		case WP_INTERFACE:
			{
			int nChoice = m_pwpElecInterface->GetChoice();
			if (nChoice == WAN_ELEC3) 
				nChoice = WAN_ELECVAL3;

			m_WAN.wan_interface = nChoice;
			AffirmThrow(AddWizClockingPage());
			}
			break;
		case WP_CLOCKING:
			{
				int nChoice = m_pwpClocking->GetChoice();
				if (nChoice == 1)
				{
					m_bExternal = FALSE;
				}
				else
				{
					m_bExternal = TRUE;
				}
				AffirmThrow(AddWizLineSpeedPage());
			}
			break;
				
		case WP_LINESPEED:
			{
			if (m_bExternal == FALSE)
			{
				m_WAN.ext_baud = 0;
				m_WAN.wan_baud = m_pwpLineSpeed->m_nLineSpeed;
			}
			else
			{
				m_WAN.wan_baud = 0;
				m_WAN.ext_baud = m_pwpLineSpeed->m_nLineSpeed;
			}
			SetLineSpeed(GetBaudRate());
			SetLineClocking(m_WAN.ext_baud);
			for(int i=0;i<GetChildCount();i++)
			{
				m_apChildren[i]->ParentUpdate();
				AffirmThrow(m_apChildren[i]->AddWizardPages(m_pwsSheet));
			}

			}
			break;
		default:
			AffirmThrow(FALSE);
			break;
		}
		bSuccess = TRUE;

	}

	catch(CAffirmException ae)
	{
	}

	return bSuccess;
}


// read/write WAN params. bRead = TRUE denotes reading
// the subkey WAN is created under the line key.
BOOL CLineWan::ReadWriteWanParams(BOOL bRead)
{
	// 
	if (bRead && !RegKeyExists(m_hKey,DXB_REGKEY_WAN))
	{
		return TRUE;	
	}
	HKEY hsubkey;
	//
	// open the FRAME RELAY section
	if (!RegCreateKey(m_hKey,DXB_REGKEY_WAN,&hsubkey))
		return FALSE;
	
	if (bRead)
	{
		RegReadIntValue(hsubkey,WAN_EXTBAUD,&m_WAN.ext_baud);
		RegReadIntValue(hsubkey,DXB_REGVAL_WAN_BAUD,&m_WAN.wan_baud);
		RegReadIntValue(hsubkey,DXB_REGVAL_WAN_INTERFACE,&m_WAN.wan_interface);
		RegReadIntValue(hsubkey,DXB_REGVAL_WAN_MAXFRAME,&m_WAN.wan_maxframe);
		SetMaxFrameSize(m_WAN.wan_maxframe);
		SetLineSpeed(GetBaudRate());
		SetLineClocking(m_WAN.ext_baud);
	}

	else
	{
		m_WAN.wan_maxframe = GetMaxFrameSize();
		RegWriteIntValue(hsubkey,WAN_EXTBAUD,m_WAN.ext_baud);
		RegWriteIntValue(hsubkey,DXB_REGVAL_WAN_BAUD,m_WAN.wan_baud);
		RegWriteIntValue(hsubkey,DXB_REGVAL_WAN_INTERFACE,m_WAN.wan_interface);
		RegWriteIntValue(hsubkey,DXB_REGVAL_WAN_MAXFRAME,m_WAN.wan_maxframe);
		RegWriteIntValue(hsubkey,DXB_REGVAL_WAN_OPTIONS,DXB_REGVAL_WAN_OPTIONS_DEFAULT);
	}
	RegCloseKey(hsubkey);
	return TRUE;
}


// bring up the wan configuration dialog.
BOOL CLineWan::DoProperties(void)
{
	BOOL bSuccess = FALSE;
	CWanConfig dlg;

	SetPageParams(&dlg);
	CPropertySheet sheet(_T("WAN"));
	sheet.AddPage(&dlg);
	if (sheet.DoModal() == IDOK)
	{
		GetPageParams(&dlg);
		for(int i=0;i<GetChildCount();i++)
			m_apChildren[i]->ParentUpdate();
		bSuccess = TRUE;
	}

	return bSuccess;
}

BOOL CLineWan::RemoveWizardPages(CConfigWizSheet * const pSheet)
{
	BOOL fSuccess = FALSE;

	try
	{

		AffirmThrow(pSheet != NULL);

		// Remove  the wizard pages that were added by our class
		if (m_pwpElecInterface) pSheet->RemovePage(m_pwpElecInterface);
		if (m_pwpLineSpeed) pSheet->RemovePage(m_pwpLineSpeed);
		if (m_pwpClocking) pSheet->RemovePage(m_pwpClocking);
		AffirmThrow(CLine::RemoveWizardPages(pSheet));

		fSuccess = TRUE;
	}
	catch (CAffirmException ae)
	{
	}

   return fSuccess;
}

BOOL CLineWan::CopyParameters(CConfigObject const * const pFrom)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(pFrom != NULL);
      CLineWan * pFromLine = (CLineWan *) pFrom;

	  m_WAN = pFromLine->m_WAN;
      AffirmThrow(CLine::CopyParameters(pFrom));

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

// return the baud rate for the line.
int CLineWan::GetBaudRate() const
{
	int nBaudRate = m_WAN.ext_baud;
	if (!nBaudRate)
		nBaudRate = m_WAN.wan_baud;
	return nBaudRate;
}

// provide a pointer to the property page that allows WAN configurations
CPropertyPage* CLineWan::GetPropertyPage()
{
	CPropertyPage* pPage = NULL;
	try
	{
		if (!m_pwpWanConfig)
		{
			m_pwpWanConfig = new CWanConfig;
			AffirmThrow(m_pwpWanConfig != NULL);
		}
		SetPageParams(m_pwpWanConfig);
		pPage = (CPropertyPage*)m_pwpWanConfig;
	}
	catch(CAffirmException ae)
	{
	}
	return pPage;
}

// public accessor for extracting params from property page
BOOL CLineWan::RetrieveParameters()
{
	BOOL bSuccess = FALSE;
	if (m_pwpWanConfig)
	{
		GetPageParams(m_pwpWanConfig);
		bSuccess = TRUE;
	}
	return bSuccess;
}

// set parameters in property page
void CLineWan::SetPageParams(CWanConfig* pPage)
{
	ASSERT_KINDOF(CWanConfig,pPage);
	if (m_WAN.ext_baud)
		pPage->m_Baud = m_WAN.ext_baud;
	else
		pPage->m_Baud = m_WAN.wan_baud;

	pPage->m_ExternalClock = (m_WAN.ext_baud > 0)?0:1;
	if (m_WAN.wan_interface == WAN_ELECVAL3)
		pPage->m_ElectricalInt = WAN_ELEC3;
	else
		pPage->m_ElectricalInt =m_WAN.wan_interface;

	pPage->m_bAskInterface = (m_WanAbilities & WANINTERFACE)?TRUE:FALSE;

}

// extract parameters from property page
void CLineWan::GetPageParams(CWanConfig* pPage)
{
	ASSERT_KINDOF(CWanConfig,pPage);
	m_WAN.ext_baud = (pPage->m_ExternalClock == 0)?pPage->m_Baud:0;
	m_WAN.wan_baud = (pPage->m_ExternalClock == 0)?0:pPage->m_Baud;

	m_WAN.wan_interface = (pPage->m_ElectricalInt == WAN_ELEC3)? 
		WAN_ELECVAL3 : pPage->m_ElectricalInt;
	// set the base class line speed 
	SetLineSpeed(GetBaudRate());
	// set the base class line clocking
	SetLineClocking(m_WAN.ext_baud);
}


CString CLineWan::GetInformationText(void)
{
	CString strInfo;
	strInfo.Format(IDS_LINEWAN_INFO,GetBaudRate(),
		(m_WAN.ext_baud)?_T("External"):_T("Internal"));
	return strInfo;
}