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

// LineClyde.cpp: implementation of the CLineClyde class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "LineClyde.h"
#include "ObjectFactory.h"
#include "resource.h"
#include "ProtocolDisplayNameMap.h"
#include "ProtocolSelect.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(CLineClyde, CLineWan)

CLineClyde::CLineClyde(HKEY const hKeyRoot, CString const strRegPath, CConfigObject const * const pParent) :
            CLineWan(hKeyRoot,strRegPath,pParent)

{

   try
   {
	  // clydesdale automatically determines electrical interface
	  // no need to ask it.
	  CLineWan::SetAskWhichAbilites(CLineWan::WANLINESPEED);
      // Get adapter parameters
      AffirmThrow(GetParameters());

	  if (m_strProtocol.IsEmpty()) 
		  m_strProtocol = DXB_REGVAL_PROTOCOL_ENUM_NONE;
      // Solve our identity crisis
      // NOTE: Lines do not have identities!

      // Set our display name
      CString strDisplayName;
      strDisplayName.Format(IDS_DisplayName_LineFormat, (GetLineNumber() + 1));
      SetDisplayName(strDisplayName);

      // Set what we can do
      SetAbility(CConfigObject::DOPROPERTIES);

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

      // Give birth to our children
      AffirmThrow(AddChild());

      // Init wiz mode stuff
      m_pwsSheet = NULL;
      m_pwpProtocol = NULL;
   }
   catch (CAffirmException ae)
   {
   }
}



CLineClyde::~CLineClyde()
{
   try
   {
      if (m_pwpProtocol != NULL) delete m_pwpProtocol;

      for (int i = 0; i < m_apTrash.GetSize(); i++)
      {
         if (m_apTrash[i] != NULL) DeleteConfigObject(&m_apTrash[i]);
      }
   }
   catch (CAffirmException ae)
   {
   }
}

BOOL CLineClyde::AddChild(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      Affirm(m_apChildren.GetSize() == 0);

      INT_PTR iNewChild = m_apChildren.Add(NULL);
      AffirmThrow(iNewChild == 0);

      // This registry path thingie needs a little explanation!
      //    Here's the layout so far:
      //       ...\DigiDxb?\Parameters\N           (where ? = the adapter instance, and
      //                                                  N = 0, 1, ... # of lines)
      //    The line protocol parameters reside at the same level.
      //    So, pass in the hKey and path we were given.

      AffirmThrow(NewConfigObject(&m_apChildren[iNewChild], CConfigObject::PROTOCOL, m_strProtocol, m_hKeyRoot, m_strRegPath, this));
      AffirmThrow(m_apChildren[iNewChild] != NULL);

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

   return fSuccess;
}

//////////////////////////////////////////////////////////////////////
// Get/Set parameters
//////////////////////////////////////////////////////////////////////

BOOL CLineClyde::GetParameters(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(CLineWan::GetParameters());
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CLineClyde::SetParameters(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      // Take out the garbage
      for (int i = 0; i < m_apTrash.GetSize(); i++)
      {
         AffirmThrow(m_apTrash[i] != NULL);
         m_apTrash[i]->RemoveParameters();
         DeleteConfigObject(&m_apTrash[i]);
      }
      m_apTrash.RemoveAll();

      AffirmThrow(CLineWan::SetParameters());
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

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

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

      if ((m_strProtocol != pFromLine->m_strProtocol) || (m_apChildren[0] == NULL))
      {
         if (m_apChildren[0] != NULL)
         {
            m_apChildren[0]->RemoveParameters();
            DeleteConfigObject(&m_apChildren[0]);
            m_apChildren.RemoveAll();
         }

         m_strProtocol = pFromLine->m_strProtocol;
         AffirmThrow(AddChild());
      }

      AffirmThrow(CLineWan::CopyParameters(pFrom));

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

   return fSuccess;
}

//////////////////////////////////////////////////////////////////////
// Config data
//////////////////////////////////////////////////////////////////////

BOOL CLineClyde::GetConfigData(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(CLineWan::GetConfigData());
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

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

BOOL CLineClyde::AddWizardPages(CConfigWizSheet * const pSheet)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(pSheet != NULL);

      m_pwsSheet = pSheet;

      if (m_pwpProtocol == NULL)
      {
         CString strTitle;
         CString strInstruction;

         AffirmThrow(strTitle.LoadString(IDS_Title_LineProtocol));
         AffirmThrow(strInstruction.LoadString(IDS_Instruction_LineProtocol));

         strTitle = GetDisplayName() + TEXT(" - ") + strTitle;

         m_pwpProtocol = new CWizPageComboBox(this, WP_PROTOCOL, strTitle, strInstruction);
         AffirmThrow(m_pwpProtocol != NULL);
		 m_pwpProtocol->SetHelpID(IDH_WIZ_PROTOCOLS);
      }

		 AffirmThrow(m_pwsSheet->InsertPage(m_pwpProtocol,FALSE,TRUE));

      int iDefaultProtocol = 0;
      CStringArray astrProtocolDisplayNames;

	  BuildProtocolsList(astrProtocolDisplayNames,iDefaultProtocol);
      AffirmThrow(m_pwpProtocol->SetValues(astrProtocolDisplayNames, iDefaultProtocol));

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

   return fSuccess;
}

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

   try
   {
      AffirmThrow(pSheet != NULL);

      if (m_pwsSheet != NULL)
      {
         AffirmThrow(m_pwsSheet == pSheet);

         if (m_pwpProtocol != NULL)  m_pwsSheet->RemovePage(m_pwpProtocol);
		 AffirmThrow(CLineWan::RemoveWizardPages(pSheet));
      }


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

   return fSuccess;
}

BOOL CLineClyde::HandleWizProtocol(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(m_pwsSheet != NULL);
      AffirmThrow(m_pwpProtocol != NULL);

      int iChoice = m_pwpProtocol->GetChoice();
      CString strNewProtocol = m_astrProtocolsAllowed[iChoice];

      if (m_strProtocol != strNewProtocol)
      {
		  AffirmThrow(SwitchProtocol(strNewProtocol));
		  // another kludgy fix. Refer to same comparison in SwitchProtocol()
		  if (m_strProtocol != strNewProtocol)
		  {
			  // if SwitchProtocol set m_strProtocol to something other than
			  // what we asked for, we need to stay on the same page
			  // first modify the protocol selection combo box to reflect the
			  // actual choice
			 CStringArray astrProtocolDisplayNames;

			BuildProtocolsList(astrProtocolDisplayNames,iChoice);
			AffirmThrow(m_pwpProtocol->SetValues(astrProtocolDisplayNames, iChoice));
			AffirmThrow(FALSE);
		  }
      }

	  // if the current protocol on this line is not SNA, call the base
	  // class to ask about WAN parameters
	  if ((m_strProtocol != DXB_REGVAL_PROTOCOL_ENUM_SNA) &&
		  (m_strProtocol != DXB_REGVAL_PROTOCOL_ENUM_NONE))
		  AffirmThrow(CLineWan::AddWizardPages(m_pwsSheet));

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

   return fSuccess;
}

BOOL CLineClyde::NextWizardPage(int const nState)
{
   BOOL fSuccess = FALSE;

   try
   {
      switch (nState)
      {
         case WP_PROTOCOL: 
			 AffirmThrow(HandleWizProtocol()); break;
         default: 
			 AffirmThrow(CLineWan::NextWizardPage(nState)); 
			 break;
      }

	  

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

   return fSuccess;
}

CString CLineClyde::GetInformationText(void)
{
   CString strInfo = TEXT("");

   try
   {
      AffirmThrow(m_apChildren[0] != NULL);
      strInfo.Format(IDS_Information_LineFormat, GetDisplayName(), m_apChildren[0]->GetDisplayName());
	  if (UsingWAN())
		  strInfo += CLineWan::GetInformationText();
   }
   catch (CAffirmException ae)
   {
   }

   return strInfo;
}

BOOL CLineClyde::DoProperties(void)
{

    BOOL bSuccess = FALSE;
	CPropertySheet sheet(_T("Line Properties"));
	CProtocolSelect selectdlg;

	CPropertyPage* pWan = CLineWan::GetPropertyPage();
	ASSERT(pWan);
	// build a list of allowed protocols
	CStringArray astrProtocolsList;
	int nSelection=0;
	BuildProtocolsList(astrProtocolsList,nSelection);
	// build a list of protocols for which WAN settings are not needed
	CStringArray astrProtocolsNoWAN;
	CProtocolDisplayNameMap mapProtoDisplayNames;
	astrProtocolsNoWAN.Add(mapProtoDisplayNames[DXB_REGVAL_PROTOCOL_ENUM_NONE]);
	astrProtocolsNoWAN.Add(mapProtoDisplayNames[DXB_REGVAL_PROTOCOL_ENUM_SNA]);

   // build the list of protocols for which we should inhibit baud rate change warnings
	CStringArray astrProtocolsNoWarn;
	astrProtocolsNoWarn.Add(mapProtoDisplayNames[DXB_REGVAL_PROTOCOL_ENUM_X25]);
	astrProtocolsNoWarn.Add(mapProtoDisplayNames[DXB_REGVAL_PROTOCOL_ENUM_PPP]);

   selectdlg.SetParams(astrProtocolsList,astrProtocolsNoWAN,astrProtocolsNoWarn,nSelection,pWan);
	sheet.AddPage(&selectdlg);

	if (sheet.DoModal() == IDOK)
	{
		CString strProtocol;
		strProtocol = m_astrProtocolsAllowed[selectdlg.m_nProtocolIndex];
        if (strProtocol != m_strProtocol)
		{
			if (!SwitchProtocol(strProtocol))
			{
				ASSERT(FALSE);
			}
		}

		if (UsingWAN())
			CLineWan::RetrieveParameters();
		for (int i=0;i<GetChildCount();i++)
			m_apChildren[i]->ParentUpdate();
		bSuccess = TRUE;
	}
	
	/*
	   // if we are running the SNA protocol, the line configuration will
	   // be done by SNA manager. Throw up a dialog to inform user
	   // otherwise call the base class to configure WAN properties.

	 if ((m_strProtocol != DXB_REGVAL_PROTOCOL_ENUM_SNA) &&
		 (m_strProtocol != DXB_REGVAL_PROTOCOL_ENUM_NONE))
		 bSuccess = CLineWan::DoProperties();
	*/
   return bSuccess;
}


void CLineClyde::BuildProtocolsList(CStringArray& astrNames,int& selection)
{
    
	try
	{
		CProtocolDisplayNameMap mapProtoDisplayNames;

		for (int iAllowed = 0; iAllowed < m_astrProtocolsAllowed.GetSize(); iAllowed++)
		{
			if (m_strProtocol == m_astrProtocolsAllowed[iAllowed]) selection = iAllowed;

			astrNames.SetAtGrow(iAllowed, mapProtoDisplayNames[m_astrProtocolsAllowed[iAllowed]]);
			AffirmThrow(!astrNames[iAllowed].IsEmpty());
		}
	}
	catch(CAffirmException ae)
	{
	}
}

// return TRUE if using a protocol that uses the WAN physical layer
BOOL CLineClyde::UsingWAN()
{
	BOOL bWANUsed = FALSE;
	if ((m_strProtocol != DXB_REGVAL_PROTOCOL_ENUM_SNA) &&
		(m_strProtocol != DXB_REGVAL_PROTOCOL_ENUM_NONE))
		bWANUsed = TRUE;
	return bWANUsed;
}


