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


// AdapterPRIme.cpp: implementation of the CAdapterPRIme class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AdapterPRIme.h"
#include "ObjectFactory.h"
#if defined NT5
#include "ProtocolDisplayNameMap.h"
#include "PropProtocol.h"
#endif // #if defined NT5

#include "Resource.h"


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

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

IMPLEMENT_DYNAMIC(CAdapterPRIme, CAdapter)

CAdapterPRIme::CAdapterPRIme(HKEY const hKeyRoot, CString const & strRegPath, CConfigObject const * const pParent) : CAdapter(hKeyRoot, strRegPath, pParent)
{
   try
   {
      // Get parameters
      AffirmThrow(GetParameters());

      // Set what we can do
#if defined NT5
      SetAbility(CConfigObject::DOPROPERTIES);
#else
      SetAbility(CConfigObject::NOABILITIES);
#endif

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

#if defined NT5
      // Init wiz mode stuff
		m_pwpProtocol = NULL;
#endif // #if defined NT5

   }
   catch (CAffirmException ae)
   {
   }
}

CAdapterPRIme::~CAdapterPRIme()
{
   try
   {
#if defined NT5
      if (NULL != m_pwpProtocol) delete m_pwpProtocol;
#endif // #if defined NT5
   }
   catch (CAffirmException ae)
   {
   }
}

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

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

   try
   {
#if defined NT5
      // NOTE: NOTE: This assumes a lot!
      // Since the Line objects aren't created yet, we get this from the registry early
      // The value should have been set by the installer if that's where we are
      // Line indexes must be zero based
      // The first line key must be present (0)
      // If more than one line, the protocols must be the same (for NT5 we impose this rule)
      m_strProtocol = TEXT("");
      HKEY hLineKey;
      if (RegOpenKey(m_hKey, TEXT("0"), &hLineKey))
      {
         AffirmThrow(RegReadStrValue(hLineKey, DXB_REGVAL_PROTOCOL, m_strProtocol));
      }
      RegCloseKey(hLineKey);
#endif // #if defined NT5

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

   return fSuccess;
}

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

   try
   {
      AffirmThrow(CAdapter::SetParameters());

#if defined NT5
      // NOTE: NOTE: The lines will take care of writing the protocol parameter
      // The adapter only needs to write the ISDN Wiz bit
      // If we're not PRI (ISDN) then we need to disable MS's ISDN Wiz

      // Get the registry entry that specifies our adapter instance,
      // it's one level up from here...
      // But, use the value "RegInstance" that's at the Parameters level (m_hKey)
      CString strRegInstance;
      CString strInstanceKey;
      AffirmThrow(RegReadStrValue(m_hKey, DXB_REGVAL_REGINSTANCE, strRegInstance));
      strInstanceKey.Format("%s%s", DXB_REGCLASS_VALUE, strRegInstance);
      TRACE("CAdapterPRIme::SetParameters(): Opening %s\n", strInstanceKey);
      HKEY hAdapterInstance;
      if (RegOpenKey(HKEY_LOCAL_MACHINE, strInstanceKey, &hAdapterInstance))
      {
         BOOL fShowIsdn = ( (DXB_REGVAL_PROTOCOL_ENUM_E1 == m_strProtocol) || (DXB_REGVAL_PROTOCOL_ENUM_PRI == m_strProtocol) );
         TRACE("CAdapterPRIme::SetParameters(): Writing  ShowIsdnPages value:%d\n", fShowIsdn ? 1 : 0);
         AffirmThrow(RegWriteDWordValue(  hAdapterInstance,
                                          TEXT("ShowIsdnPages"),
                                          (fShowIsdn ? 1 : 0)));
         RegCloseKey(hAdapterInstance);
      }
#endif // #if defined NT5

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

   return fSuccess;
}

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

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

   try
   {
#if defined NT5
      // Get the line protocols available for this kind of adapter
      CString strConfigDataRegPath;
      AffirmThrow(BuildConfigDataRegPath(strConfigDataRegPath));
      TRACE("CAdapterPRIme::GetConfigData(): strConfigDataRegPath:%s\n",strConfigDataRegPath);
      HKEY hConfigData = NULL;
      AffirmThrow(RegOpenKey(HKEY_LOCAL_MACHINE, strConfigDataRegPath, &hConfigData));
      AffirmThrow(hConfigData != NULL);
      AffirmThrow(RegReadMultiStrValue(hConfigData, DXB_REGVAL_PROTOCOLS_ALLOWED, m_astrProtocolsAllowed));
      RegCloseKey(hConfigData);
#endif // #if defined NT5

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

   return fSuccess;
}

//////////////////////////////////////////////////////////////////////
// Wizard config methods
//////////////////////////////////////////////////////////////////////

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

   try
   {
      AffirmThrow(pSheet != NULL);

#if defined(_DEBUG)
      if ((m_pwsSheet != NULL) && (m_pwsSheet != pSheet))
         TRACE("AddWizardPages() called for different sheet!\n");
#endif

      AffirmThrow(CAdapter::AddWizardPages(pSheet));

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

   return fSuccess;
}

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

   try
   {
      AffirmThrow(pSheet != NULL);

#if defined NT5
      if (NULL != m_pwpProtocol) pSheet->RemovePage(m_pwpProtocol);
#endif // #if defined NT5

      AffirmThrow(CAdapter::RemoveWizardPages(pSheet));

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

   return fSuccess;
}

BOOL CAdapterPRIme::HandleWizWelcome(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(m_pwsSheet != NULL);

#if defined NT5
      // Create, configure and add the protocol wiz page
		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_WizPageLineProtocol);

			int iDefaultProtocol = 0;
			CProtocolDisplayNameMap mapProtocolDisplayNames;
			CStringArray astrProtocolDisplayNames;

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

				astrProtocolDisplayNames.SetAtGrow(iAllowed, mapProtocolDisplayNames[m_astrProtocolsAllowed[iAllowed]]);
				AffirmThrow(!astrProtocolDisplayNames[iAllowed].IsEmpty());
			}

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

  		AffirmThrow(m_pwsSheet->InsertPage(m_pwpProtocol));
#else // #if defined NT5
      AffirmThrow(CAdapter::HandleWizWelcome());
#endif // #if defined NT5

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

   return fSuccess;
}

#if defined NT5
BOOL CAdapterPRIme::HandleWizProtocol(void)
{
   BOOL fSuccess = FALSE;

   // The protocol page finished, need to impose the new protocol on the child lines....
   try
   {
      AffirmThrow(m_pwsSheet != NULL);
      TRACE("CAdapterPRIme::HandleWizProtocol()\n");

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

      // We assume that the children are lines here
      // Step through all of them and impose the change
      for (int j = 0; j < m_apChildren.GetSize(); j++)
      {
         AffirmThrow(m_apChildren[j] != NULL);
         CLine * pChild = (CLine *)m_apChildren[j];
         TRACE("CAdapterPRIme::HandleWizProtocol(): Switching Line:%d to Protocol:%s\n", j, m_strProtocol);
         AffirmThrow(pChild->SwitchProtocol(m_strProtocol));
      }

      // For NT5, we need to add our line pages here
      // CAdapter::HandleWizWelcome() ends up doing this...
      AffirmThrow(CAdapter::HandleWizWelcome());

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

   return fSuccess;
}
#endif // #if defined NT5

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

   try
   {
      switch (nState)
      {
         case WP_WELCOME: AffirmThrow(HandleWizWelcome());                break;
#if defined NT5
         case WP_PROTOCOL: AffirmThrow(HandleWizProtocol());              break;
#endif // #if defined NT5
         default:         AffirmThrow(CAdapter::NextWizardPage(nState));  break;
      }

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

   return fSuccess;
}

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

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

   try
   {
#if defined NT5
      CString strInfoProtocol = TEXT("");
      CProtocolDisplayNameMap mapProtocolDisplayNames;
      strInfoProtocol.Format(IDS_Information_LineFormat,mapProtocolDisplayNames[m_strProtocol]);
#endif // #if defined NT5
   }
   catch (CAffirmException ae)
   {
   }

   return strInfo;
}

BOOL CAdapterPRIme::DoProperties(void)
{
   BOOL fThingsHaveChanged = FALSE;

   try
   {
#if !defined NT5
      AffirmThrow(FALSE);
#else
      CPropertySheet PropSheet(GetDisplayName());

      // Create and add the Protocol page
      CProtocolDisplayNameMap mapProtocolDisplayNames;
      CStringArray astrProtocolDisplayNames;
      int iDefaultProtocol = 0;
      for (int iAllowed = 0; iAllowed < m_astrProtocolsAllowed.GetSize(); iAllowed++)
      {
         if (m_strProtocol == m_astrProtocolsAllowed[iAllowed]) iDefaultProtocol = iAllowed;
         astrProtocolDisplayNames.SetAtGrow(iAllowed, mapProtocolDisplayNames[m_astrProtocolsAllowed[iAllowed]]);
         AffirmThrow(!astrProtocolDisplayNames[iAllowed].IsEmpty());
      }
      CPropProtocol PropProtocol(IDS_Title_LineProtocol);
      AffirmThrow(PropProtocol.SetValues(astrProtocolDisplayNames, iDefaultProtocol));
      PropSheet.AddPage(&PropProtocol);

      // Run the propsheet
      PropSheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
      if (PropSheet.DoModal() == IDOK)
      {
         int iChoice = PropProtocol.GetChoice();
         m_strProtocol = m_astrProtocolsAllowed[iChoice];
         // We assume that the children are lines here
         // Step through all of them and impose the change
         for (int j = 0; j < m_apChildren.GetSize(); j++)
         {
            AffirmThrow(m_apChildren[j] != NULL);
            CLine * pChild = (CLine *)m_apChildren[j];
            TRACE("CAdapterPRIme::DoProperties(): Switching Line:%d to Protocol:%s\n", j, m_strProtocol);
            AffirmThrow(pChild->SwitchProtocol(m_strProtocol));
         }

         fThingsHaveChanged = TRUE;
      }
#endif
   }
   catch (CAffirmException ae)
   {
   }

   return fThingsHaveChanged;
}
