//////////////////////////////////////////////////////////////////////////////// 
// 
// step3d2.cpp -   
// 
// 1.                                               - CreateDocument3D 
// 2.                                            - DocIterator 
// 3.                                   - UseEntityCollection 
// 4.  /                                   - GetSetPartName 
// 5.                       - FixAndStandartComponent 
// 6.                       - GetSetColorProperty 
// 7.                       - GetSetArrayVariable 
// 8.                 - GetSetPlacmentComponent 
// 9.    ksEntity    
//                                      - GetSetEntity 
// 10.                                                   - CreateSketch 
// 11.   (   )    
//      ksEntityCollection( IEntityCollection )             - GetArraySketch 
// 12.            - GetSetUserParamComponent 
// 
//////////////////////////////////////////////////////////////////////////////// 
#include "stdafx.h"
#include <afxdllx.h> 
#include "resource.h"

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


//-------------------------------------------------------------------------------
//       DLL
// ---
static AFX_EXTENSION_MODULE StepDLL = { NULL, NULL };


//-------------------------------------------------------------------------------
//   
//    DLL
// ---
extern "C" int APIENTRY
DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
  UNREFERENCED_PARAMETER( lpReserved );

  if ( dwReason == DLL_PROCESS_ATTACH )
  {
    TRACE0( "DLL Initializing!" );
 
    if ( !AfxInitExtensionModule( StepDLL, hInstance ) )
      return 0;

    new CDynLinkLibrary( StepDLL );
  }
  else if ( dwReason == DLL_PROCESS_DETACH )
  {
    TRACE0( "DLL Terminating!" );
    AfxTermExtensionModule( StepDLL );
  }
  return 1;
}


//-------------------------------------------------------------------------------
//   
//  (  ,  ,  )   <res\step3d2.rc2> ,   <step3d2.rh> 
// ---
unsigned int WINAPI LIBRARYID()
{
  return IDR_LIBID;
}


//-------------------------------------------------------------------------------
//   
// ---
void CreateDocument3D();
void DocIterator();
void UseEntityCollection();
void GetSetPartName          ( IDocument3DPtr& pDocument3d );
void FixAndStandartComponent ( IDocument3DPtr& pDocument3d );
void GetSetColorProperty     ( IDocument3DPtr& pDocument3d );
void GetSetArrayVariable     ( IDocument3DPtr& pDocument3d );
void GetSetPlacmentComponent ( IDocument3DPtr& pDocument3d );
void GetSetEntity            ( IDocument3DPtr& pDocument3d );
void CreateSketch            ( IDocument3DPtr& pDocument3d );
void GetArraySketch          ( IDocument3DPtr& pDocument3d );
void GetSetUserParamComponent( IDocument3DPtr& pDocument3d );


//------------------------------------------------------------------------------
//   
// ---
void WINAPI LIBRARYENTRY( UINT comm )
{
  switch ( comm )
  {
    case 10 :  CreateDocument3D();     break;  //  
    case 11 :  DocIterator();          break;  //   
    case 12 :  UseEntityCollection();  break;  //   
    default :
    {
      IDocument3DPtr document3d( ksGetActive3dDocument(), false /*Addref*/ ); //       
      if ( document3d  )
      {
        switch ( comm )
        {
          case 1  : GetSetPartName          ( document3d ); break; // /  
          case 2  : FixAndStandartComponent ( document3d ); break; //     
          case 3  : GetSetColorProperty     ( document3d ); break; //      
          case 4  : GetSetArrayVariable     ( document3d ); break; //      
          case 5  : GetSetPlacmentComponent ( document3d ); break; //        
          case 6  : GetSetEntity            ( document3d ); break; //   ksEntity        
          case 7  : CreateSketch            ( document3d ); break; //  
          case 8  : GetArraySketch          ( document3d ); break; //   (   )     ksEntityCollection( IEntityCollection )
          case 9  : GetSetUserParamComponent( document3d ); break; //       
        }
      }
      else
      {
        CString strError;
        strError.LoadString( IDS_3DDOCERROR ); // "      3D-"
        ErrorT( (LPTSTR)( LPCTSTR )strError ); //    
      }
      if ( ReturnResult() == etError10 ) // "!  "
        ResultNULL(); //  
    }    
  }
}


//-------------------------------------------------------------------------------
//   3D
// ---
void CreateDocument3D()
{
  //       
  IDocument3DPtr pDocument3d( ksGet3dDocument(), false/*AddRef*/ );
  if ( pDocument3d ) 
  {
    if ( pDocument3d->Create( false,   //     ( TRUE -  , FALSE -   )
                              true ) ) //   ( TRUE - , FALSE -  ) 
    {
      pDocument3d->SetAuthor( _bstr_t( _T("") ) );                //  
      pDocument3d->SetComment( _bstr_t( _T("  3D") ) ); //   
      pDocument3d->SetFileName( _bstr_t( _T("C:\\Example.m3d") ) );    //   
      pDocument3d->UpdateDocumentParam();                          //   
      pDocument3d->Save();                                         //  
      MessageT( _T("    ") );
      pDocument3d->SaveAs( _bstr_t( _T("C:\\Example2.m3d") ) );        //     

      TCHAR buf[255];
      
      //  
      CString author = pDocument3d->GetAuthor();      
      _stprintf( buf, _T(" : %s"), author );
      MessageT( buf );
      
      //   
      CString comment = pDocument3d->GetComment();
      _stprintf( buf, _T("  : %s"), comment );
      MessageT( buf );
      
      //  
      CString fileName = pDocument3d->GetFileName();      
      _stprintf( buf, _T(" : %s"), fileName );
      MessageT( buf );

      pDocument3d->Close(); //  
    }
  }
}


//-------------------------------------------------------------------------------
//        
// ---
void DocIterator()
{
  //       
  reference rArDocFileName = CreateArray( CHAR_STR_ARR, 0 );
  
  if ( ksChoiceFilesT( _T("*.m3d"), _T(" ( *.m3d )|*.m3d| ( *.a3d )|*a3d|  ( *.* )|*.*|"), rArDocFileName, 1 ) )
  {
    TCHAR buf[255];
    
    //     
    int docCount = GetArrayCount( rArDocFileName );
    for ( int i = 0; i < docCount; i++ ) 
    {
      if ( GetArrayItem( rArDocFileName, i, buf, 255 ) ) 
      {
        //       
        IDocument3DPtr pDocument3d( ksGet3dDocument(), false /*AddRef*/ );
        if ( pDocument3d )
          //    - (    )
          pDocument3d->Open( _bstr_t( buf ), //    
                             false );        //    
                                             // ( TRUE   , FALSE -   )
      }
    }

    //        
    _stprintf( buf, _T(" %d "), docCount );
    MessageT( buf );
    
    //   3D 
    reference rIterator = CreateIterator( D3_DOCUMENT_OBJ, 0 );
    if ( rIterator ) 
    { 
      reference rDocument = MoveIterator( rIterator, 'F' ); //     
      while ( rDocument > 0 )
      {
        IDocument3DPtr pDocument3d( ksGet3dDocumentFromReference( rDocument ), false/*AddRef*/ );
        if ( pDocument3d ) 
        {
          //  
          CString author = pDocument3d->GetAuthor();      
          _stprintf( buf, _T(" : %s"), author );
          MessageT( buf );
      
          //   
          CString comment = pDocument3d->GetComment();
          _stprintf( buf, _T("  : %s"), comment );
          MessageT( buf );
      
          //  
          CString fileName = pDocument3d->GetFileName();      
          _stprintf( buf, _T(" : %s"), fileName );
          MessageT( buf );
          
          //  
          _stprintf( buf, _T(" : %s"), pDocument3d->IsDetail() ? _T("") : _T("") );
          MessageT( buf );
            
        }
        rDocument = MoveIterator( rIterator, 'N' ); //     
      } 
      DeleteIterator( rIterator ); //  
    }
  }
}


//-------------------------------------------------------------------------------
//   
// ---
void UseEntityCollection()
{
  IDocument3DPtr pDocument3d( ksGetActive3dDocument(), false/*AddRef*/ ); //       
  if ( pDocument3d )
  {
    //           ( pNew_Part -  ,
    // pEdit_Part -  , pTop_Part -   )    
    IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/ );
    if ( part )
    {
      TCHAR buf[255];
            
      //          -   
      IEntityCollectionPtr entityCollection( part->EntityCollection( o3d_face ), false/*AddRef*/ );
      if ( entityCollection )
      {
        int countAllFace  = entityCollection->GetCount(); //   
        int countPlane = 0;                               //   
        int countCone  = 0;                               //   
        for ( int i = 0; i < countAllFace; i++ ) 
        {
          IEntityPtr entityFace( entityCollection->GetByIndex( i ), false/*AddRef*/ ); //  
          IColorParamPtr colorParam( entityFace->ColorParam(), false/*AddRef*/ );       //  
          
          //        
          //   
          IFaceDefinitionPtr faceDefinition( IUnknownPtr( entityFace->GetDefinition(), false/*AddRef*/ ) );
          if ( faceDefinition ) 
          {
            if ( faceDefinition->IsCone() ||    //   
                 faceDefinition->IsCylinder() ) //  
            {
              colorParam->SetColor( RGB( 255, 255, 0 ) );
              countCone++; //    
            }
      
            if ( faceDefinition->IsPlanar() ) //   
            {
              colorParam->SetColor( RGB( 0, 255, 255 ) );
              countPlane++; //    
            }
            entityFace->Update(); //   
          }
        }

        if ( countAllFace == 0 )
          MessageT( _T("    ") );
        else 
        {
          _stprintf( buf, _T(" %i   %i  "), countCone, countPlane );
          MessageT( buf );
        }
      } 
      
      //          -   
      IEntityCollectionPtr entityCollection2( part->EntityCollection( o3d_edge ), false/*AddRef*/ );
      if ( entityCollection2 )
      {
        int countAllEdge     = entityCollection2->GetCount(); //   
        int countRectilinear = 0;                             //   
        int countCurvilinear = 0;                             //   
        for ( int i = 0; i < countAllEdge; i++ ) 
        {
          IEntityPtr entityEdge( entityCollection->GetByIndex( i ), false/*AddRef*/ ); //  
          if ( entityEdge )
          {
            //        
            //   
            IEdgeDefinitionPtr edgeDefinition( IUnknownPtr( entityEdge->GetDefinition(), false/*AddRef*/ ) );
            if ( edgeDefinition ) 
            {
              if ( edgeDefinition->IsStraight() )
                countRectilinear++; //   
              else
                countCurvilinear++; //   
            }
          }
        }
        
        if ( countAllEdge == 0 )
          MessageT( _T("    ") );
        else 
        {
          _stprintf( buf, _T(" %i   %i  "), countRectilinear, countCurvilinear );
          MessageT( buf );
        }
      }    
    }
  }
}


//-------------------------------------------------------------------------------
// /       
// ---
void GetSetPartName( IDocument3DPtr& pDocument3d ) 
{
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/ );
  if ( part )
  {
    TCHAR buf[255];
   
    //        
    CString str = part->GetName();
    _stprintf( buf, _T("  %s"), str );
    MessageT( buf );
   
    //        
    part->SetName( _bstr_t(_T("  ")) );
    part->Update(); //   
  }
}


//-------------------------------------------------------------------------------
//     
// ---
void FixAndStandartComponent( IDocument3DPtr& pDocument3d ) 
{
  if ( pDocument3d->IsDetail() ) // ,    
  {
    ErrorT( _T("    ") );
    return;
  }
  
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart(0), false/*AddRef*/ ); //    
  if ( part )
  {
    //     (   ,      )
    int fixedComponent = part->GetFixedComponent();
    MessageT( fixedComponent ? _T(" ") : _T("  ") );
    
    //     (     )
    int standardComponent = part->GetStandardComponent();
    MessageT( standardComponent ? _T(" ") : _T(" ") );
    
    //     (   ,      )
    part->SetFixedComponent( !fixedComponent );    
    //     (     )
    part->SetStandardComponent( !standardComponent );
  }
}


//-------------------------------------------------------------------------------
// /   
// ---
void GetSetColorProperty( IDocument3DPtr& pDocument3d ) 
{
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/ );
  if ( part )
  {
    TCHAR buf[255];

    //    
    //   
    IColorParamPtr colorParam( part->ColorParam(), false/*AddRef*/ );
    if ( colorParam ) 
    {
      _stprintf( buf, _T(" = %d,   = %g,\n = %g,  = %g,\n = %g,  = %g,\n = %g"), 
               colorParam->GetColor(), colorParam->GetAmbient(), 
               colorParam->GetDiffuse(), colorParam->GetSpecularity(), 
               colorParam->GetShininess(), colorParam->GetTransparency(), 
               colorParam->GetEmission() );
      MessageT( buf );
      
      //    
      colorParam->SetColor( 5421504 );
      colorParam->SetTransparency( 0.5 );
      colorParam->SetAmbient( 0.1 );
      colorParam->SetDiffuse( 0.1 );
      
      part->Update(); //   
      
      _stprintf( buf, _T(" = %d,   = %g,\n = %g,  = %g,\n = %g,  = %g,\n = %g"), 
               colorParam->GetColor(), colorParam->GetAmbient(), 
               colorParam->GetDiffuse(), colorParam->GetSpecularity(), 
               colorParam->GetShininess(), colorParam->GetTransparency(), 
               colorParam->GetEmission() );
      MessageT( buf );
    }
    
    //  
    COLORREF color;      // 
    double ambient,      //  
           diffuse,      // 
           specularity,  //   
           shininess,    // 
           transparency, // 
           emission;     //   
    
    //        
    part->GetAdvancedColor( &color, &ambient, &diffuse, &specularity, &shininess, &transparency, &emission );
    _stprintf( buf, _T(" = %d,   = %g,\n = %g,  = %g,\n = %g,  = %g,\n = %g"), 
             color, ambient, 
             diffuse, specularity, 
             shininess, transparency, 
             emission );
    MessageT( buf );
    
    //    
    color = 9421504; 
    transparency = 0.5; 
    ambient = 0.1; 
    diffuse = 0.1;
    
    //       
    part->SetAdvancedColor( color, ambient, diffuse, specularity, shininess, transparency, emission );
   
    part->Update(); //   
    
    //        
    part->GetAdvancedColor( &color, &ambient, &diffuse, &specularity, &shininess, &transparency, &emission );
    _stprintf( buf, _T(" = %d,   = %g,\n = %g,  = %g,\n = %g,  = %g,\n = %g"), 
             color, ambient, 
             diffuse, specularity, 
             shininess, transparency, 
             emission );
    MessageT( buf );
  }
}


//-------------------------------------------------------------------------------
// /   
// ---
void GetSetArrayVariable( IDocument3DPtr& pDocument3d ) 
{
  if ( pDocument3d->IsDetail() ) // ,    
  {
    ErrorT( _T("    ") );
    return;
  }
  
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( 0 ), false/*AddRef*/ ); //    
  if ( part )
  {  
    //     
    IVariableCollectionPtr variableCollection( part->VariableCollection(), false/*AddRef*/ );
    if ( variableCollection ) 
    {
      //     
      int count = variableCollection->GetCount();
      for ( int i = 0; i < count; i++ ) 
      {
        //  
        IVariablePtr variable( variableCollection->GetByIndex( i ), false/*AddRef*/ );
        if ( variable ) 
        {
          if ( i == 0 ) 
          {
            //   
            variable->SetNote( _bstr_t( _T(" ") ) );
            double d = 0;
            //   
            ReadDoubleT( _T(" "), 10, 0, 100, &d );
            //    
            variable->SetValue( d );
          }
        
          TCHAR buf[255];
          CString name( variable->GetName() ); //  
          CString note( variable->GetNote() ); //  
          _stprintf( buf, _T("  : %d\n  : %s\n  : %g\n : %s"), 
                   i, name, variable->GetValue(), note );
          MessageT( buf );
        }
      }
      //         
      part->RebuildModel();
    }
  }
}


//-------------------------------------------------------------------------------
//        
// ---
void GetSetPlacmentComponent( IDocument3DPtr& pDocument3d ) 
{
  if ( pDocument3d->IsDetail() ) // ,    
  {
    ErrorT( _T("    ") );
    return;
  }
  
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( 0 ), false/*AddRef*/ ); //    
  if ( part )
  {  
    IPlacementPtr placement( part->GetPlacement(), false/*AddRef*/ ); //      
    if ( placement ) 
    {
      double x, y, z;  
      placement->GetOrigin( &x, &y, &z ); //      
      
      TCHAR buf[255];
      _stprintf( buf, _T("x = %g\ny = %g\nz = %g"), x, y, z );
      MessageT( buf );
      
      placement->SetOrigin( 20, 20, 20 ); //      
      
      part->SetPlacement( placement );    //    
      part->UpdatePlacement(); //   ,   SetPlacement
      part->Update(); //    (   ) 
    }
  }
}


//-------------------------------------------------------------------------------
//   ksEntity        
// ---
void GetSetEntity( IDocument3DPtr& pDocument3d ) 
{
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/ ); 
  if ( part )
  {  
    IEntityPtr entityPlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ ); //     ,
                                                                                       //     -  XOY
    if ( entityPlane ) 
    {
      CString name( entityPlane->GetName() );   //    
      MessageT( (LPTSTR)(LPCTSTR)name );
      
      entityPlane->SetName( _bstr_t(_T("Plane")) ); //      
      entityPlane->Update(); //    (   )
    }
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void CreateSketch( IDocument3DPtr& pDocument3d )
{
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/); 
  if ( part )
  {  
    //   
    IEntityPtr entitySketch( part->NewEntity( o3d_sketch ), false/*AddRef*/ );
    if ( entitySketch )
    {
      //        
      //   
      ISketchDefinitionPtr sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(), false/*AddRef*/ ) );
      if ( sketchDefinition )
      {
        //     XOY
        IEntityPtr basePlane( part->GetDefaultEntity( o3d_planeXOY ), false/*AddRef*/ );
 
        //   
        sketchDefinition->SetPlane( basePlane ); //   XOY   
        sketchDefinition->SetAngle( 45 );               //   
 
        //  
        entitySketch->Create();

        //     
        if ( sketchDefinition->BeginEdit() )
        {
          //    - 
          LineSeg(  50,  50, -50,  50, 1 );
          LineSeg(  50, -50, -50, -50, 1 );
          LineSeg(  50, -50,  50,  50, 1 );
          LineSeg( -50, -50, -50,  50, 1 );
          //     
          sketchDefinition->EndEdit();
        }
      }
    }
  }
}


//-------------------------------------------------------------------------------
//    (  )     IEntityCollection
// ---
void GetArraySketch( IDocument3DPtr& pDocument3d ) 
{
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart( pTop_Part ), false/*AddRef*/ ); 
  if ( part )
  {  
    //          -   
    IEntityCollectionPtr entityCollection( part->EntityCollection( o3d_sketch ), false/*AddRef*/ ); 
    if ( entityCollection ) 
    {
      //     
      int count = entityCollection->GetCount();
      for ( int i = 0; i < count; i++ ) 
      {
        IEntityPtr currentEntity( entityCollection->GetByIndex( i ), false/*AddRef*/ ); //  
        CString  name( currentEntity->GetName() ); //  
        MessageT( (LPTSTR)(LPCTSTR) name );
      }
    }
  }
}


//-------------------------------------------------------------------------------
//       
// ---
void GetSetUserParamComponent( IDocument3DPtr& pDocument3d  ) 
{
  if ( pDocument3d->IsDetail() ) // ,    
  {
    ErrorT( _T("    ") );
    return;
  }
  
  //           ( pNew_Part -  ,
  // pEdit_Part -  , pTop_Part -   )    
  IPartPtr part( pDocument3d->GetPart(0), false/*AddRef*/ ); //    
  if ( part )
  {    
    //  
    struct UserParam 
    {
      double d1;
      double d2;
      int    i1;
      int    i2;
    } param;
    
    param.d1 = 12.12;
    param.d2 = 21.21;
    param.i1 = 888;
    param.i2 = 999;

    //   ,  
    part->SetUserParam( &param, sizeof( param ), 0, 0, -1 );
    part->Update(); //    (   ) 

    TCHAR buf[255];
    _stprintf( buf, _T("   %d"), part->GetUserParamSize() ); //   
    MessageT( buf );

    part->GetUserParam( &param, sizeof( param ) ); //   ,   
    _stprintf( buf, _T("  \nd1 = %g\nd2 = %g\ni1 = %d\ni2 = %d"), 
             param.d1, param.d2, param.i1, param.i2 );
    MessageT( buf ); 
  }
}

