////////////////////////////////////////////////////////////////////////////////
//
// 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
//
////////////////////////////////////////////////////////////////////////////////
#pragma hdrstop

#include <objbase.h>
#include <initguid.h>

#ifndef __WINDOWS_H
#include <windows.h>
#endif

#ifndef __VALUES_H
#include "values.h"
#endif

#ifndef __STDIO_H
#include <stdio.h>
#endif

#ifndef __STRING_H
#include <string.h>
#endif

#ifndef __STDLIB_H
#include <stdlib.h>
#endif

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

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

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

#ifndef __STEP8_RH
#include "step8.rh"
#endif


//-------------------------------------------------------------------------------
//   
// ---
extern "C" unsigned int __export __pascal 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 


//-------------------------------------------------------------------------------
//   
// ---
extern "C" void __export __pascal LIBRARYENTRY( unsigned int comm )
{
  doc     = ksGetCurrentDocument( 0 );
  docType = ksGetDocumentType( doc );

  switch ( docType ) {
    case lt_DocTxtStandart:        //               7-   
    case lt_DocTxtUser:            //               8-   
    {
      int res = YesNo( "       \n"
                       "    ?" );
      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 )
{
  ColumnInfo parColumn; //     
    
  //   
  parColumn.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
  parColumn.fieldEnum = CreateArray( CHAR_STR_ARR, 0 );    //        

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


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

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

  ColumnInfo parColumn,  //    
             parStruct;  //     
  
  //   
  reference rArColumn = CreateArray( ATTR_COLUMN_ARR, 0 ); //   
  reference rArStruct = CreateArray( ATTR_COLUMN_ARR, 0 ); //    
  reference rArEnum   = CreateArray( CHAR_STR_ARR, 0 );    //    

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

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

  //   ,     
  AddArrayItem( rArColumn,             //   
                -1,                    //   
                &parColumn,            //    
                sizeof( parColumn ) ); //     
                
  //      - ( RECORD ),   columns   
  //  ,    . 
      
  //  
  strcpy( parColumn.header, "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;      //        
 
  //     
  //   
  strcpy( parStruct.header, "double" ); // o- 
  parStruct.type = DOUBLE_ATTR_TYPE;    //     - .
  parStruct.key  = 0;                   //  ,        
  strcpy( parStruct.def, "123456789" ); //   
  parStruct.flagEnum  = 0;              //   ,      
                                        //     1  0 
  parStruct.fieldEnum = 0;              //        
  parStruct.columns   = 0;              //          
  //    ,     
  AddArrayItem( rArStruct,             //   
                -1,                    //   
                &parStruct,            //    
                sizeof( parStruct ) ); //     
                
  //   
  strcpy( parStruct.header, "long" ); // o- 
  parStruct.type = LINT_ATTR_TYPE;    //     - .
  parStruct.key  = 0;                 //  ,        
  strcpy( parStruct.def, "1000000" ); //   
  parStruct.flagEnum  = 0;            //   ,      
                                      //     1  0 
  parStruct.fieldEnum = 0;            //        
  parStruct.columns   = 0;            //        
  //    ,     
  AddArrayItem( rArStruct,             //   
                -1,                    //   
                &parStruct,            //    
                sizeof( parStruct ) ); //     
                
  //   
  strcpy( parStruct.header, "char" ); // o- 
  parStruct.type = CHAR_ATTR_TYPE;    //     - .
  parStruct.key  = 0;                 //  ,        
  strcpy( parStruct.def, "10" );      //   
  parStruct.flagEnum = 0;             //   ,      
                                      //     1  0 
  parStruct.fieldEnum = 0;            //        
  parStruct.columns   = 0;            //        
  //    ,     
  AddArrayItem( rArStruct,             //   
                -1,                    //   
                &parStruct,            //    
                sizeof( parStruct ) ); //     
                  
  //   ,     
  AddArrayItem( rArColumn,             //   
                -1,                    //   
                &parColumn,            //    
                sizeof( parColumn ) ); //     
                
  //   
  strcpy( parColumn.header, "string" ); // o- 
  parColumn.type = STRING_ATTR_TYPE;    //     - .
  parColumn.key  = 0;                   //  ,        
  strcpy( parColumn.def, "text" );      //   
  parColumn.flagEnum  = 0;              //   ,      
                                        //     1  0 
  parColumn.fieldEnum = 0;              //        
  parColumn.columns   = 0;              //        
  
  //   ,     
  AddArrayItem( rArColumn,             //   
                -1,                    //   
                &parColumn,            //    
                sizeof( parColumn ) ); //     

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

  // C  
  double numbType = ksCreateAttrType( &parAttributeType, //    
                                      nameFile );        //    
  if ( numbType > 1 )  
  {
    char buf[255];
    sprintf( buf, "numbType = %f", numbType );
    Message( buf );
  }
  else
    MessageBoxResult(); //         

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


//-------------------------------------------------------------------------------
//   
// ---
void DelTypeAttr()
{
  char nameFile[255] = "";
  //   
  ChoiceFile( "*.lat", NULL, nameFile, 255 );

  if ( nameFile[0] || doc ) //      
  {   
    char password[255] = "";
    double numbType    = ChoiceAttrTypes( nameFile ); //   
  
    if ( numbType > 1 ) 
    { 
      // ReadDouble( "   ", 1000., 0, 1e12, &numbType ) ) 
      if ( ReadString( "   ", password, 255 ) ) 
        //   
        if ( !DeleteAttrType( numbType,    //    
                              nameFile,    //    
                              password ) ) //   
          MessageBoxResult(); //      
    }
  }
}


//-------------------------------------------------------------------------------
//    
// ---
void ShowTypeAttr() 
{
  char nameFile[255] = "";
  //   
  ChoiceFile( "*.lat", NULL, nameFile, 255 );

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

      //       
      if ( !ksGetAttrType( numbType, nameFile, &rAttributeType ) )
        MessageBoxResult(); //         
      else 
      {
        char buf[500]; 
        sprintf( buf, "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 );
        Message( buf );
     
        ShowColumns( rAttributeType.columns, FALSE ); //     
      }
      //    
      DeleteArray( rAttributeType.columns );
    }
  }
}


//-------------------------------------------------------------------------------
//   
// ---
void ChangeType()
{
  char nameFile[255] = "";
  
  //   
  ChoiceFile( "*.lat", NULL, nameFile, 255 );

  if ( nameFile[0] || doc )  //      
  {
    char password[255] = "";
    // double numbType;
    double numbType = ChoiceAttrTypes( nameFile );
    if ( numbType > 1000 ) 
    {
      if ( ReadString( "   ", password, 255 ) ) 
      {
        ksAttributeType rAttributeType; //     
        rAttributeType.columns = CreateArray( ATTR_COLUMN_ARR, 0 ); //        

        //       
        if ( !ksGetAttrType( numbType,           //   
                             nameFile,           //    
                             &rAttributeType ) ) //     
          MessageBoxResult(); //         
        else
        {
          //      
          ColumnInfo parColumn1; //        
          parColumn1.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
          parColumn1.fieldEnum = CreateArray( CHAR_STR_ARR, 0 );    //        

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

          strcpy( 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 = ksSetAttrType( numbType,        //   
                                    nameFile,        //    
                                    &rAttributeType, //     
                                    password );      //   
          if ( numbType > 1 )  
          {
            char buf[255];
            sprintf( buf, "numbType = %f", numbType );
            Message( buf );
          }
          else
            MessageBoxResult(); //        
          
            //   
          DeleteArray( parColumn1.columns );   //        
          DeleteArray( parColumn1.fieldEnum ); //        

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

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


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

  char nameFile[255] = "";

  ChoiceFile( "*.lat", NULL, nameFile, 255 );    //   
  double numbType = ChoiceAttrTypes( nameFile ); //     

  if ( numbType > 1 )
  {
    //   
    reference attr = 0;
    if ( obj )
      attr = ksCreateAttr( obj,          //   
                           &parAttribute,//    
                           numbType,     //   
                           nameFile );   //  
    else
    {
      IUEnv<IAttribute3D> attr3D ( ksCreateAttr3D( fObj,          //     3D 
                                                   &parAttribute, //    
                                                   numbType,      //   
                                                   nameFile ) );  //  
      if ( attr3D )
        attr = attr3D->GetReference();
    }
    if ( attr )     
      ViewEditAttr( 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, OLESTR( " " ) ) );
      if ( !ReturnResult() ) 
      {
        if ( selEnt.GetI() )
        {
          obj = selEnt->GetFeature();
        }
      }
    }
  }
  return obj;
}


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

      //     
      if ( Cursor( &info, &x, &y, 0 ) )
      {
        //       
        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- 
    {
      IUPTR (Feature) feature3D ( Select3DFeature() );
      if ( feature3D ) 
      {
        LibCreateAttr( NULL, feature3D ); 
      }
      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 )
      {
        char password[255] = "";
         
        if ( ReadString( "   ", password, 10 ) )
        {  
          //  
          if ( !DeleteAttr( rObject,     //   
                            rAttribute,  //   
                            password ) ) //   
            MessageBoxResult(); //         
        }
         
        //    ,    
        rAttribute = MoveAttrIterator( rIterator, //   
                                      'N',        //   'F'/'N'
                                       0 );       //      ,  NULL,  
      }  
      DeleteIterator( rIterator );  
    }
  }
}


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

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


//-------------------------------------------------------------------------------
//    3
// ---
void DelObj3DAttr() 
{
  IUPTR (Feature) feature3D ( Select3DFeature() );
  if ( feature3D ) 
  {
    IUEnv<IAttribute3DCollection> attrColl( feature3D->AttributeCollection( 0, 0, 0, 0, 0) ); 
    int count = attrColl->GetCount();
    if ( count ) 
    {
      char buf[255];
      sprintf( buf, " =%i", count );
      Message( buf );

      for ( int i = count - 1; i >= 0; i-- ) 
      {
        IUEnv<IAttribute3D> attr3D( attrColl->GetByIndex(i) );
        if ( attr3D ) 
        {
          char password[255] = "";
           
          if ( ReadString( "   ", password, 10 ) )
          {  
            //  
            if ( !ksDeleteAttr3D( feature3D,     //   
                                  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 
  {
    double d; 
    char s[MAX_TEXT_LENGTH];
    long l;
  } bufStruct;
  
  //     
  RequestInfo info;
  memset( &info, 0, sizeof( info ) );
  
  //      
  info.prompt = " ";
  
  //     
  double x, y; 

  //     
  if ( Cursor( &info, &x, &y, 0 ) )
  {
    //       
    reference rObject = FindObj( x, y,  //  
                                 1e6 ); //   -     x,y
    if ( rObject )
    {
      //   
      LightObj( rObject, 1 );
      Message( "  " );
      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 );                //                                 
          char buf[255];
          sprintf( buf, "key1 = %d, key2 = %d, key3 = %d, key4 = %d, numbType = %f", key1, key2, key3, key4, numbType );
          Message( buf );
 

          //  
          unsigned int countColums;        
          //     
          GetAttrTabInfo( rAttribute,     //   
                          0,              //  
                          &countColums ); //         
          sprintf ( buf, "countColums = %d", countColums );
          Message( buf );
 
          //   
          ColumnInfo parColumn; //     
          //   
          parColumn.columns   = CreateArray( ATTR_COLUMN_ARR, 0 ); //        
          parColumn.fieldEnum = CreateArray( CHAR_STR_ARR, 0 );    //        
          for ( unsigned int i = 0; i < countColums; i++ ) 
          {
            //    
            GetAttrColumnInfo( rAttribute,   //   
                               0,            //      
                               &parColumn ); //     
              
            //    
            sprintf( buf, "i = %d, header = %s,\ntype = %d, def = %s, flagEnum = %d", 
                     i, parColumn.header, parColumn.type, parColumn.def, parColumn.flagEnum );
            Message( buf );
          }
          //   
          DeleteArray( parColumn.columns );   //        
          DeleteArray( parColumn.fieldEnum ); //        

          //    
          GetAttrRow( rAttribute,            //    
                      0,                     //     
                      0,                     //       
                      &bufStruct,            //     
                      sizeof( bufStruct ) ); //  
          sprintf ( buf, "d = %f, s = %s, l = %ld", bufStruct.d, bufStruct.s, bufStruct.l );
          Message( buf );

          //   
          bufStruct.d = 123.123;
          strcpy( bufStruct.s, "1234567\nasdfgh\nzxcvb" );
          bufStruct.l = 88888l;
          
          SetAttrRow( rAttribute,            //    
                      0,                     //     
                      0,                     //       
                      &bufStruct,            //    
                      sizeof( bufStruct ),   //  
                      "111" );               //    
        
          memset( &buf, 0, sizeof( bufStruct ) );
                
          //    
          GetAttrRow( rAttribute,            //    
                      0,                     //     
                      0,                     //       
                      &bufStruct,            //     
                      sizeof( bufStruct ) ); //  
          sprintf ( buf, "d = %f, s = %s, l = %ld", bufStruct.d, bufStruct.s, bufStruct.l );
          Message( buf );
        
          //    ,    
          rAttribute = MoveAttrIterator( rIterator, //   
                                          'N',       //   'F'/'N' 
                                          0 );       //      ,  NULL,  
        }
        DeleteIterator( rIterator ); 
      }  
    }
  }  
}


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

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


//-------------------------------------------------------------------------------
//   3D 
// ---
void ShowObj3DAttr()
{
  IUPTR (Feature) feature3D ( Select3DFeature() );
  if ( feature3D )
  {
    ksChoiceAttr3D( feature3D );
  }
}


//-------------------------------------------------------------------------------
//  
// ---
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()
{
  char nameFile[255] = "";
  
  //   
  if ( !ChoiceFile( "*.lat", NULL, nameFile, 255 ) )
    nameFile[0] = '\0'; //    ,         

  //              
  double numbType = ChoiceAttrTypes( nameFile );

  if ( numbType > 1 )  
  {
    char buf[255];
    sprintf( buf, "numbType = %f", numbType );
    Message( buf );
  }
}


//-------------------------------------------------------------------------------
//  
// ---
void ShowType()
{
  char nameFile[255] = "";
  
  //   
  ChoiceFile( "*.lat", NULL, nameFile, 255 );
  
  double numbType = ChoiceAttrTypes( nameFile );
  if ( numbType > 1000 ) {

    char password[255] = "";
    if ( ReadString( "   ", password, 255 ) ) 
      //    
      ViewEditAttrType( nameFile,   //    
                        2,          //   ( 1 - , 2 -  )
                        numbType,   //   
                        password ); //   
  }
}


//-------------------------------------------------------------------------------
//   3D 
// ---
void WalkFromObj3DWithAttr()
{
  IUPTR (Feature) feature3D ( Select3DFeature() );             //   
  if ( feature3D )
  {
    //   
    IUEnv<IAttribute3DCollection> attrColl( feature3D->AttributeCollection( 0, 0, 0, 0, 0) ); 
    int count = attrColl->GetCount();                          //  
    if ( count ) {
      char buf[255];
      sprintf( buf, " =%i", count );
      Message( buf );

      for ( int i = count - 1; i >= 0; i-- )
      {
        IUEnv<IAttribute3D> attr3D( attrColl->GetByIndex(i) ); //     
        if ( attr3D )
        {
          char* password = "";
          if ( ReadString( "   ", 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++ )
//                cMng->Choose( ifColl->GetByIndex(i) );
//           }
            ViewEditAttr( attr3D->GetReference(), 1, password ); //  
//            if ( YesNo( " ?" ) == 1 ) 
//              ksDeleteAttr3D( feature3D, attr3D.GetI(), password );
//            if ( cMng )
//              cMng->UnChooseAll();
          }
        }
      }
    }
  }
}


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

  //     
  if ( Cursor( &info, &x, &y, 0 ) )
  {
    //       
    reference rObject = FindObj( x, y,  //  
                                 1e6 ); //   -     x,y
    if ( rObject )
    {
      //   
      LightObj( rObject, 1 );
      Message( "  " );
      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 )
        {
          //    
          ViewEditAttr( rAttribute, //    
                        1,          //   ( 1 - , 2 -  )
                        0 );        //   
          
          //    ,    
          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 = attrColl->GetCount();                  //  
      if ( count ) 
      {
        char buf[255];
        sprintf( buf, " =%i", count );
        Message( buf );

        for ( int i = count - 1; i >= 0; i-- ) 
        {
          IUEnv<IAttribute3D> attr3D( attrColl->GetByIndex(i) ); //  
          if ( attr3D ) 
          {
            char password[255] = "";
            if ( ReadString( "   ", 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++ )
                  cMng->Choose( ifColl->GetByIndex(i) );
              }
              //  
              ViewEditAttr( attr3D->GetReference(), 1, password );
              //  
              if ( YesNo( " ?" ) == 1 ) 
                ksDeleteAttr3D( doc3D.GetI(), attr3D.GetI(), password );
              if ( cMng )
                cMng->UnChooseAll(); //  
            }
          }
        }
        
        attrColl->Refresh();
        count = attrColl->GetCount();
        sprintf( buf, " =%i", count );
        Message( 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() );               //  
        }
      }
    }
  }
}