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


#ifndef __LIBHPPAR_H
#include <Libhppar.h>
#endif 

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

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

CPar * obj    = NULL;
bool   repeat = false;               //      
                                     // Placement  Cursor

reference oldPosLeader = 0;  
reference posLeater    = 0;          // 0 -   , -1 -    

struct Phantom         rub;          //  
extern IApplicationPtr newKompasAPI; //    


//-------------------------------------------------------------------------------------
//   
//---
BaseMacroParam::BaseMacroParam() 
{ 
  memset( &version, 0, sizeof(BaseMacroParam) ); 
  drawType = ID_VIEW; 
}


//-------------------------------------------------------------------------------------
// 
//---
CPar::CPar( unsigned int _command, reference _ref ) 
  : PropertyManagerObject(),
    //objError( false ), // true -     (      )
    command   ( _command ),
    refMacr   ( _ref     ),
    x         ( 0        ),
    y         ( 0        ),
    angle     ( 0        ),
    changed   ( true     ),
    spcObject ( 0        ) 
{
  if ( _ref ) 
  {
    flagMode = true;
    GetMacroPlacement( _ref, &x, &y, &angle );
  }
  else
    m_baseParam.version = GetVersion();
}


//-------------------------------------------------------------------------------------
//    
//---
void CPar::_MessageBoxResult() 
{
  long res = ReturnResult();  
  if ( res ) 
  {
    if ( res != etError10 ) //  10  "!  "
      MessageBoxResult();
    ResultNULL();
  }
}


//-------------------------------------------------------------------------------------
//  
//---
void CPar::Assign( const CPar &other ) 
{
  command     = other.command;
  refMacr     = other.refMacr;
  flagMode    = other.flagMode;
//  objError    = other.objError;
  angle       = other.angle; 
  m_baseParam = other.m_baseParam;
}


//-------------------------------------------------------------------------------------
//   
//---
bool CPar::DrawSpcObj( reference _group ) 
{
  spcObject = 0; 
  if( m_baseParam.flags.flagAttr && IsSpcObjCreate() ) 
  {
    _MessageBoxResult();
    spcObject = EditSpcObj( _group );
  }
  return !!spcObject;
}


//-------------------------------------------------------------------------------------
//      
//---
int WINAPI CPar::CallBackP ( int           com,                          //  
                             double      * x, double * y, double * angl, //  
                             RequestInfo * info,                         //  
                             void        * phantom,                      // 
                             int           dynamic )                     //   
{
  Phantom * rub = (Phantom *)phantom;
  if( !dynamic ) 
  {                                                            // 
    switch ( com ) 
    {
      case -1:                                                 //   
//        obj->angle = (float)*angl;
        obj->SetParam(/* obj->refMacr*/ );                     //  
        ::SetMacroPlacement( obj->refMacr, *x, *y, *angl, 0 ); //       Placement
        StoreTmpGroup( rub->type1.gr );                        //  
        repeat = obj->DrawSpcObj( rub->type1.gr );             //   
        ClearGroup( rub->type1.gr );                           //  

        if ( repeat || obj->flagMode ) 
          return 0;                                            //   
        break;
    }
    obj->DrawGroup ( rub->type1.gr );                          //  
  }
//  else {
//    obj->angle = *angl;
//    obj->RedrawPhantom();
//  }
  return 1;
}


//----------------------------------------------------------------------------------------------
//    
//---
char * _LoadString( int ID ) 
{
  static char buf[255];
  ksConvertLangStrEx( StepDLL.hModule, ID, buf, 255 );
  return buf;
}


//-------------------------------------------------------------------------------------
//  , ,     
//---
void CPar::RedrawPhantom() 
{
  if ( Changed() ) 
  {
    DrawGroup ( rub.type1.gr );
    ksChangeObjectInLibRequest( 0, &rub );
    //  
    if ( paramGrid ) 
    {
      rowIndex = 1;
      ShowParam();
      paramGrid->RowCount = rowIndex;
      paramGrid->UpdateParam();
    }
    //    
    if ( slideBox ) 
    {
      //   
      reference gr = (long) slideBox->DrawingSlide;
      if ( gr ) 
        DeleteObj( gr );
      //  
      gr = GetPreviewGroup();
      slideBox->DrawingSlide = _variant_t(gr);
      slideBox->UpdateParam();
    }
  }
}


//-------------------------------------------------------------------------------------
//  
//---
void CPar::Draw1() 
{
     
  int j           = 1;            //   

  memset( &rub, 0, sizeof(rub) ); //  
  rub.type1.scale = 1;            //    
  rub.phType      = 1;            //  - 
  
  if ( !ReturnResult() )          //   
  {    
    flagMode = EditMacroMode();   // != 0 - m    
    obj = this;                   //   

    if ( OpenBase() )             //  
    {
      //   
      if ( InitProcessParam( command + 4000, pnEnterEscHelp, command + 4000 ) ) 
      { 
        
        while ( j ) 
        {
          
          repeat        = false;
          rub.type1.ang = angle;                 //   

          DrawGroup( rub.type1.gr );             //  
          
          //  
          RequestInfo info;                      
          memset(&info, 0, sizeof(info) );
          info.dynamic = 1;                             // 1 -  
          info.prompt  = (char*)GetPromptID();          // 
          info.callBack = &CallBackP;                   //   
          
          //     
          j = !!PlacementEx( &info, &x, &y,             
                             &rub.type1.ang,
                             &rub,
                             procParam );
          
          //   
          if ( m_baseParam.flags.flagAttr && spcObject ) 
          {
            if ( ksEditWindowSpcObject( spcObject ) )
              DrawPosLeader();                         //      
            spcObject = 0;
          }

          if ( flagMode )
            j = 0;
          else
            if ( repeat )                //      
            {              
              j = 1;
              DrawGroup( rub.type1.gr ); //   
            }
        }
      }
      EndProcess();                    //  
      CloseBase();                     //  
    }
  }
}


//-------------------------------------------------------------------------------------
//  
//---
void CPar::DrawGroup( reference & gr ) 
{
  if ( ::ExistObj(gr) )  //    
    ::DeleteObj( gr );  //  
    
  gr = ::NewGroup( 1/*  */ ); //   
  refMacr = 0;
  ::Macro( 0 );

  GetGroup();                                   //  -
  if ( !refMacr )
   refMacr = ::EndObj();

  ::EndGroup();                                 //  
  _MessageBoxResult();
  changed = false;
}


//-------------------------------------------------------------------------------------
//     
//---
reference CPar::GetPreviewGroup() 
{
  reference gr = ::NewGroup( 1/*  */ ); //   
    RedrawPreview();
//    GetGroup();
  ::EndGroup(); //  
  return gr;
}

// HOT_POINTS ##################################################################

//-------------------------------------------------------------------------------------
//     
//---
bool CPar::SetHotPoint( HotPointDescription * point, int index )
{
  switch ( index ) 
  {
    case 0 : //   
    {
      SetPlacement( point->x, point->y, 0.0 );
      break;
    }
    
    case 1 : //    
    {
      double angle = ::Angle( 0, 0, point->x, point->y );
      SetPlacement( 0, 0, angle );
      break;
    }
  }

  return index < 2;
}

// HOT_POINTS ##################################################################


//-------------------------------------------------------------------------------
//  
// ---
void CPar::SetParam()
{
  if ( refMacr ) 
  {
    m_baseParam.version = GetVersion();
    ksSetMacroParam( refMacr, *this, Size(), 0, 0, command, MP_HOTPOINTS );
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void CPar::SetPlacement( double x, double y, double ang )
{
  if ( refMacr ) 
    SetMacroPlacement( refMacr, x, y, ang, 1 );
}


//------------------------------------------------------------------------------
//  
//
reference CPar::EditSpcObj( reference _group ) 
{
  spcObject = 0;
  if ( flagMode ) 
  {
    spcObject = ::ksGetSpcObjForGeomWithLimit( NULL,             //   
                                               0,                //   
                                               _group,
                                               0,                                                       // 1 -      ; 0-    
                                               1,                                                       // 1 -  0-  
                                               STANDART_SECTION, //  
                                               AttrNumber()      //  
                                             );
    if( !m_baseParam.flags.flagAttr )
      return spcObject;

    if( spcObject && !::ksSpcObjectEdit(spcObject) ) //   
      spcObject = 0;

  }

  //  
  if ( spcObject || ::ksSpcObjectCreate( NULL,       //   
                                   0,                //   
                                   STANDART_SECTION,
                                   0,                //    
                                    AttrNumber(),    //   
                                   0) ) 
  {                                                          
    _EditSpcObj();                                   //   

    if( _group )                                     //  
      ::ksSpcIncludeReference( _group, 1 );

    spcObject = ::ksSpcObjectEnd();                  //   
  }
  return spcObject;
}


//------------------------------------------------------------------------------
//   
// ---
void CPar::CloseBase( reference bd ) 
{
  DeleteDB( bd );
}


//------------------------------------------------------------------------------
//   
// ---
void CPar::CloseBase() 
{
  if ( base.bg ) 
    CloseBase( base.bg );
}


//-------------------------------------------------------------------------------
//   
// ---
void CPar::ShowControls() 
{
  //   
  if ( IsSpcObjCreate() ) 
  {
    IPropertyCheckBoxPtr checkBox( CreateCheckBox(m_baseParam.flags.flagAttr) );
    if ( checkBox ) 
      InitPropertyControl( checkBox, IDP_SPC_OBJ, IDS_SPC_OBJ_TIPS/*hint*/, IDS_SPC_OBJ_TIPS/*tips*/ );
  }
}


//-------------------------------------------------------------------------------
//    
// ---
void CPar::ShowHatchControl() 
{
  if ( IsHatchObject() ) 
  {
//    CreateTab( IDP_HATCH_PAGE );
//    CreateSeparator( 0, ksSeparatorDownName );

//    bool hEnable = HatchEnable(); 
    CreateUserControl( IDP_HATCH_PARAM, 100, 150 );
//    CreateRealEdit( IDP_HATCHANG_ANGLE, HatchAngle(), -360, 360, hEnable );
//    CreateRealEdit( IDP_HATCHANG_STEP, HatchStep(), 0.01, 100, hEnable );
  }
}


//-------------------------------------------------------------------------------
//     
// ---
void CPar::SetHatchControlEnable( bool enable ) 
{
//  SetControlEnable( IDP_HATCH_PARAM,  enable ); 
  if ( hatchCtrl ) 
    hatchCtrl->Enable = enable; 
}


//-------------------------------------------------------------------------------
//   ActiveX Control-a
// ---
void CPar::OnCreateOCX( long ctrlID, LPDISPATCH control )
{
  if ( ctrlID == IDP_HATCH_PARAM )              //  
  { 
    hatchCtrl = control;
    if ( hatchCtrl ) 
    {
      hatchCtrl->Angle = HatchAngle();          // 
      hatchCtrl->Step  = HatchStep();           //   
      SetHatchControlEnable( HatchEnable() );   //  
    }
  }
}


//-------------------------------------------------------------------------------
//    
// ---
bool CPar::OnChangeControlValue( /*IPropertyControl* cntrl,*/ long ctrlID, const VARIANT & newVal ) 
{
  switch ( ctrlID ) 
  {
/*    case IDP_HATCHANG_ANGLE: 
      SetHatchAngle( newVal.dblVal );
      changed = true;
      break;
    case IDP_HATCHANG_STEP:
      SetHatchStep( newVal.dblVal );
      changed = true;
      break;
  }
*/
    case IDP_SPC_OBJ:
      m_baseParam.flags.flagAttr = !m_baseParam.flags.flagAttr;
      break;
  }
  return changed;  
} 


//---------------------------------------------------------------------------------------------------- 
//   
// ---
bool CPar::OnButtonClick( long buttonID ) 
{ 
  bool res    = false;
  bool oldSec = HatchEnable(); //   
  switch ( buttonID ) 
  { 
    // 
    case ID_VIEW    : //  
    case ID_LEFT    : // C 
    case ID_TOP     : // C
    case ID_SEC     : // /  
      m_baseParam.drawType = (short)buttonID;
      res = true;
      break;

    case ID_SIMPLE  : // 
      m_baseParam.flags.flagSimp = !m_baseParam.flags.flagSimp;
      res = true;
      break;

    case ID_AXIS    : //  
      m_baseParam.flags.flagAxis = !m_baseParam.flags.flagAxis;
      res = true;
      break;

    case ID_LEADER_CREATE: //    
    {
      if ( newKompasAPI ) 
      {
        newKompasAPI->StopCurrentProcess( TRUE, NULL );
        posLeater = -1;
      }
//  K7+         posLeater = ksCreateViewObject( POSLEADER_OBJ );
      break;
    }

  }
  if ( res ) 
  {
    //      
    if ( oldSec != HatchEnable() ) 
    {
      SetHatchControlEnable( HatchEnable() ); 
      // SetControlEnable( IDP_HATCHANG_ANGLE,  HatchEnable() ); 
      // SetControlEnable( IDP_HATCHANG_STEP,   HatchEnable() ); 
    }
    changed = true;
  }
  return res; 
}


//-------------------------------------------------------------------------------------
//    
//---
int WINAPI CPar::LeaderCallBack( int com, double *      x,
                                          double *      y,
                                          RequestInfo * info,
                                          void *        phantom,
                                          int           dynamic ) 
{
  //      
  reference newPosLeater = ::FindObj( *x, *y, ::ksGetCursorLimit() ); //   -   x,y
  //     -     
  if ( newPosLeater && ::GetObjParam( newPosLeater, 0, 0, ALLPARAM ) != POSLEADER_OBJ )
    newPosLeater = 0;                        //     

  if ( !dynamic )                            //  
  {                          
    if ( !newPosLeater )  
      ::ErrorT( ::LoadStr(ID_ERROR_LEADER) ); //     
    else 
    {                                        //    
      posLeater = newPosLeater;              //     

      if ( oldPosLeader )
        ::LightObj( oldPosLeader, 0 );       //           
 
      return 0; //  
    }
  }
  else 
  {
    //     
    if ( newPosLeater != oldPosLeader ) 
    {
      if ( oldPosLeader )
        ::LightObj( oldPosLeader, 0 );       //      

      oldPosLeader = newPosLeater;

      if ( oldPosLeader )
        ::LightObj( oldPosLeader, 1 );       //    
    }
  }
  return 1;     
}


//-------------------------------------------------------------------------------
//    
//     Cursor  Placement
// ---
void CPar::DrawPosLeader() 
{
  oldPosLeader = 0;  
  posLeater    = 0;

  if ( IsSpcObjCreate() && InitPosLeaderParam() ) 
  {
    RequestInfo info; 
    ::memset(&info, 0, sizeof(info) );
    info.prompt = (char*) ID_INDICATE_LEADER; 
    info.dynamic = 1;
    info.callBack = &LeaderCallBack;          //   
    double x, y; 
    int comm = ::CursorEx( &info, &x, &y, 0, posLiaderParam );
    if ( !comm && oldPosLeader )
      ::LightObj( oldPosLeader, 0 );          //        (Esc)
  }

  if ( posLeater < 0 ) 
    posLeater = ::ksCreateViewObject( POSLEADER_OBJ );
  

  //   ,      
  if ( posLeater > 0 ) 
  {
    //      
    if ( ::ksSpcObjectEdit(spcObject) ) 
    {
      //   
      ::ksSpcIncludeReference( posLeater, true );
      //   
      ::ksSpcObjectEnd();
    }
  }
}


//--------------------------------------------------------------------------
//   
//---
int CPar::_GetMacroParam( void * value, unsigned int size ) 
{
  return ::GetMacroParam( 0, value, size );
}


////////////////////////////////////////////////////////////////////////////////
// 
//


//--------------------------------------------------------------------------
//        "." 
// "123.000" -> "123";   "123.10" -> "123.1"
// pointToComma =1  '.'  ','
//--------------------------------------------------------------------------
void CheckDecimelPart( TCHAR * s, unsigned int pointToComma )
{
  if ( s && ::_tcslen(s) ) 
  {
    TCHAR *c = ::_tcschr( s, _T('.'));
    TCHAR *c1 = c;
    unsigned int flag = 0;
    if ( c1 ) 
    {
      c1++;
      while( *c1!=_T('\0') && !flag ) 
      {
        if ( *c1 != _T('0') )
          flag = 1;
        c1++;
      }
      if( !flag )
        *c = _T('\0');
      else 
      {
        c1 = &s[ ::_tcslen(s)-1 ];
        while( *c1==_T('0') ) 
        {
          *c1 = _T('\0');
          c1--;
        }
        if ( pointToComma )
          *c = _T(',');
      }
    }
  }
}


//------------------------------------------------------------------------------
//     (by AVR)
// ---
bool GetFullName( TCHAR * inName, TCHAR * outName, int outNameLen ) 
{
  bool     rez; //    name
  OFSTRUCT ofs;

  if ( ::GetModuleFileName(StepDLL.hModule, outName, outNameLen) )
  {
    TCHAR * c = ::_tcsrchr( outName, _T('\\') );
    if( c )
    {
      *(c + 1) = _T('\0');
      ::_tcscat( outName, inName );
      rez = ::OpenFile( _bstr_t(outName), &ofs, OF_EXIST ) != HFILE_ERROR;
      if ( !rez ) 
      {
        *(c + 1) = _T('\0');
        ::_tcscat( outName, _T("LOAD\\") );
        ::_tcscat( outName, inName );
        rez = ::OpenFile( _bstr_t(outName), &ofs, OF_EXIST ) != HFILE_ERROR;
      }
    }
  }

  if ( !rez ) 
  {
    ::ksGetFullPathFromSystemPathT( inName,         //    (    )
                                   outName,        // ()    
                                   outNameLen,     //  
                                   sptSYSTEM_FILES //    . ksSystemPath
                                 );

    rez = ::OpenFile( _bstr_t(outName), &ofs, OF_EXIST ) != HFILE_ERROR;
  }

  return rez;
}


//------------------------------------------------------------------------------
// GetFullNameDB
//---
static int GetFullDBName( TCHAR * name, TCHAR * fName ) 
{
  return ::GetFullName( name, fName, _MAX_PATH);
}


//------------------------------------------------------------------------------
//    
// ---
LPTSTR LoadStr( int id ) 
{ 
  static TCHAR buf[512]; 
  //       
  ksConvertLangStrExT( StepDLL.hModule, id, buf, 512 );
  return buf;
}


//------------------------------------------------------------------------------
// _ConnectDB
//---
int _ConnectDB( reference db, TCHAR * name ) 
{
  TCHAR buf[_MAX_PATH];
  return ::GetFullDBName( name, buf ) ? ::ConnectDBT( db, buf ) : ::ConnectDBT( db, name );
}


////////////////////////////////////////////////////////////////////////////////

