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


// ProtocolT1.cpp: implementation of the CProtocolT1 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ProtocolT1.h"
#include "PropSignaling.h"
#include "PropAdvanced.h"
#include "ObjectFactory.h"

#include "Resource.h"

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

IMPLEMENT_DYNAMIC(CProtocolT1, CProtocol)

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

      // Solve our identity crisis
      SetIdentity(DXB_REGVAL_PROTOCOL_ENUM_T1);

      // Set our display name
      CString strDisplayName;
      AffirmThrow(strDisplayName.LoadString(IDS_DisplayName_T1));
      SetDisplayName(strDisplayName);

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

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

      m_astrServices.Copy(m_astrServicesAllowed);

      // Give birth to our children
      for (int i = 0; i < m_astrServices.GetSize(); i++)
      {
         AffirmThrow(AddChild(m_astrServices[i]));
      }

      // Init config mode stuff
      m_pwsSheet = NULL;

      m_pSignalingWizPage = NULL;
      m_pWinkDigitsWizPage = NULL;

      AffirmThrow(m_SignalingValueMap.Init(SValueMap::MAP_CT1_SIGNALING));
      AffirmThrow(m_WinkDigitsValueMap.Init(SValueMap::MAP_CT1_WINKDIGITS));

      if ((m_DS1Config.Data.signalling == 0) ||
          ((m_DS1Config.Data.signalling != CT1_LOOP_START) &&
           (m_DS1Config.Data.signalling != CT1_WINK_START) &&
           (m_DS1Config.Data.signalling != CT1_GROUND_START) &&
           (m_DS1Config.Data.signalling != CT1_IMMED_START)))
         m_DS1Config.Data.signalling = CT1_LOOP_START;

      if (m_DS1Config.Data.wink_digits > 20)
         m_DS1Config.Data.wink_digits = 4;

   }
   catch (CAffirmException ae)
   {
   }
}

CProtocolT1::~CProtocolT1()
{
   try
   {
      if (m_pSignalingWizPage != NULL) delete m_pSignalingWizPage;
      if (m_pWinkDigitsWizPage != NULL) delete m_pWinkDigitsWizPage;
   }
   catch (CAffirmException ae)
   {
   }
}

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

   try
   {
      // Currently unimplemented
      AffirmThrow(FALSE);
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CProtocolT1::AddChild(CString const & strChild)
{
   BOOL fSuccess = FALSE;

   try
   {
      INT_PTR iNewChild = m_apChildren.Add(NULL);

      // 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 service parameters reside at:
      //       ...\DigiDxb?\Parameters\XXXX\N      (where XXXX = the service name)
      //    So, pass in the hKey we were told to start at, and the XXXX\N reg path.

      CString strServiceRegPath = strChild + TEXT("\\") + m_strRegPath;
      AffirmThrow(NewConfigObject(&m_apChildren[iNewChild], CConfigObject::SERVICE, strChild, m_hKeyRoot, strServiceRegPath, this));
      AffirmThrow(m_apChildren[iNewChild] != NULL);

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

   return fSuccess;
}

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

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

   try
   {
      AffirmThrow(CProtocol::GetParameters());
      AffirmThrow(m_DS1Config.Get(m_hKey));
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

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

   try
   {
      AffirmThrow(CProtocol::SetParameters());
      AffirmThrow(m_DS1Config.Set(m_hKey));
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CProtocolT1::RemoveParameters(BOOL fRemoveKey /* = FALSE */)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(m_DS1Config.Remove(m_hKey));
      AffirmThrow(CProtocol::RemoveParameters(fRemoveKey));
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

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

   try
   {
      AffirmThrow(pFrom != NULL);
      CProtocolT1 * pFromProtocol = (CProtocolT1 *) pFrom;

      m_DS1Config = pFromProtocol->m_DS1Config;

      AffirmThrow(CProtocol::CopyParameters(pFrom));

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

   return fSuccess;
}

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

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

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

   return fSuccess;
}




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

BOOL CProtocolT1::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

      m_pwsSheet = pSheet;

      CString strTitle;
      CString strInstruction;

      if (m_pSignalingWizPage == NULL)
      {
         AffirmThrow(strTitle.LoadString(IDS_Title_Signaling));
         AffirmThrow(strInstruction.LoadString(IDS_Instruction_Signaling));
         strTitle = GetParent()->GetDisplayName() + TEXT(" - ") + strTitle;

         m_pSignalingWizPage = new CWizPageRadioButtons(this, WP_SIGNALING, strTitle, strInstruction);
         AffirmThrow(m_pSignalingWizPage != NULL);

         AffirmThrow(m_pSignalingWizPage->SetValues(m_SignalingValueMap.astrDisplayNames, m_SignalingValueMap.ToIndex(m_DS1Config.Data.signalling, 0)));
         m_pSignalingWizPage->SetHelpID(IDH_WizPageSignaling);
      }


      if (m_pWinkDigitsWizPage == NULL)
      {
         AffirmThrow(strTitle.LoadString(IDS_Title_WinkDigits));
         AffirmThrow(strInstruction.LoadString(IDS_Instruction_WinkDigits));
         strTitle = GetParent()->GetDisplayName() + TEXT(" - ") + strTitle;

         m_pWinkDigitsWizPage = new CWizPageSpin(this, WP_WINKDIGITS, strTitle, strInstruction);
         AffirmThrow(m_pWinkDigitsWizPage != NULL);

         AffirmThrow(m_pWinkDigitsWizPage->SetValues(m_WinkDigitsValueMap.nMin, m_WinkDigitsValueMap.nMax, m_DS1Config.Data.wink_digits));
         m_pWinkDigitsWizPage->SetHelpID(IDH_WizPageWinkDigits);
      }

      AffirmThrow(m_pwsSheet->InsertPage(m_pSignalingWizPage));

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

   return fSuccess;
}

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

   try
   {
      AffirmThrow(pSheet != NULL);

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

         if (m_pSignalingWizPage != NULL) m_pwsSheet->RemovePage(m_pSignalingWizPage);
         if (m_pWinkDigitsWizPage != NULL) m_pwsSheet->RemovePage(m_pWinkDigitsWizPage);
      }

      AffirmThrow(CProtocol::RemoveWizardPages(pSheet));

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

   return fSuccess;
}

BOOL CProtocolT1::HandleWizSignaling(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(m_pwsSheet != NULL);

      int iChoice = m_pSignalingWizPage->GetChoice();
      m_DS1Config.Data.signalling = m_SignalingValueMap.FromIndex(iChoice);

      if (m_DS1Config.Data.signalling == CT1_WINK_START)
      AffirmThrow(m_pwsSheet->InsertPage(m_pWinkDigitsWizPage));

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

   return fSuccess;
}

BOOL CProtocolT1::HandleWizWinkDigits(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(m_pwsSheet != NULL);

      int iChoice = m_pWinkDigitsWizPage->GetChoice();
      m_DS1Config.Data.wink_digits = m_WinkDigitsValueMap.FromIndex(iChoice);

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

   return fSuccess;
}

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

   try
   {
      switch (nState)
      {
         case WP_SIGNALING:   AffirmThrow(HandleWizSignaling());  break;
         case WP_WINKDIGITS:  AffirmThrow(HandleWizWinkDigits()); break;
         default: AffirmThrow(FALSE); break;
      }

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

   return fSuccess;
}

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

   try
   {
      CString str;

      str.Format(IDS_Information_SignalingFormat,
                 m_SignalingValueMap.DisplayNameFromValue(m_DS1Config.Data.signalling));
      strInfo += StripUnderscores(str);

      if (m_DS1Config.Data.signalling == CT1_WINK_START)
      {
         str.Format(IDS_Information_WinkDigitsFormat,
                    m_WinkDigitsValueMap.DisplayNameFromValue(m_DS1Config.Data.wink_digits));
         strInfo += str;
      }
   }
   catch (CAffirmException ae)
   {
   }

   return strInfo;
}

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

   try
   {
      CPropertySheet PropSheet(GetDisplayName());

      CPropSignaling PropSignaling;
      PropSignaling.SetStart(m_DS1Config.Data.signalling);
      PropSignaling.SetDigits(m_DS1Config.Data.wink_digits);

      PropSheet.AddPage(&PropSignaling);
      
      PropSheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
      if (PropSheet.DoModal() == IDOK)
      {
         m_DS1Config.Data.signalling = PropSignaling.GetStart();
         m_DS1Config.Data.wink_digits = PropSignaling.GetDigits();

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

   return fThingsHaveChanged;
}
