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

// ServiceFR.cpp: implementation of the CServiceFR class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "ServiceFR.h"
#include "ObjectFactory.h"
#include "defs.h"
#include "ProtocolFR.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CServiceFR, CServiceBase)

CServiceFR::CServiceFR(HKEY const hKeyRoot, CString const strRegPath, CConfigObject const * const pParent)
			:CServiceBase(hKeyRoot, strRegPath, pParent)
{
   try
   {
       // Get adapter parameters
       AffirmThrow(GetParameters());

       // Solve our identity crisis
       SetIdentity(DXB_REGVAL_LINE_SERVICE_FR);

 	   CString szDisplayName;
	   AffirmThrow(szDisplayName.LoadString(IDS_FRServiceName));
	   SetDisplayName(szDisplayName);

	   SetAbility(CConfigObject::ADDCHILD | 
		   CConfigObject::DELETECHILD);

	   // Get our static config data
       AffirmThrow(GetConfigData());


      // Give birth to our children. Need to read the number of PVC ports existing 
	  // in the registry

	   DWORD dwIndex = 0;
	   TCHAR szbuffer[32];
	   DWORD dwbuffsize = sizeof(szbuffer);
	   PFILETIME lpftime = NULL;
	   while (RegEnumKeyEx(m_hKey,dwIndex,szbuffer,&dwbuffsize,NULL,NULL,NULL,lpftime) ==
		   ERROR_SUCCESS)
	   {
		   m_apChildren.SetAtGrow(dwIndex, NULL);
			
		   AffirmThrow(NewConfigObject(&m_apChildren[dwIndex], CConfigObject::PORT, 
			 DXB_REGVAL_PORT_TYPE_FR, m_hKey, szbuffer, this));      // always Frame
           AffirmThrow(m_apChildren[dwIndex] != NULL);
		   dwIndex++;
		   dwbuffsize = sizeof(szbuffer);
       }
   }
   catch (CAffirmException ae)
   {
   }

}

CServiceFR::~CServiceFR()
{
}


//////////////////////////////////////////////////////////////////////
// UI config methods
//////////////////////////////////////////////////////////////////////

// pop up new PVC dialog box and allow user to add it.
BOOL CServiceFR::AddChild(void)
{
	BOOL bSuccess = FALSE;

	try
	{
		// ask the parent protocol whether we can add another PVC entry
		if (((CProtocolFR*)GetParent())->AllocPVC())
		{
			// enumerate subkeys to see which one we can use.
			// keys are all numeric and start with 0 and work from there
			CString szPortKey;
			DWORD_PTR dwIndex=0;
	
			do
			{
				szPortKey.Format("%d",dwIndex++);
			}while(RegKeyExists(m_hKey,szPortKey));

			CConfigObject* pChild = NULL;
			AffirmThrow(NewConfigObject(&pChild, CConfigObject::PORT, 
			 DXB_REGVAL_PORT_TYPE_FR, m_hKey, szPortKey, this));      // always Frame
			// Give the user a chance to accept/cancel creation of child
			if (pChild->DoProperties())
			{
				dwIndex = GetChildCount();
				m_apChildren.SetAtGrow(dwIndex,NULL);
				m_apChildren[dwIndex] = pChild;
				bSuccess = TRUE;
			}
			else
			{
				DeleteChild(pChild);
				DeleteConfigObject( &pChild );
			}
		}

	}

	catch(CAffirmException ae)
	{
	}

	return bSuccess;
	
}

BOOL CServiceFR::DeleteChild(CConfigObject const * const pChild)
{
	// inform parent protocol of regaining a PVC count
	((CProtocolFR*)GetParent())->DeAllocPVC();
	CServiceBase::DeleteChild(pChild);
	return TRUE;
}


// return the line speed on which this service is installed
// by calling the protocol parent.
DWORD CServiceFR::GetLineSpeed() const
{
	return(((CProtocolFR*)GetParent())->GetLineSpeed());
}


// parent has changed. Inform PVC's that are affected by them.
void CServiceFR::ParentUpdate(void)
{
	for(int i=0;i<GetChildCount();i++)
		m_apChildren[i]->ParentUpdate();
}