////////////////////////////////////////////////////////////////////////////////
//
//      
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"

#include "resource.h"

#ifndef __CPAR_H
#include "CPar.h"
#endif

#include <COMUTIL.H>
#include <comdef.h>


#ifndef _APROPUSEREVENT_H
#include "aPropUserEvent.h"
#endif


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

extern AFX_MODULE_STATE* pModuleState;

IApplicationPtr newKompasAPI( NULL );


//------------------------------------------------------------------------------
//  
// ---
int LibMessage( LPCTSTR str, int flags ) {
  int res = 0;

  if ( str && str[0] )                    //      
  {                  
    int enabse = ::IsEnableTaskAccess();  //  
    if ( enabse )                         //     
      ::EnableTaskAccess(0);              //  

    //                                      
    res = MessageBox( (HWND) GetHWindow(), str, LoadStr(ID_LIBID), flags );

    if ( enabse )                         //      
      ::EnableTaskAccess(1);              //    
  }

  return res;
}


//------------------------------------------------------------------------------
//  
// ---
int LibMessage( int strId, int flags ) 
{
  return ::LibMessage( LoadStr(strId), flags );
}


//------------------------------------------------------------------------------
//  ,    
// ---
void DumpError( _com_error & e )
{
	CString str;
	str.Format( LoadStr(IDS_COM_ERROR), e.Error(),
	                                    e.ErrorMessage(),
	                                    e.Source(),
	                                    e.Description() );
	LibMessage( str, MB_OK | MB_ICONERROR);	
}


/*
//------------------------------------------------------------------------------
//  ,    
// ---
void ShowError()
{
  IErrorInfoPtr ef;
  GetErrorInfo( NULL, &ef );
  BSTR                bstrDescription;
  ef->GetDescription( &bstrDescription );
  USES_CONVERSION;
  LibMessage( OLE2T(bstrDescription), MB_OK | MB_ICONERROR );
}
*/

//-------------------------------------------------------------------------------
//     API
// ---
void GetNewKompasAPI() {
	if ( !( IApplication* )newKompasAPI ) {
		CString filename;
		if( ::GetModuleFileName(NULL, filename.GetBuffer(255), 255) ) {
			filename.ReleaseBuffer( 255 );
			CString libname;

      #ifdef __LIGHT_VERSION__
        libname = LoadStr( IDS_API7LT );  // klAPI7.dll
      #else
        libname = LoadStr( IDS_API7 );    // kAPI7.dll
      #endif

			filename.Replace( filename.Right(filename.GetLength() - (filename.ReverseFind('\\') + 1)), 
												libname );

			HINSTANCE hAppAuto = LoadLibrary( filename ); //  kAPI7.dll
			if(  hAppAuto ) {
				//      KompasApplication  
        typedef LPDISPATCH ( WINAPI *FCreateKompasApplication )(); 
				 
        FCreateKompasApplication pCreateKompasApplication = 
					(FCreateKompasApplication)GetProcAddress( hAppAuto, "CreateKompasApplication" );	
				if ( pCreateKompasApplication )
					newKompasAPI = IDispatchPtr( pCreateKompasApplication(), false/*AddRef*/ ); //   Application
				FreeLibrary( hAppAuto );  
			}
		}
	}
}

//-------------------------------------------------------------------------------
//  Application
// ---
void App7NULL() {
  ABaseEvent::DestroyList(); //   
  if ( newKompasAPI )
    newKompasAPI = NULL;     //  
}

//----------------------------------------------------------------------------------------------
// 
// ---
PropertyManagerObject::PropertyManagerObject() :
  procParam        (NULL),  //  
  propTabs         (NULL),  //  
  curentCollection (NULL),  //   
  hatchCtrl        (NULL),  //  -  
  paramGrid        (NULL),  //       
  slideBox         (NULL),  //   
  rowIndex         (0)      //  
  , posLiaderParam ( NULL  )
  , flagMode       ( 0     )
{ 
}     

//----------------------------------------------------------------------------------------------
// 
// ---
PropertyManagerObject::~PropertyManagerObject() 
{  
  hatchCtrl        = NULL;  //  -  
  paramGrid        = NULL;  //       
  slideBox         = NULL;  //   
  curentCollection = NULL;  //   
  propTabs         = NULL;  //  
  procParam        = NULL;  //  
  posLiaderParam   = NULL;
  rowIndex         =    0;  //  
}     

//----------------------------------------------------------------------------------------------
//   
// ---
bool PropertyManagerObject::InitProcessParam( long toolBarID, SpecPropertyToolBarEnum toolBarType, long firstTabID ) 
{
  bool res = false;
  GetNewKompasAPI();                                                  //   Api  
  if ( newKompasAPI ){
    try {
      
      procParam = newKompasAPI->CreateProcessParam();                 // newKompasAPI->CreateProcessParam();                 //   
      if ( procParam ) {
        new PropertyManagerEvent( procParam, *this );                 //     
        //    
        procParam->SpecToolbar = toolBarType;                         //       
        _bstr_t tmpBstr( LoadStr( toolBarID ) );
        procParam->Caption    = tmpBstr;                              //     
        procParam->AutoReduce = !flagMode;                            //  

        if ( flagMode ) {
          procParam->DefaultControlFix = ksAllFix;
        }

        //     
        propTabs = procParam->PropertyTabs;                       

        //    
        if ( firstTabID ) {
          CreateTab( firstTabID, TRUE, TRUE );
          //       
          ShowControls();                                               
          //   
          //     
          reference gr = GetPreviewGroup();
          if ( gr ) { 
            slideBox = curentCollection->Add( ksControlSlideBox );            
            slideBox->SlideType      = ksGroup;                       //  
            slideBox->DrawingSlide   = _variant_t(gr);                //  reference  
            slideBox->Hint           = "Hint  ";
            slideBox->Tips           = "Tips  ";
            slideBox->Id             = 10000;
            slideBox->Name           = " ";
            slideBox->NameVisibility = ksNameHorizontalVisible;
          }
        }
        
        int  paramCount = ParamCount();                               //     ?
        if ( paramCount || IsHatchObject() ) {
          CreateTab( IDP_ELEMENT_PARAM );                             //        
          if ( IsHatchObject() ) {
            ShowHatchControl();
          }

          if ( paramCount ) {
            //  
            paramGrid = curentCollection->Add( ksControlGrid );
            if ( paramGrid ) {
              paramGrid->ColumnCount      = 2;                        //   
              paramGrid->FixedColumnCount = 1;                        //     
              paramGrid->FixedRowCount    = 1;                        //  
              paramGrid->RowCount         = paramCount + 1;           //     
              paramGrid->AutoSizeColumns  = TRUE;                     //    
              paramGrid->Hint             = "Hint  ";
              paramGrid->Tips             = "Tips  ";
              paramGrid->Id               = 10001;
              paramGrid->Name             = " ";
              paramGrid->NameVisibility   = ksNameHorizontalVisible;
                //  
              rowIndex = 0;                                           //   
              AddStringToGrig( IDS_PARAM_CAPTION, LoadStr(IDS_VALUE_CAPTION) );
              ShowParam();                                            //    
              paramGrid->Height = rowIndex  * 20;
              paramGrid->RowCount         = rowIndex;                 
            }
          }
        }

        res = true;
      }
    }

    //  
    catch(_com_error &e)
    {
		  DumpError(e);                            //    
    }
    
    catch( TCHAR* mes ) {
      LibMessage( mes, MB_ICONERROR | MB_OK ); //    
    }
    
  }
  return res;
}

//-------------------------------------------------------------------------------
//    
//     
// ---
bool PropertyManagerObject::InitPosLeaderParam() 
{
  bool res = posLiaderParam != NULL;
  //        
  if ( newKompasAPI != NULL && posLiaderParam == NULL ) {
    try {
      
      posLiaderParam = newKompasAPI->CreateProcessParam();                 // newKompasAPI->CreateProcessParam();                 //   
      if ( posLiaderParam ) {
        new PropertyManagerEvent( posLiaderParam, *this );                 //     

        //     
        IPropertyTabsPtr liaderPropTabs = posLiaderParam->PropertyTabs;
        if ( liaderPropTabs ) {
          _bstr_t tmpBstr( LoadStr(IDP_POS_LEADER) ); 

          IPropertyTabPtr propTab = liaderPropTabs->Add( tmpBstr );
          if ( propTab ) {

            IPropertyControlsPtr ctrlCollection = propTab->PropertyControls;
            if ( ctrlCollection ) {

              IPropertyMultiButtonPtr buttons( ctrlCollection->Add(ksControlMultiButton) );
              if ( buttons ) {
                InitPropertyControl( buttons, ID_LEADER_CREATE, IDS_LEADER_HINT/*hint*/, IDS_LEADER_TIPS/*tips*/ );
                buttons->ButtonsType = ksPushButton;
                buttons->ResModule   = _variant_t( (long)StepDLL.hModule );
              }
            }
          }
        }

        res = true;
      }
    }

    //  
    catch(_com_error &e)
    {
		  DumpError(e);                            //    
    }
    
    catch( TCHAR* mes ) {
      LibMessage( mes, MB_ICONERROR | MB_OK ); //    
    }
  }
//     CreateTab( ID_POS_LEADER );
//     IPropertyMultiButtonPtr simpleButtons( CreateMultiButton( ksPushButton, IDP_LEADER_BUTTONS ), false /*AddRef*/ // );
//      // 
//      AddButton( simpleButtons, ID_LEADER_CREATE );
//     }   
  return res;
}

//----------------------------------------------------------------------------------------------
//    
// ---
void PropertyManagerObject::AddStringToGrig( long paramID, LPCTSTR value ) {
  if ( paramGrid ) {
    paramGrid->CellText[ rowIndex   ][ 1 ] = _bstr_t(value);
    paramGrid->CellText[ rowIndex++ ][ 0 ] = _bstr_t(LoadStr(paramID)); //    
  }
}  

//----------------------------------------------------------------------------------------------
//    
// ---
const char* DoubleToStr( double value ) 
{
  static char res[20];
  sprintf( res, "%g", value );
  return res;
}
  
//----------------------------------------------------------------------------------------------
//    
// ---
void PropertyManagerObject::AddDoubleToGrig( long paramID, double value ) {
  if ( paramGrid ) {
    paramGrid->CellText[ rowIndex   ][ 1 ] = _bstr_t( DoubleToStr(value) );  //  
    paramGrid->CellText[ rowIndex++ ][ 0 ] = _bstr_t( LoadStr(paramID)   );  //  
  }
}  

//----------------------------------------------------------------------------------------------
//  
// ---
bool PropertyManagerObject::CreateTab( long tabID, BOOL visible, BOOL active ) 
{
  bool res = false;
  if ( tabID ) { 
    if ( propTabs ) {
                          
      _bstr_t tmpBstr( LoadStr(tabID) ); 
      IPropertyTabPtr propTab = propTabs->Add( tmpBstr );
      if ( propTab ) {
        curentCollection   = propTab->PropertyControls;
        if ( !visible )
          propTab->Visible = visible;
        propTab->Active    = active;
        res = true;
      }
    }
  }
  return res;
}

//----------------------------------------------------------------------------------------------
//  
// ---
void  PropertyManagerObject::InitPropertyControl( IPropertyControl* control, long ctrlID, UINT hint, UINT tips, 
                                                  BOOL enable, PropertyControlNameVisibility nameVisibility, 
                                                  BOOL visible ) {
  if ( control ) {
    _bstr_t tmpBstr( LoadStr(ctrlID) ); 
    control->Name           = tmpBstr;
    control->Id             = ctrlID;
    tmpBstr = hint ? LoadStr(hint) : _T(""); 
    control->Hint           = tmpBstr;
    tmpBstr = tips ? LoadStr(tips) : _T(""); 
    control->Tips           = tmpBstr;
    control->Enable         = enable;
    control->Visible        = visible;
    control->NameVisibility = nameVisibility;
  }
}

//----------------------------------------------------------------------------------------------
//  
// ---
IPropertyListPtr PropertyManagerObject::CreateList( double minVal, double maxVal )
{

  IPropertyListPtr realList( NULL );
  if ( curentCollection ) {
    realList = curentCollection->Add( ksControlListReal );
    if ( realList ) {
      if ( minVal != maxVal )
        realList->SetValueRange( _variant_t(minVal), _variant_t(maxVal) );
        realList->ReadOnly = TRUE;
    }
  }

  return realList;
}

//----------------------------------------------------------------------------------------------
//  
// ---
IPropertySeparatorPtr PropertyManagerObject::CreateSeparator( SeparatorTypeEnum type ) {
  IPropertySeparatorPtr rSepar( NULL );
  if ( curentCollection ) {
    rSepar = curentCollection->Add( ksControlSeparator );
    if ( rSepar ) {
      rSepar->SeparatorType = type;
    }
  }
  return rSepar;
}

//----------------------------------------------------------------------------------------------
//  CheckBox- 
// ---
IPropertyCheckBoxPtr PropertyManagerObject::CreateCheckBox( bool checked ) {
  IPropertyCheckBoxPtr check( NULL );
  if ( curentCollection ) {
    check = curentCollection->Add( ksControlCheckBox );
    if ( check ) {
      check->Value = _variant_t( checked );
    }
  }
  return check;
}

//----------------------------------------------------------------------------------------------
//   
// ---
IPropertyMultiButtonPtr PropertyManagerObject::CreateMultiButton( ButtonTypeEnum type )
{
  IPropertyMultiButtonPtr buttons( NULL );
  if ( curentCollection ) {
    buttons = curentCollection->Add( ksControlMultiButton );
    if ( buttons ) {
      buttons->ButtonsType = type;
      buttons->ResModule   = _variant_t( (long)StepDLL.hModule );
    }
  }
  return buttons;
}

//----------------------------------------------------------------------------------------------
//    
// ---
void
PropertyManagerObject::AddButton( IPropertyMultiButtonPtr& buttons, long btnID, bool cheched, bool enable )
{
  AddButton2( buttons, btnID, btnID, cheched, enable );
}

//----------------------------------------------------------------------------------------------
//    
// ---
void
PropertyManagerObject::AddButton2( IPropertyMultiButtonPtr& buttons, long btnID, long bmpID, bool cheched, bool enable )
{
  if ( buttons ) {
    buttons->AddButton( btnID, _variant_t(bmpID), -1 );
    buttons->ButtonEnable [ btnID ] = enable;
    buttons->ButtonChecked[ btnID ] = cheched;
    _bstr_t tmpBstr( LoadStr(btnID) ); 
//           buttons->ButtonHint   [ btnID ] = tmpBstr;
    buttons->ButtonTips   [ btnID ] = tmpBstr;
  }
}

//----------------------------------------------------------------------------------------------
//    
// ---
void PropertyManagerObject::EndProcess() {
  ABaseEvent::TerminateEvents();
}

//----------------------------------------------------------------------------------------------
//  
// ---
IPropertyControlPtr PropertyManagerObject::GetPropertyControl( int ctrlID ) {
  IPropertyControlPtr control(NULL);
  if ( propTabs ) {
    for ( long i = 0, c = propTabs->Count; i < c && control == NULL; i++ ) {
      IPropertyTabPtr tab( propTabs->Item[ _variant_t(i) ] );
      IPropertyControlsPtr ctrls( tab ? tab->PropertyControls : NULL );
      if ( ctrls ) {
        _bstr_t name( LoadStr(ctrlID) );
        control = ctrls->Item[ _variant_t(name) ];
      }
    }
  }
  return control;
}

//----------------------------------------------------------------------------------------------
//   
// ---
void PropertyManagerObject::SetControlEnable( long ctrlID, bool enabled ) {
  IPropertyControlPtr control( GetPropertyControl(ctrlID) );
  if ( control ) 
    control->Enable = enabled;
}

/*
//----------------------------------------------------------------------------------------------
//   
// ---
void PropertyManagerObject::SetTabVisible( long tabID, bool visible ) {
  IPropertyTabPtr tab = propTabs->Item[ _variant_t(LoadStr(tabID)) ];
  if ( tab ) 
    tab->Visible = visible;
}
*/

//----------------------------------------------------------------------------------------------
//   
// ---
IPropertyUserControlPtr PropertyManagerObject::CreateUserControl( long ctrlID, long height, long width ) {
  IPropertyUserControlPtr userCtrl( NULL );
  if ( curentCollection ) {
    userCtrl = curentCollection->Add( ksControlUser );
    if ( userCtrl ) {
      userCtrl->NameVisibility = ksNameHorizontalVisible;
      _bstr_t conrolID( LoadStr(ctrlID+2000) );
      userCtrl->SetOCXControl(conrolID);
      userCtrl->Name   = LoadStr(ctrlID+2001); 
      userCtrl->Height = height;
      userCtrl->Width  = width; 
      userCtrl->Id     = ctrlID;
      new APropertyUserControlEvent( userCtrl, ctrlID, *this );
    }
  }
  return userCtrl;
}

//-------------------------------------------------------------------------------
//  ,   
// ---
void PropertyManagerObject::OnDestroyOCX( long ctrlID/*, LPDISPATCH control*/ ) {
  if ( ctrlID == IDP_HATCH_PARAM )
    hatchCtrl = NULL;
}

////////////////////////////////////////////////////////////////////////////////
//
// PropertyManagerEvent -    
//
////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------
//
// ---
PropertyManagerEvent::PropertyManagerEvent( LPDISPATCH manager, PropertyManagerObject& _obj ):
  ABaseEvent( manager, DIID_ksPropertyManagerNotify )
  , obj( _obj )
{
  Advise();
}


//-------------------------------------------------------------------------------
//
// ---
PropertyManagerEvent::~PropertyManagerEvent()
{
}

//-------------------------------------------------------------------------------
//  
// ---
BEGIN_EVENTSINK_MAP(PropertyManagerEvent, ABaseEvent)
  // 1 - prButtonClick        -  .
  ON_EVENT (PropertyManagerEvent, (unsigned int)-1,  prButtonClick,        ButtonClick,        VTS_I4 )
  // 2 - prChangeControlValue -    
  ON_EVENT (PropertyManagerEvent, (unsigned int)-1,  prChangeControlValue, ChangeControlValue, VTS_DISPATCH )
  // 3 - prControlCommand     -   
  ON_EVENT (PropertyManagerEvent, (unsigned int)-1,  prControlCommand,     ControlCommand,     VTS_DISPATCH VTS_I4 )
  // 4 - prButtonUpdate       -    
  ON_EVENT (PropertyManagerEvent, (unsigned int)-1, prButtonUpdate,        ButtonUpdate,       VTS_I4 VTS_PI4 VTS_PBOOL )
  // 5 - prProcessActivate    -  
  ON_EVENT (PropertyManagerEvent, (unsigned int)-1, prProcessActivate,     ProcessActivate,    VTS_NONE )  
  // 6 - prProcessDeactivate  -  
  ON_EVENT (PropertyManagerEvent, (unsigned int)-1, prProcessDeactivate,   ProcessDeactivate,  VTS_NONE )  
  // 7 - prCommandHelp -  
  ON_EVENT ( PropertyManagerEvent, (unsigned int)-1, prCommandHelp,        CommandHelp,        VTS_I4  )


END_EVENTSINK_MAP()

//-----------------------------------------------------------------------------
// prChangeControlValue -     
// ---
afx_msg BOOL PropertyManagerEvent::ChangeControlValue(LPDISPATCH  iCtrl)
{
  IPropertyControlPtr control( iCtrl );
  if ( control ) {
    _variant_t v      = control->Value;
    long       ctrlID = control->Id;
    if ( obj.OnChangeControlValue(ctrlID, v) ) {
      obj.RedrawPhantom();  
    }
  }
  return TRUE;
}

//-------------------------------------------------------------------------------
//   
// ---
void OpenHelp( int Id ) 
{
  TCHAR gaykaHlp[260] = _T("");
  if ( GetFullName( LIB_HELP, gaykaHlp, 260 ) )
    ksOpenHelpFileT( gaykaHlp, HELP_CONTEXT,  Id );
}


//-----------------------------------------------------------------------------
// prChangeControlValue -     
// ---
afx_msg BOOL PropertyManagerEvent::ButtonClick(long buttonID)
{
  if ( buttonID == pbHelp ) 
    OpenHelp( 1 );
//  else
//    if ( obj.OnButtonClick( buttonID ) ) 
//      obj.RedrawPhantom();  
  return TRUE;
}

//-----------------------------------------------------------------------------
// prControlCommand   
// ---
afx_msg BOOL PropertyManagerEvent::ControlCommand(LPDISPATCH ctrl, long buttonID ) {
//	METHOD_PROLOGUE_EX_(PropertyManagerEvent, PropertyManagerNotify)
//  IPropertyRealEditPtr rEdit (ctrl);
//  if(rEdit) {
//    CheckStateEnum  s;
//    rEdit->get_CheckState(&s);
//    rEdit->put_CheckState( s != ksCheckCurrent ? ksCheckCurrent :ksCheckFixed );
//  }
//  else
  if ( obj.OnButtonClick(buttonID) ) {
    obj.RedrawPhantom();  
  }
  return TRUE;
}


//-----------------------------------------------------------------------------
// prButtonUpdate        -    .
// ---
afx_msg BOOL PropertyManagerEvent::ButtonUpdate( long buttonID, long* check, VARIANT_BOOL* _enable) {
  return TRUE;
}

//-----------------------------------------------------------------------------
// prProcessActibate     -  .
// ---
afx_msg BOOL PropertyManagerEvent::ProcessActivate() {
  return TRUE;
}

//-----------------------------------------------------------------------------
// prProcessDeactivate   -  .
// ---
afx_msg BOOL PropertyManagerEvent::ProcessDeactivate() {
  return TRUE;
}


afx_msg BOOL PropertyManagerEvent::CommandHelp( long buttonID )
{
  OpenHelp( 1 ); // buttonID );
  return TRUE;
}


