//////////////////////////////////////////////////////////////////////////////// 
// 
// step8.cpp -   
// 
// 1.                          - FuncTypeAttr 
// 2.                          - DelTypeAttr  
// 3.                         - ShowTypeAttr 
// 4.                         - ChangeType  
// 5.             - NewAttr  
// 6.                              - DelObjAttr  
// 7.                              - ReadObjAttr  
// 8.                          - ShowObjAttr   
// 9.                       - ShowLib   
// 10.                             - ShowType   
// 11.                         - WalkFromObjWithAttr   
// 12.                    - CreateDocumentAttr  
// 13.                    - DeleteDocumentAttr
// 14.                - ShowDocumentAttr 
// 15.   3D               - CreateDocument3DAttr 
// 16.   3D               - DeleteDocument3DAttr 
// 17.                - ShowDocument3DAttr 
// 18.    3D  - ShowObjects3DAttr 
// 
//////////////////////////////////////////////////////////////////////////////// 
#include "stdafx.h"
#include <afxdllx.h> 
#include "resource.h"

#ifndef __LIBTOOL_H
#include <libtool.h>
#endif

#ifndef __LTOOL3D_H
#include <Ltool3d.h>
#endif

#ifndef __IUPTR_H
#include <iuptr.h>
#endif

#include <comdef.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;
}


//-------------------------------------------------------------------------------
//   
// ---
unsigned int WINAPI LIBRARYID()
{
  return IDR_LIBID;
}


//-------------------------------------------------------------------------------
//   
// ---
void FuncTypeAttr();
void DelTypeAttr();
void ChangeType();
void NewAttr();
void ShowTypeAttr();
void DelObjAttr();
void ReadObjAttr();
void ShowObjAttr();
void ShowLib();
void ShowType();
void WalkFromObjWithAttr();
void CreateDocumentAttr();
void DeleteDocumentAttr();
void ShowDocumentAttr();
void CreateDocument3DAttr();
void DeleteDocument3DAttr();
void ShowDocument3DAttr();
void ShowObjects3DAttr();  


int       docType = 0; //  
reference doc     = 0; // reference 
  
//-------------------------------------------------------------------------------
//   
// ---
void WINAPI LIBRARYENTRY( unsigned int comm )
{
  doc     = ksGetCurrentDocument( 0 );
  docType = ksGetDocumentType( doc );

  switch ( docType ) {
    case lt_DocTxtStandart:        //               7-   
    case lt_DocTxtUser:            //               8-   
    { 
      int res = YesNoT( _T("       \n")
                        _T("    ?") );
      if ( res ) 
      {
        doc     = 0;
        docType = 0;
      }
      else 
        break;
    }
    case 0:                        //   (   ) 
    case lt_DocSheetStandart:      //   1-  
    case lt_DocSheetUser:          //               2-  
    case lt_DocFragment:           //               3- 
    case lt_DocSpc:                //               4- 
    case lt_DocPart3D:             //               5- 3d- 
    case lt_DocAssemble3D:         //               6- 3d- 
    case lt_DocSpcUser:            //               9-   
      switch ( comm )
      {
        case 1  : FuncTypeAttr();        break; //   
        case 2  : DelTypeAttr();         break; //   
        case 3  : ShowTypeAttr();        break; //   
        case 4  : ChangeType();          break; //   
        case 5  : NewAttr();             break; //    
        case 6  : DelObjAttr();          break; //  
        case 7  : ReadObjAttr();         break; //  
        case 8  : ShowObjAttr();         break; //  
        case 9  : ShowLib();             break; //  
        case 10 : ShowType();            break; //  
        case 11 : WalkFromObjWithAttr(); break; //  
        case 12 : CreateDocumentAttr();  break; //    
        case 13 : DeleteDocumentAttr();  break; //   
        case 14 : ShowDocumentAttr();    break; //   
        case 15 : CreateDocument3DAttr();break; //   3D 
        case 16 : DeleteDocument3DAttr();break; //   3D 
        case 17 : ShowDocument3DAttr();  break; //   
        case 18 : ShowObjects3DAttr();   break; //    3D 
      }
  }
}


//-------------------------------------------------------------------------------
//     
// ---
void ShowColumns( reference rArColumn, bool record )
{
  ColumnInfoT parColumn; //     
    
  //   
  parColumn.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
  parColumn.fieldEnum = CreateArray( CHAR_STR_ARR, 0 );    //        

  //     
  int count = GetArrayCount( rArColumn );
  TCHAR buf[255]; 
  _stprintf( buf, _T("count = %d"), count );
  MessageT( buf );
  
  //   
  for ( int i = 0; i < count; i++ )
  {
    //    
    if ( !GetArrayItem( rArColumn,              //   
                        i,                      //   
                        &parColumn,             //    
                        sizeof( parColumn ) ) ) //     
      MessageBoxResult(); //       
    else
    {
      //    
      _stprintf( buf, record ? _T("RECORD, i = %d, header = %s,\ntype = %d, def = %s, flagEnum = %d") : 
                             _T("i = %d, header = %s,\ntype = %d, def = %s, flagEnum = %d"), 
               i, parColumn.header, parColumn.type, parColumn.def, parColumn.flagEnum );
      MessageT( buf );
      
      //      - ( RECORD ),   columns   
      //  ,    . 
      
      if ( parColumn.type == RECORD_ATTR_TYPE ) //   
        ShowColumns( parColumn.columns, TRUE );  
      else
      {
        //   
        if ( parColumn.flagEnum )
        {
          //     
          int count1 = GetArrayCount( parColumn.fieldEnum );
          
          MessageT( _T(" ") );
          for ( int j = 0; j < count1; j++ )
          {
            //    
            if ( !GetArrayItem( parColumn.fieldEnum, //   
                                j,                   //   
                                &buf,                //    
                                sizeof( buf ) ) )    //     
              MessageBoxResult();     //       
            else
              MessageT( buf );
          }
        }
      }
    }
  }
  
  //   
  DeleteArray( parColumn.columns );   //        
  DeleteArray( parColumn.fieldEnum ); //        
}


//-------------------------------------------------------------------------------
//   
// ---
void FuncTypeAttr()
{
  TCHAR nameFile[255] = _T("");
 
  //   
  ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 );
  
  if ( !nameFile[0] && !doc )  //       
    return;

  //    3 
  //   -  int    ( 100, 200, 300 )
  //   -    double (   123456789 )
  //                                                 long   (   1000000 )
  //                                                 char   (   10 )
  //   -   (   "text" )

  ColumnInfoT parColumn,  //    
              parStruct;  //     
  
  //   
  reference rArColumn = CreateArray( ATTR_COLUMN_ARR, 0 ); //   
  reference rArStruct = CreateArray( ATTR_COLUMN_ARR, 0 ); //    
  reference rArEnum   = CreateArray( CHAR_STR_ARR_T,  0 ); //    

  //  
  _tcscpy( parColumn.header, _T("int") ); // o- 
  parColumn.type = INT_ATTR_TYPE;    //     - .
  parColumn.key = 0;                 //  ,        
  _tcscpy( parColumn.def, _T("100") );    //   
  parColumn.flagEnum = 1;            //   ,      
                                     //     1  0 
  parColumn.fieldEnum = rArEnum;     //        
  parColumn.columns = 0;             //        

  //       ,     
  TCHAR buf[255];
  _tcscpy( buf, _T("100") );
  //  1- ,     
  AddArrayItem( rArEnum,         //   
                -1,              //   
                &buf,            //    
                sizeof( buf ) ); //     
                  
  _tcscpy( buf, _T("200") );
  //  2- ,     
  AddArrayItem( rArEnum,         //   
                -1,              //   
                &buf,            //    
                sizeof( buf ) ); //     
  
  _tcscpy( buf, _T("300") );
  //  3- ,     
  AddArrayItem( rArEnum,         //   
                -1,              //   
                &buf,            //    
                sizeof( buf ) ); //     

  //   ,     
  AddArrayItem( rArColumn,             //   
                -1,                    //   
                &parColumn,            //    
                sizeof( parColumn ) ); //     
                
  //      - ( RECORD ),   columns   
  //  ,    . 
      
  //  
  _tcscpy( parColumn.header, _T("struct") ); // o- 
  parColumn.type = RECORD_ATTR_TYPE;    //     - .
  parColumn.key = 0;                    //  ,        
  memset( parColumn.def, 0, sizeof(parColumn.def) );
  parColumn.flagEnum  = 0;              //   ,      
                                        //     1  0 
  parColumn.fieldEnum = 0;              //        
  parColumn.columns   = rArStruct;      //        
 
  //     
  //   
  _tcscpy( parStruct.header, _T("double") ); // o- 
  parStruct.type = DOUBLE_ATTR_TYPE;    //     - .
  parStruct.key  = 0;                   //  ,        
  _tcscpy( parStruct.def, _T("123456789") ); //   
  parStruct.flagEnum  = 0;              //   ,      
                                        //     1  0 
  parStruct.fieldEnum = 0;              //        
  parStruct.columns   = 0;              //          
  //    ,     
  AddArrayItem( rArStruct,             //   
                -1,                    //   
                &parStruct,            //    
                sizeof( parStruct ) ); //     
                
  //   
  _tcscpy( parStruct.header, _T("long") ); // o- 
  parStruct.type = LINT_ATTR_TYPE;    //     - .
  parStruct.key  = 0;                 //  ,        
  _tcscpy( parStruct.def, _T("1000000") ); //   
  parStruct.flagEnum  = 0;            //   ,      
                                      //     1  0 
  parStruct.fieldEnum = 0;            //        
  parStruct.columns   = 0;            //        
  //    ,     
  AddArrayItem( rArStruct,             //   
                -1,                    //   
                &parStruct,            //    
                sizeof( parStruct ) ); //     
                
  //   
  _tcscpy( parStruct.header, _T("TCHAR") ); // o- 
  parStruct.type = CHAR_ATTR_TYPE;    //     - .
  parStruct.key  = 0;                 //  ,        
  _tcscpy( parStruct.def, _T("10") );      //   
  parStruct.flagEnum = 0;             //   ,      
                                      //     1  0 
  parStruct.fieldEnum = 0;            //        
  parStruct.columns   = 0;            //        
  //    ,     
  AddArrayItem( rArStruct,             //   
                -1,                    //   
                &parStruct,            //    
                sizeof( parStruct ) ); //     
                  
  //   ,     
  AddArrayItem( rArColumn,             //   
                -1,                    //   
                &parColumn,            //    
                sizeof( parColumn ) ); //     
                
  //   
  _tcscpy( parColumn.header, _T("string") ); // o- 
  parColumn.type = STRING_ATTR_TYPE;    //     - .
  parColumn.key  = 0;                   //  ,        
  _tcscpy( parColumn.def, _T("text") );      //   
  parColumn.flagEnum  = 0;              //   ,      
                                        //     1  0 
  parColumn.fieldEnum = 0;              //        
  parColumn.columns   = 0;              //        
  
  //   ,     
  AddArrayItem( rArColumn,             //   
                -1,                    //   
                &parColumn,            //    
                sizeof( parColumn ) ); //     

  ksAttributeTypeT parAttributeType; //     
  
  //    
  _tcscpy( parAttributeType.header, _T("int_struct_string") ); // o- 
  parAttributeType.rowsCount   = 0;                       // -   
  parAttributeType.flagVisible = 1;                       // ,     
  _tcscpy( parAttributeType.password, _T("") );                // ,      -     
  parAttributeType.columns     = rArColumn;               //      
  parAttributeType.key1        = 10;                      //    
  parAttributeType.key2        = 20;                      //    
  parAttributeType.key3        = 30;                      //    
  parAttributeType.key4        = 0;                       //     

  // C  
  double numbType = ksCreateAttrTypeT( &parAttributeType, //    
                                        nameFile );       //    
  if ( numbType > 1 )  
  {
    TCHAR buf[255];
    _stprintf( buf, _T("numbType = %f"), numbType );
    MessageT( buf );
  }
  else
    MessageBoxResult(); //         

  //   
  DeleteArray( rArColumn ); //   
  DeleteArray( rArStruct ); //    
  DeleteArray( rArEnum   ); //      
}


//-------------------------------------------------------------------------------
//   
// ---
void DelTypeAttr()
{
  TCHAR nameFile[255] = _T("");
  //   
  ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 );

  if ( nameFile[0] || doc ) //      
  {   
    TCHAR password[255] = _T("");
    double numbType    = ChoiceAttrTypesT( nameFile ); //   
  
    if ( numbType > 1 ) 
    { 
      // ReadDouble( "   ", 1000., 0, 1e12, &numbType ) ) 
      if ( ReadStringT( _T("   "), password, 255 ) ) 
        //   
        if ( !DeleteAttrTypeT( numbType,    //    
                               nameFile,    //    
                               password ) ) //   
          MessageBoxResult(); //      
    }
  }
}


//-------------------------------------------------------------------------------
//    
// ---
void ShowTypeAttr() 
{
  TCHAR nameFile[255] = _T("");
  //   
  ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 );

  if ( nameFile[0] || doc ) //       
  { 
    double numbType = ChoiceAttrTypesT( nameFile ); //   
    if ( numbType > 1 )
    {
      ksAttributeTypeT rAttributeType; //     
      rAttributeType.columns = CreateArray( ATTR_COLUMN_ARR, 0 ); //        

      //       
      if ( !ksGetAttrTypeT( numbType, nameFile, &rAttributeType ) )
        MessageBoxResult(); //         
      else 
      {
        TCHAR buf[500]; 
        _stprintf( buf, _T("key1 = %d, key2 = %d, key3 = %d, key4 = %d,\nheader = %s, rowsCount = %d, flagVisible = %d, password = %s"), 
                rAttributeType.key1, rAttributeType.key2, rAttributeType.key3, rAttributeType.key4,
                rAttributeType.header, rAttributeType.rowsCount, rAttributeType.flagVisible, rAttributeType.password );
        MessageT( buf );
     
        ShowColumns( rAttributeType.columns, FALSE ); //     
      }
      //    
      DeleteArray( rAttributeType.columns );
    }
  }
}


//-------------------------------------------------------------------------------
//   
// ---
void ChangeType()
{
  TCHAR nameFile[255] = _T("");
  
  //   
  ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 );

  if ( nameFile[0] || doc )  //      
  {
    TCHAR password[255] = _T("");
    // double numbType;
    double numbType = ChoiceAttrTypesT( nameFile );
    if ( numbType > 1000 ) 
    {
      if ( ReadStringT( _T("   "), password, 255 ) ) 
      {
        ksAttributeTypeT rAttributeType; //     
        rAttributeType.columns = CreateArray( ATTR_COLUMN_ARR, 0 ); //        

        //       
        if ( !ksGetAttrTypeT( numbType,           //   
                              nameFile,           //    
                              &rAttributeType ) ) //     
          MessageBoxResult(); //         
        else
        {
          //      
          ColumnInfoT parColumn1; //        
          parColumn1.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
          parColumn1.fieldEnum = CreateArray( CHAR_STR_ARR_T,  0 ); //        

          ColumnInfo parColumnN; //          
          parColumnN.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
          parColumnN.fieldEnum = CreateArray( CHAR_STR_ARR_T,  0 ); //        

          _tcscpy( rAttributeType.password, password );
          //  
          int count = GetArrayCount( rAttributeType.columns );
        
          //    
          GetArrayItem( rAttributeType.columns, 0, &parColumn1, sizeof( parColumn1 ) );
          //    
          GetArrayItem( rAttributeType.columns, count - 1, &parColumnN, sizeof( parColumnN ) );
        
          //    (   )
          SetArrayItem( rAttributeType.columns, 0, &parColumnN, sizeof( parColumnN ) );
          //    (   )
          SetArrayItem( rAttributeType.columns, count - 1, &parColumn1, sizeof( parColumn1 ) );

          //      
          numbType = ksSetAttrTypeT( numbType,        //   
                                    nameFile,        //    
                                    &rAttributeType, //     
                                    password );      //   
          if ( numbType > 1 )  
          {
            TCHAR buf[255];
            _stprintf( buf, _T("numbType = %f"), numbType );
            MessageT( buf );
          }
          else
            MessageBoxResult(); //        
          
            //   
          DeleteArray( parColumn1.columns );   //        
          DeleteArray( parColumn1.fieldEnum ); //        

          DeleteArray( parColumnN.columns );   //        
          DeleteArray( parColumnN.fieldEnum ); //        

        }
        DeleteArray( rAttributeType.columns );  //   
      }
    }
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void LibCreateAttr( reference obj, LPFEATURE fObj )
{
  ksAttributeT parAttribute; //    
  memset( &parAttribute, 0, sizeof(parAttribute) );
  parAttribute.key1 = 1;                  //    
  parAttribute.key2 = 10;                 //    
  parAttribute.key3 = 100;                //    
  _tcscpy( parAttribute.password, _T("111") ); // ,     -       

  TCHAR nameFile[255] = _T("");
  
  ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 );    //   
  double numbType = ChoiceAttrTypesT( nameFile ); //     

  if ( numbType > 1 ) 
  {  
    //   
    reference attr = 0;
    if ( obj )
      attr = ksCreateAttrT( obj,          //   
                            &parAttribute,//    
                            numbType,     //   
                            nameFile );   //  
    else
    {
      IUEnv<IAttribute3D> attr3D ( ksCreateAttr3DExT( fObj, NULL,    //     3D 
                                                      &parAttribute, //     
                                                      numbType,      //   
                                                      nameFile ) );  //  
      if ( attr3D ) 
        attr = attr3D->GetReference();
    }
    if ( attr )     
      ViewEditAttrT( attr, 2, parAttribute.password ); //  
  }
  if ( ReturnResult() ) 
  {
    MessageBoxResult(); //      
    ResultNULL();
  }
}


//-------------------------------------------------------------------------------
//    3D 
// ---
LPFEATURE Select3DFeature() 
{
  LPFEATURE obj = NULL;
  reference doc = ::ksGetCurrentDocument( 3 );
  if ( doc )
  {
    IUEnv<IDocument3D> doc3D( ksGet3dDocumentFromReference(doc) );
    IUEnv<IEntity> selEnt(NULL);
    if ( doc3D ) 
    { 
      selEnt.SetI( doc3D->UserSelectEntity( 0, 0, _bstr_t(_T(" "))) );
      if ( !ReturnResult() ) 
      {
        if ( selEnt.GetI() )
        {
          obj = selEnt->GetFeature();
        }
      }
    }
  }
  return obj;
}


//-------------------------------------------------------------------------------
//    
// ---
void NewAttr()
{
  if ( !doc ) 
  { 
    MessageT( _T("    ") );
    return;
  }
       
  switch ( docType ) 
  {
    case lt_DocSheetStandart: //   1-  
    case lt_DocSheetUser:     //               2-  
    case lt_DocFragment:      //               3- 
    {         
      //     
      RequestInfoT info;
      memset( &info, 0, sizeof( info ) );
  
      //      
      info.prompt = _T(" ");
  
      //     
      double x, y; 

      //     
      if ( CursorExT( &info, &x, &y, 0, NULL ) )
      {
        //       
        reference rObject = FindObj( x, y,  //  
                                     ksGetCursorLimit() ); //   -     x,y
        if ( rObject )
        {
          //   
          LightObj( rObject, 1 );
          LibCreateAttr( rObject, NULL ); //  
          LightObj( rObject, 0 );
        }
      }
      break;
    }
    case lt_DocPart3D:             // 5- 3d- 
    case lt_DocAssemble3D:         // 6- 3d- 
    {
      IUEnv<IFeature> feature3D ( Select3DFeature() );
      if ( feature3D ) 
      {
        LibCreateAttr( NULL, feature3D.GetI() ); 
      }
      break;
    }
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void DeleteAttributes( reference rObject )
{
  if ( rObject ) 
  {
    //       
    reference rIterator = CreateAttrIterator( rObject, //   ,  0,       
                                                       //    ,       
                                              0,       //       0 
                                              0, 
                                              0, 
                                              0, 
                                              0 );     //         0       
    if ( rIterator )
    {
      //    
      reference rAttribute = MoveAttrIterator( rIterator, //   
                                               'F',       //   'F'/'N' 
                                                0 );      //      ,  NULL,  
      while ( rAttribute )
      {
        TCHAR password[255] = _T("");
         
        if ( ReadStringT( _T("   "), password, 10 ) )
        {  
          //  
          if ( !DeleteAttrT( rObject,     //   
                             rAttribute,  //   
                             password ) ) //   
            MessageBoxResult(); //         
        }
         
        //    ,    
        rAttribute = MoveAttrIterator( rIterator, //   
                                      'N',        //   'F'/'N'
                                       0 );       //      ,  NULL,  
      }  
      DeleteIterator( rIterator );  
    }
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void DelObj2DAttr()
{
  //     
  RequestInfoT info;
  memset( &info, 0, sizeof( info ) );
  
  //      
  info.prompt = _T(" ");
  
  //     
  double x, y; 

  //     
  if ( CursorExT( &info, &x, &y, NULL, NULL ) )
  {
    //       
    reference rObject = FindObj( x, y,  //  
                                 1e6 ); //   -     x,y
    if ( rObject )
    {
      //   
      LightObj( rObject, 1 );
      DeleteAttributes( rObject ); //  
      LightObj( rObject, 0 );
    }
  }
}


//-------------------------------------------------------------------------------
//    3
// ---
void DelObj3DAttr() 
{
  IUEnv<IFeature> feature3D ( Select3DFeature() );
  if ( feature3D ) 
  {
    IUEnv<IAttribute3DCollection> attrColl( feature3D->AttributeCollection( 0, 0, 0, 0, 0) ); 
    int count = 0;
    if ( attrColl )
      count = attrColl->GetCount();
    if ( count ) 
    {
      TCHAR buf[255];
      _stprintf( buf, _T(" =%i"), count );
      MessageT( buf );

      for ( int i = count - 1; i >= 0; i-- ) 
      {
        IUEnv<IAttribute3D> attr3D( attrColl->GetByIndex(i) );
        if ( attr3D ) 
        {
          TCHAR password[255] = _T("");
           
          if ( ReadStringT( _T("   "), password, 10 ) )
          {  
            //  
            if ( !ksDeleteAttr3DT( feature3D.GetI(),     //   
                                   attr3D.GetI(), //   
                                   password ) )   //   
              MessageBoxResult(); //         
          }            
        }  
      }
    }
    
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void DelObjAttr() {
  switch ( docType ) {
    case lt_DocSheetStandart:      //   1-  
    case lt_DocSheetUser:          //               2-  
    case lt_DocFragment:           //               3- 
      DelObj2DAttr();
      break;
    case lt_DocPart3D:             //               5- 3d- 
    case lt_DocAssemble3D:         //               6- 3d- 
      DelObj3DAttr();
      break;
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void ReadObjAttr()
{
  //       
  struct BufStruct1
  {
    double   d; 
    long int li;
    TCHAR    c;
  };

  struct
  {
    int i;
    BufStruct1 struct1;
    TCHAR s[MAX_TEXT_LENGTH];
  } bufStruct;
  
  //     
  RequestInfoT info;
  memset( &info, 0, sizeof( info ) );
  
  //      
  info.prompt = _T(" ");
  
  //     
  double x, y; 

  //     
  if ( CursorExT( &info, &x, &y, NULL, NULL ) )
  {
    //       
    reference rObject = FindObj( x, y,  //  
                                 1e6 ); //   -     x,y
    if ( rObject )
    {
      //   
      LightObj( rObject, 1 );
      MessageT( _T("  ") );
      LightObj( rObject, 0 );
        
      //       
      reference rIterator = CreateAttrIterator( rObject, //   ,  0,       
                                                         //    ,       
                                                0,       //       0 
                                                0, 
                                                0, 
                                                0, 
                                                0 );     //         0           
      if ( rIterator )
      {
        //    
        reference rAttribute = MoveAttrIterator( rIterator, //   
                                                 'F',       //   'F'/'N' 
                                                 0 );       //      ,  NULL,          
        while ( rAttribute )
        {
          //    
          unsigned int key1, key2, key3, key4;
          double numbType;         
          //    
          GetAttrKeysInfo( rAttribute,                 //   
                           &key1, &key2, &key3, &key4, //      
                           &numbType );                //                                 
          TCHAR buf[255];
          _stprintf( buf, _T("key1 = %d, key2 = %d, key3 = %d, key4 = %d, numbType = %f"), key1, key2, key3, key4, numbType );
          MessageT( buf );
 

          //  
          unsigned int countColums;        
          //     
          GetAttrTabInfo( rAttribute,     //   
                          0,              //  
                          &countColums ); //         
          _stprintf ( buf, _T("countColums = %d"), countColums );
          MessageT( buf );
 
          //   
          ColumnInfoT parColumn; //     
          memset( &parColumn, 0, sizeof(parColumn) );
          //   
          parColumn.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
          parColumn.fieldEnum = CreateArray( CHAR_STR_ARR_T, 0 );    //        
          for ( unsigned int i = 0; i < countColums; i++ ) 
          {
            //    
            GetAttrColumnInfoT( rAttribute,   //   
                                i,            //      
                                &parColumn ); //     
              
            //    
            _stprintf( buf, _T("i = %d, header = %s,\ntype = %d, def = %s, flagEnum = %d"), 
                     i, parColumn.header, parColumn.type, parColumn.def, parColumn.flagEnum );
            MessageT( buf );
          }
          //   
          DeleteArray( parColumn.columns );   //        
          DeleteArray( parColumn.fieldEnum ); //        

          //    
          ksGetAttrRowT( rAttribute,            //    
                        0,                      //     
                        NULL,                   //       
                        NULL,                   //  
                        &bufStruct,            //     
                        sizeof(bufStruct) ); //  
          _stprintf ( buf, _T("d = %f, s = %s, l = %ld"), bufStruct.struct1.d, bufStruct.s, bufStruct.struct1.li );
          MessageT( buf );

          //   
          bufStruct.struct1.d = 123.123;
          _tcscpy( bufStruct.s, _T("1234567\nasdfgh\nzxcvb") );
          bufStruct.struct1.li = 1;
          
          ksSetAttrRowT( rAttribute,            //    
                         0,                     //     
                         NULL,                  //       
                         NULL,
                         &bufStruct,            //    
                         sizeof( bufStruct ),   //  
                         _T("111") );           //    
        
          memset( &bufStruct, 0, sizeof(bufStruct) );
                
          //    
          ksGetAttrRowT( rAttribute,            //    
                         0,                     //     
                         NULL,                     //       
                         NULL,
                         &bufStruct,            //     
                         sizeof( bufStruct ) ); //  
          _stprintf ( buf, _T("d = %f, s = %s, l = %ld"), bufStruct.struct1.d, bufStruct.s, bufStruct.struct1.li );
          MessageT( buf );
        
          //    ,    
          rAttribute = MoveAttrIterator( rIterator, //   
                                          'N',       //   'F'/'N' 
                                          0 );       //      ,  NULL,  
        }
        DeleteIterator( rIterator ); 
      }  
    }
  }  
}


//-------------------------------------------------------------------------------
//  
// ---
void ShowObj2DAttr()
{
  //     
  RequestInfoT info;
  memset( &info, 0, sizeof( info ) );
  
  //      
  info.prompt = _T(" ");
  
  //     
  double x, y; 

  //     
  if ( CursorExT( &info, &x, &y, NULL, NULL ) )
  {
    //       
    reference rObject = FindObj( x, y,  //  
                                 1e6 ); //   -     x,y
    if ( rObject )
    {
      //   
      LightObj( rObject, 1 );        
      ChoiceAttr( rObject ); //     
      LightObj( rObject, 0 );
    }
  }
}


//-------------------------------------------------------------------------------
//   3D 
// ---
void ShowObj3DAttr()
{
  IUEnv<IFeature> feature3D ( Select3DFeature() );
  if ( feature3D )
  {
    ksChoiceAttr3D( feature3D.GetI() );
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void ShowObjAttr() {
  switch ( docType ) {
    case lt_DocSheetStandart:      //   1-  
    case lt_DocSheetUser:          //               2-  
    case lt_DocFragment:           //               3- 
      ShowObj2DAttr();
      break;
    case lt_DocPart3D:             //               5- 3d- 
    case lt_DocAssemble3D:         //               6- 3d- 
      ShowObj3DAttr();
      break;
  }
}


//-------------------------------------------------------------------------------
//   
// ---
void ShowLib()
{
  TCHAR nameFile[255] = _T("");
  
  //   
  if ( !ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 ) )
    nameFile[0] = _T('\0'); //    ,         

  //              
  double numbType = ChoiceAttrTypesT( nameFile );

  if ( numbType > 1 )  
  {
    TCHAR buf[255];
    _stprintf( buf, _T("numbType = %f"), numbType );
    MessageT( buf );
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void ShowType()
{
  TCHAR nameFile[255] = _T("");
  
  //   
  ksChoiceFileT( _T("*.lat"), NULL, nameFile, 255, 0 );
  
  double numbType = ChoiceAttrTypesT( nameFile );
  if ( numbType > 1000 ) {

    TCHAR password[255] = _T("");
    if ( ReadStringT( _T("   "), password, 255 ) ) 
      //    
      ViewEditAttrTypeT( nameFile,   //    
                         2,          //   ( 1 - , 2 -  )
                         numbType,   //   
                         password ); //   
  }
}


//-------------------------------------------------------------------------------
//   3D 
// ---
void WalkFromObj3DWithAttr()
{
  IUEnv<IFeature> feature3D ( Select3DFeature() );             //   
  if ( feature3D )
  {
    //   
    IUEnv<IAttribute3DCollection> attrColl( feature3D->AttributeCollection( 0, 0, 0, 0, 0) ); 
    int count = 0;
    if ( attrColl )
      count = attrColl->GetCount();                          //  
    if ( count ) {
      TCHAR buf[255];
      _stprintf( buf, _T(" =%i"), count );
      MessageT( buf );

      IUEnv<IDocument3D> doc3D( ksGet3dDocumentFromReference(doc) );  
      if ( doc3D )
      {
        for ( int i = count - 1; i >= 0; i-- )
        {
          IUEnv<IAttribute3D> attr3D( attrColl->GetByIndex(i) ); //     
          if ( attr3D )
          {
            TCHAR password[255] = _T("");
            if ( ReadStringT( _T("   "), password, 255 ) )
            {
              //        
              IUEnv<IChooseMng> cMng ( doc3D->GetChooseMng() );
              IUEnv<IFeatureCollection> ifColl ( attr3D->FeatureCollection( o3d_unknown ) );
              if ( cMng && ifColl ) {
                for ( int i = 0, count = ifColl->GetCount(); i < count; i++ )
                {
                  IUEnv<IFeature> feature( ifColl->GetByIndex(i) );
                  cMng->Choose( feature.GetI() );
                }
              }
              ViewEditAttrT( attr3D->GetReference(), 1, password ); //  
              if ( YesNoT( _T(" ?") ) == 1 ) 
                ksDeleteAttr3DT( feature3D.GetI(), attr3D.GetI(), password );
              if ( cMng )
                cMng->UnChooseAll();
            }
          }
        }  
      }
    }
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void WalkFromObj2DWithAttr()
{
  //     
  RequestInfoT info;
  memset( &info, 0, sizeof( info ) );
  
  //      
  info.prompt = _T(" ");
  
  //     
  double x, y; 

  //     
  if ( CursorExT( &info, &x, &y, NULL, NULL ) )
  {
    //       
    reference rObject = FindObj( x, y,  //  
                                 1e6 ); //   -     x,y
    if ( rObject )
    {
      //   
      LightObj( rObject, 1 );
      MessageT( _T("  ") );
      LightObj( rObject, 0 );
        
      //        10
      reference rIterator = CreateAttrIterator( rObject,   //   ,  0,       
                                                     //    ,       
                                                10,  //       0 
                                                0, 
                                                0, 
                                                0, 
                                                0 ); //         0    
      if ( rIterator )
      {
        //    
        reference rAttribute = MoveAttrIterator( rIterator, //   
                                                 'F',       //   'F'/'N'
                                                 0 );       //      ,  NULL,  
        while ( rAttribute )
        {
          //    
          ViewEditAttrT( rAttribute, //    
                         1,          //   ( 1 - , 2 -  )
                         NULL );     //   
          
          //    ,    
          rAttribute = MoveAttrIterator( rIterator, //   
                                        'N',        //   'F'/'N' 
                                         0 );       //      ,  NULL,  
        } 
        DeleteIterator( rIterator );
      }
    }
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void WalkFromObjWithAttr() 
{
  switch ( docType ) 
  {
    case lt_DocSheetStandart:  //   1-  
    case lt_DocSheetUser:      //               2-  
    case lt_DocFragment:       //               3- 
      WalkFromObj2DWithAttr();
      break;
    case lt_DocPart3D:         //               5- 3d- 
    case lt_DocAssemble3D:     //               6- 3d- 
      WalkFromObj3DWithAttr();
      break;
  }
}


//-------------------------------------------------------------------------------
//   
// ---
void CreateDocumentAttr() 
{
  if ( doc ) 
    LibCreateAttr( doc, NULL );
}


//-------------------------------------------------------------------------------
//   
// ---
void DeleteDocumentAttr() 
{
  if ( doc ) 
    DeleteAttributes( doc ); //  
}


//-------------------------------------------------------------------------------
//   
// ---
void ShowDocumentAttr() 
{
  if ( doc ) 
    ChoiceAttr( doc );
}


//-------------------------------------------------------------------------------
//   
// ---
void CreateDocument3DAttr() //   3D 
{  
  if ( doc && docType == lt_DocAssemble3D || docType == lt_DocPart3D ) 
    LibCreateAttr( 0, NULL );  
}
  

//-------------------------------------------------------------------------------
//   3D 
// ---
void DeleteDocument3DAttr() 
{  
  if ( doc && docType == lt_DocAssemble3D || docType == lt_DocPart3D ) 
  {
    IUEnv<IDocument3D> doc3D( ksGetActive3dDocument() ); //  3D 
    if ( doc3D ) 
    {
      //  3D 
      IUEnv<IAttribute3DCollection> attrColl( doc3D->AttributeCollection( 0, 0, 0, 0, 0, doc3D.GetI() ) ); 
      
      int count = 0;
      if ( attrColl.GetI() ) 
        count = attrColl->GetCount();                  //  
      if ( count ) 
      {
        TCHAR buf[255];
        _stprintf( buf, _T(" =%i"), count );
        MessageT( buf );

        for ( int i = count - 1; i >= 0; i-- ) 
        {
          IUEnv<IAttribute3D> attr3D( attrColl->GetByIndex(i) ); //  
          if ( attr3D ) 
          {
            TCHAR password[255] = _T("");
            if ( ReadStringT( _T("   "), password, 255 ) ) 
            {
              //  
              ViewEditAttrT( attr3D->GetReference(), 1, password );
              //  
              if ( YesNoT( _T(" ?") ) == 1 ) 
                ksDeleteAttr3DT( doc3D.GetI(), attr3D.GetI(), password );
            }
          }
        }
        
        attrColl->Refresh();
        count = attrColl->GetCount();
        _stprintf( buf, _T(" =%i"), count );
        MessageT( buf );
      }
    }
  }
}


//-------------------------------------------------------------------------------
//   
// ---
void ShowDocument3DAttr() 
{  
  if ( doc && docType == lt_DocAssemble3D || docType == lt_DocPart3D ) 
  {
//    IUEnv<IDocument3D> doc3D( ksGetActive3dDocument() );
//    if ( doc3D ) 
      ksChoiceAttr3D( NULL ); // doc3D.GetI() );
  }
}


//-------------------------------------------------------------------------------
//      
// ---
void ShowObjects3DAttr() 
{  
  if ( doc && docType == lt_DocAssemble3D || docType == lt_DocPart3D ) 
  {
    IUEnv<IDocument3D> doc3D( ksGetActive3dDocument() );
    if ( doc3D ) 
    {
      //  
      IUEnv<IFeatureCollection> fColl ( doc3D->FeatureCollection( 0, 0, 0, 0, 0, o3d_unknown ) );
      if ( fColl )
        ksChoiceAttr3D( fColl.GetI() );                     //   
    }
    if ( docType == lt_DocAssemble3D ) 
    {
      IUEnv<IPart> part0( doc3D->GetPart(0) );              //  
      if ( part0 ) 
      {
        IUEnv<IFeature> iFeatureP0 ( part0->GetFeature() ); //   
        if ( iFeatureP0 )
        {
          //   
          IUEnv<IFeatureCollection> fCollP0 ( iFeatureP0->SubFeatureCollection( true, true ) );
          if ( fCollP0 )
            ksChoiceAttr3D( fCollP0.GetI() );               //  
        }
      }
    }
  }
}
