/*****************************************************************************
* Copyright (c) 2000 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
*
*****************************************************************************/

//////////////////////////////////////////////////////////////////////
//
// ProtocolE1R2.cpp: implementation of the CProtocolE1R2 class.
//
// Author: Nam Nguyen
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ProtocolE1R2.h"
#include "PropPgE1R2Ctry.h"
#include "PropPageR2Dnis.h"
#include "PropPgSignals.h"
#include "PropPgOther.h"
#include "ObjectFactory.h"

#include "Resource.h"

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

IMPLEMENT_DYNAMIC(CProtocolE1R2, CProtocol)

CProtocolE1R2::CProtocolE1R2(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_E1R2);

      // Set our display name
      CString strDisplayName;
      AffirmThrow(strDisplayName.LoadString(IDS_DisplayName_E1R2));
      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]));
      }
	
	  // Hard coded defaults

	  m_DS1Config.Data.signalling = E1_R2;
	  
	  if (m_E1R2Config.Data.r2_switch_type == 0) m_E1R2Config.Data.r2_switch_type = R2_BRAZIL;
	  if (m_E1R2Config.Data.r2_method == 0) m_E1R2Config.Data.r2_method = R2_DIGITAL_COMPELLED;
	  if (m_E1R2Config.Data.r2_cd_bits	== 0) m_E1R2Config.Data.r2_cd_bits = E1_R2_D_BIT;
      if (m_E1R2Config.Data.max_dnis_digits == 0) m_E1R2Config.Data.max_dnis_digits = 8;
	  if (m_E1R2Config.Data.min_dnis_digits	== 0) m_E1R2Config.Data.min_dnis_digits	= 0;
      if (m_E1R2Config.Data.max_ani_digits == 0) m_E1R2Config.Data.max_ani_digits = 12;
	  if (m_E1R2Config.Data.min_ani_digits == 0) m_E1R2Config.Data.min_ani_digits = 0;
	  if (m_E1R2Config.Data.send_ani_digits == 0) m_E1R2Config.Data.send_ani_digits = 0;
	  if (m_E1R2Config.Data.ani_digit_signal == 0) m_E1R2Config.Data.ani_digit_signal = MF_R2_BW_5;
      if (m_E1R2Config.Data.answer_signal == 0) m_E1R2Config.Data.answer_signal = MF_R2_BW_6;
	  if (m_E1R2Config.Data.end_dnis_signal == 0) m_E1R2Config.Data.end_dnis_signal = MF_R2_BW_5;
      if (m_E1R2Config.Data.busy_signal == 0) m_E1R2Config.Data.busy_signal = MF_R2_BW_3;
	  if (m_E1R2Config.Data.outgoing_type == 0) m_E1R2Config.Data.outgoing_type = MF_R2_NATIONAL_SUBSCRIBER;
	        
      AffirmThrow(m_E1R2SwitchValueMap.Init(SValueMap::MAP_E1R2_SWITCH));
   }
   catch (CAffirmException ae)
   {
   }
}

CProtocolE1R2::~CProtocolE1R2()
{
   try
   {
   }
   catch (CAffirmException ae)
   {
   }
}

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

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

   return fSuccess;
}

BOOL CProtocolE1R2::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 CProtocolE1R2::GetParameters(void)
{
   BOOL fSuccess = FALSE;

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

   return fSuccess;
}

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

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

   return fSuccess;
}

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

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

   return fSuccess;
}

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

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

      m_DS1Config = pFromProtocol->m_DS1Config;
	  m_DChanExtConfig = pFromProtocol->m_DChanExtConfig;
      m_E1R2Config = pFromProtocol->m_E1R2Config;

      AffirmThrow(CProtocol::CopyParameters(pFrom));

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

   return fSuccess;
}

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

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

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

   return fSuccess;
}


//////////////////////////////////////////////////////////////////////
// UI config methods
//////////////////////////////////////////////////////////////////////
BOOL CProtocolE1R2::AddWizardPages(CConfigWizSheet * const pSheet)
{
	return TRUE;
}

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

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

   return fSuccess;
}

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

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

   return fSuccess;
}

CString CProtocolE1R2::GetInformationText(void)
{
   CString strInfo = TEXT("");
   
   try
   {
      CString str;

      // R2 Switch Type - country or switch type defining R2 implementation
	  AffirmThrow(m_R2SwitchTypeValueMap.Init(SValueMap::MAP_E1R2_R2SWITCHTYPE));
	  str.Format(IDS_Information_R2SwitchTypeFormat,
                 m_R2SwitchTypeValueMap.DisplayNameFromValue(m_E1R2Config.Data.r2_switch_type));
      strInfo += str;

	  // Outgoing Type - what supplier ident we supply on dial-out
	  AffirmThrow(m_OutTypeMap.Init(SValueMap::MAP_E1R2_OUTGOINGTYPE));
      str.Format(IDS_Information_R2OutgoingTypeFormat,
                 m_OutTypeMap.DisplayNameFromValue(m_E1R2Config.Data.outgoing_type));
      strInfo += str;
   }   

   catch (CAffirmException ae)
   {
   }

   return strInfo;
}

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

   try
   {
      CPropertySheet PropSheet(GetDisplayName());

	  CPropPgE1R2Ctry PropR2Ctry;
	  PropR2Ctry.SetE1R2Ctry(m_E1R2Config.Data.r2_switch_type);

	  PropSheet.AddPage(&PropR2Ctry);

      CPropPageR2Dnis PropDnis;
      PropDnis.SetMinDnis(m_E1R2Config.Data.min_dnis_digits);
      PropDnis.SetMaxDnis(m_E1R2Config.Data.max_dnis_digits);
	  PropDnis.SetMinAni(m_E1R2Config.Data.min_ani_digits);
      PropDnis.SetMaxAni(m_E1R2Config.Data.max_ani_digits);
      PropDnis.SetSendANI(m_E1R2Config.Data.send_ani_digits);

	  PropSheet.AddPage(&PropDnis);

	  CPropPgSignals PropSignals;
      PropSignals.SetAniSig(m_E1R2Config.Data.ani_digit_signal);
      PropSignals.SetAnsSig(m_E1R2Config.Data.answer_signal);
	  PropSignals.SetEndDNIS(m_E1R2Config.Data.end_dnis_signal);
      PropSignals.SetBusySig(m_E1R2Config.Data.busy_signal);

	  PropSheet.AddPage(&PropSignals);

	  CPropPgOther PropOther;
      PropOther.SetCBit(m_E1R2Config.Data.r2_cd_bits);
	  PropOther.SetDBit(m_E1R2Config.Data.r2_cd_bits);
	  PropOther.SetGroup2Type(m_E1R2Config.Data.outgoing_type);
      
	  PropSheet.AddPage(&PropOther);

      PropSheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
      if (PropSheet.DoModal() == IDOK)
      {
         m_E1R2Config.Data.r2_switch_type = PropR2Ctry.GetE1R2Ctry();

		 m_E1R2Config.Data.min_dnis_digits = PropDnis.GetMinDnis();
         m_E1R2Config.Data.max_dnis_digits = PropDnis.GetMaxDnis();
		 m_E1R2Config.Data.min_ani_digits = PropDnis.GetMinAni();
         m_E1R2Config.Data.max_ani_digits = PropDnis.GetMaxAni();
		 m_E1R2Config.Data.send_ani_digits = PropDnis.GetSendANI();

		 m_E1R2Config.Data.ani_digit_signal = PropSignals.GetAniSig();
		 m_E1R2Config.Data.answer_signal = PropSignals.GetAnsSig();
		 m_E1R2Config.Data.end_dnis_signal = PropSignals.GetEndDNIS();
		 m_E1R2Config.Data.busy_signal = PropSignals.GetBusySig();

		 m_E1R2Config.Data.outgoing_type = PropOther.GetGroup2Type();
		 m_E1R2Config.Data.r2_cd_bits = PropOther.GetCBit();
		 m_E1R2Config.Data.r2_cd_bits = PropOther.GetDBit();

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

   return fThingsHaveChanged;
}