//---------------------------------------------------------------------------
#include <vcl.h>

#pragma hdrstop

#include <windows.h>
#include <stdio.h>

#include <ldefin2d.h>
#include <ksConstants.h>

#ifdef __LIGHT_VERSION__
#include <Kl_TLB.h>
#else
#include <Ks_TLB.h>
#endif
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
// ---
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}

//------------------------------------------------------------------------------
//
// ---
extern "C" unsigned int far __export __pascal LibraryId(){
  return 100;
}

//------------------------------------------------------------------------------
//
// ---
extern "C" IDispatch* far __export WINAPI CreateKompasObject();

KompasObject* kompas = NULL;

void StrIndefiniteArray();
void PointIndefiniteArray();
void TextIndefiniteArray();
void AttrIndefiniteArray();
void PolyLineArray();
void RectArray();

extern "C" void far __export __pascal  LibraryEntry( UINT Comm ){
  kompas = (KompasObject*)::CreateKompasObject();
  if ( kompas ) {
    switch ( Comm ) {
     case 1: //  
       StrIndefiniteArray();
       break;
     case 2: //  
       PointIndefiniteArray();
       break;
     case 3: //    ""
       TextIndefiniteArray();
       break;
     case 4: //    
       AttrIndefiniteArray();
       break;
     case 5: //  
       PolyLineArray();
       break;
     case 6: //   
       RectArray();
        break;
    }
    kompas->Release();
  }
}

//------------------------------------------------------------------------------
//
// ---
void StrIndefiniteArray() {
  //   
  ksDynamicArray* arr     = (ksDynamicArray*)kompas->GetDynamicArray( CHAR_STR_ARR );
  ksChar255*      charBuf = (ksChar255*)kompas->GetParamStruct( ko_Char255 );
  if ( arr && charBuf ) {
    charBuf->str = StringToOleStr( "12345" );
    //  
    arr->ksAddArrayItem( -1, charBuf );

    charBuf->str = StringToOleStr( "67890" );
    arr->ksAddArrayItem( -1, charBuf );

    charBuf->str = StringToOleStr( "qwerty" );
    arr->ksAddArrayItem( -1, charBuf );

    kompas->ksMessageBoxResult();

    //  
    int n = arr->ksGetArrayCount();

    char buf[128];
    sprintf( buf, " n = %d ", n );
    kompas->ksMessage( StringToOleStr(buf) );

    for( int i = 0; i < n; i++ ) {
      arr->ksGetArrayItem( i, charBuf );
      kompas->ksMessage( charBuf->str );
    }

    //     1
    arr->ksExcludeArrayItem( 1 );
    n = arr->ksGetArrayCount();

    //  
    for ( int i = 0; i < n; i++ ) {
      arr->ksGetArrayItem( i, charBuf );
      kompas->ksMessage( StringToOleStr(buf) );
    }

    kompas->ksMessageBoxResult();
    arr->ksDeleteArray();
  }
}

//------------------------------------------------------------------------------
//
// ---
void PointIndefiniteArray() {
  ksMathPointParam* mathPar = (ksMathPointParam*)kompas->GetParamStruct( ko_MathPointParam );
  ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
  if ( mathPar && arr ) {
    mathPar->x = 10;
    mathPar->y = 10;
    arr->ksAddArrayItem( -1, mathPar );

    mathPar->x = 20;
    mathPar->y = 20;
    arr->ksAddArrayItem( -1, mathPar );

    mathPar->x = 30;
    mathPar->y = 30;
    arr->ksAddArrayItem( -1, mathPar );

    kompas->ksMessageBoxResult();

    //  
    int n = arr->ksGetArrayCount();
    char buf[128];
    ::sprintf( buf, " n = %d ", n );
    kompas->ksMessage( StringToOleStr(buf) );

    for( int i = 0; i < n; i++ ) {
      arr->ksGetArrayItem( i, mathPar );
      sprintf( buf, "i = %d  x = %5.1f y = %5.1f ", i, mathPar->x, mathPar->y );
      kompas->ksMessage( StringToOleStr(buf) );
    }

    //   1- 
    mathPar->x = 50;
    mathPar->y = 50;
    arr->ksSetArrayItem( 1, mathPar );

    //   0- 
    mathPar->x = 60;
    mathPar->y = 60;
    arr->ksSetArrayItem( 0, mathPar );

    //  
    n = arr->ksGetArrayCount();
    for( int i = 0; i < n; i++ ) {
      arr->ksGetArrayItem( i, mathPar );
      ::sprintf( buf, "i = %d  x = %5.1f y = %5.1f ", i, mathPar->x, mathPar->y );
      kompas->ksMessage( StringToOleStr(buf) );
    }

    arr->ksDeleteArray();
  }

  kompas->ksMessageBoxResult();
}

//--------------------------------------------------------------------------
//          ,
//       ,    
//    ,   
//  (  ,  ,   . .)
//--------------------------------------------------------------------------
void TextIndefiniteArray() {
  ksTextItemParam* itemPar = (ksTextItemParam*)kompas->GetParamStruct( ko_TextItemParam );
  ksTextLineParam* linePar = (ksTextLineParam*)kompas->GetParamStruct( ko_TextLineParam );

  if ( itemPar && linePar ) {
    itemPar->Init();
    linePar->Init();
    linePar->style = 1;
    ksDynamicArray* itemArr = (ksDynamicArray*)linePar->GetTextItemArr();
    ksTextItemFont* font = (ksTextItemFont*)itemPar->GetItemFont();
    if ( font && itemArr ) {
      font->height    = 10;   //  
      font->ksu       = 1;    //  
      font->color     = 1000; // 
      font->bitVector = 1;    //   (, , ,   (, ,   ))
      itemPar->s      = StringToOleStr( "1  1 " );
      itemArr->ksAddArrayItem( -1, itemPar );

      font->height    = 20;   //  
      font->ksu       = 2;    //  
      font->color     = 2000; // 
      font->bitVector = 2;    //   (, , ,   (, ,   ))
      itemPar->s      = StringToOleStr( "2  1 " );
      itemArr->ksAddArrayItem( -1, itemPar );

      //    
      ksDynamicArray* lineArr = (ksDynamicArray*)kompas->GetDynamicArray( TEXT_LINE_ARR );
      if ( lineArr ) {
        //  1- 
        lineArr->ksAddArrayItem( -1, linePar );

        //   ,       
        itemArr->ksClearArray();

        //    
        font->height    = 30;   //  
        font->ksu       = 3;    //  
        font->color     = 3000; // 
        font->bitVector = 3;    //   (, , ,   (, ,   ))
        itemPar->s      = StringToOleStr( "1  2 " );
        itemArr->ksAddArrayItem( -1, itemPar );

        font->height    = 40;   //  
        font->ksu       = 4;    //  
        font->color     = 4000; // 
        font->bitVector = 4;    //   (, , ,   (, ,   ))
        itemPar->s      = StringToOleStr( "2  2 " );
        itemArr->ksAddArrayItem( -1, itemPar );

        linePar->style = 1;
        //  2- 
        lineArr->ksAddArrayItem( -1, linePar );

        //     
        kompas->ksMessageBoxResult();

        int n = lineArr->ksGetArrayCount();
        char buf[128];
        ::sprintf( buf, "n = %d ", n );
        kompas->ksMessage( StringToOleStr(buf) );

        //    
        for ( int i = 0; i < n; i++ ) { //    
          lineArr->ksGetArrayItem( i, linePar );
          ::sprintf( buf, "i = %d style = %d   ", i, linePar->style );
          kompas->ksMessage( StringToOleStr(buf) );
          itemArr = (ksDynamicArray*)linePar->GetTextItemArr();
          if ( itemArr ) {
            int n1 = itemArr->ksGetArrayCount();
            for ( int j = 0; j < n1; j++ ) { //     
              itemArr->ksGetArrayItem( j, itemPar );
              font = (ksTextItemFont*)itemPar->GetItemFont();
              ::sprintf( buf, "j = %d h = %5.1f  s = %s ", j, font->height, WideCharToString(itemPar->s) );
              kompas->ksMessage( StringToOleStr(buf) );
            }
          }
        }

        lineArr->ksDeleteArray();
      }

      itemArr->ksDeleteArray();
    }
  }

  kompas->ksMessageBoxResult(); //     
}

//----------------------------------------------------------------------------
//
static void ShowColumns( ksDynamicArray* array, BOOL fl ) {
  if ( array ) {
    ksColumnInfoParam* par = (ksColumnInfoParam*)kompas->GetParamStruct( ko_ColumnInfoParam );
    if ( par ) {
      par->Init();
      char buf[128];
      char s[10];

      if ( fl )
        strcpy( s, "" );
      else
        s[0] = '\0';

      ksDynamicArray* columnArr = (ksDynamicArray*)par->GetColumns();
      ksDynamicArray* fieldEnum = (ksDynamicArray*)par->GetFieldEnum();
      if ( columnArr && fieldEnum ) {
        int n = array->ksGetArrayCount();
        for ( int i = 0; i < n; i++ ) {
          if ( !array->ksGetArrayItem(i, par) )
            kompas->ksMessageBoxResult();         //     
          else {
            //      
            sprintf( buf, "%s i = %d header = %s type = %d def = %s flagEnum = %d", s, i, par->header,
                     par->type, par->def, par->flagEnum ? 1 : 0 );
            kompas->ksMessage( StringToOleStr(buf) );
            if( par->type == RECORD_ATTR_TYPE )   //  
              ShowColumns( (ksDynamicArray*)par->GetColumns(), true );
            else {
              if ( par->flagEnum )  {             //   
                ksDynamicArray* fEnum = (ksDynamicArray*)par->GetFieldEnum();
                int n1 = fEnum->ksGetArrayCount();
                kompas->ksMessage( StringToOleStr(" ") );
                ksChar255* charBuf = (ksChar255*)kompas->GetParamStruct( ko_Char255 );
                if ( charBuf ) {
                  for ( int i1 = 0; i1 < n1; i1++ ) {
                    if( !fEnum->ksGetArrayItem(i1, charBuf) )
                      kompas->ksMessageBoxResult();  //     
                    else
                      kompas->ksMessage( charBuf->str );
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


//------------------------------------------------------------------------------
//         ,
//       
// ---
void AttrIndefiniteArray() {
  if ( kompas ) {
  /*
      3 
       int    ( 100, 200, 300 )
     -   
   struct {
     double ;//   123456789
     long   ;//   1000000
     char   ;//   10
   }
         "text"
  */

    ksDynamicArray* pCol    = (ksDynamicArray*)kompas->GetDynamicArray( ATTR_COLUMN_ARR );
    ksDynamicArray* pStruct = (ksDynamicArray*)kompas->GetDynamicArray( ATTR_COLUMN_ARR );
    ksDynamicArray* pEnum   = (ksDynamicArray*)kompas->GetDynamicArray( CHAR_STR_ARR    );

    ksColumnInfoParam* parCol1 = (ksColumnInfoParam*)kompas->GetParamStruct( ko_ColumnInfoParam );
    if ( pCol && pStruct && pEnum && parCol1 ) {
      parCol1->Init();
      //  
      parCol1->header   = StringToOleStr( "int" ); // o- 
      parCol1->type     = INT_ATTR_TYPE;           //     - .
      parCol1->key      = 0;                       //  ,        
      parCol1->def      = StringToOleStr( "100" ); //   
      parCol1->flagEnum = 1;                       //   ,    
                                                   //       1  0 
                                                   //   ,    
                                                   //       1  0 
      parCol1->SetFieldEnum( pEnum );              //     ()
      parCol1->SetColumns( 0 );                    //        

      ksChar255* charBuf = (ksChar255*)kompas->GetParamStruct( ko_Char255 );
      if ( charBuf ) {
        charBuf->str = StringToOleStr( "100" );
        pEnum->ksAddArrayItem( -1, charBuf );

        charBuf->str = StringToOleStr( "200" );
        pEnum->ksAddArrayItem( -1, charBuf );

        charBuf->str = StringToOleStr( "300" );
        pEnum->ksAddArrayItem( -1, charBuf );

        pCol->ksAddArrayItem( -1, parCol1 );

        ksColumnInfoParam* parCol2 = (ksColumnInfoParam*)kompas->GetParamStruct( ko_ColumnInfoParam );
        if ( parCol2 ) { //  
          parCol2->header   = StringToOleStr( "struct" ); // o- 
          parCol2->type     = RECORD_ATTR_TYPE;           //     - .
          parCol2->key      = 0;                          //  ,        
          parCol2->def      = StringToOleStr( "\0" );     //   
          parCol2->flagEnum = 0;
          parCol2->SetFieldEnum( 0 );                     //     ()
          parCol2->SetColumns( pStruct );                 //        

          ksColumnInfoParam* parStruct = (ksColumnInfoParam*)kompas->GetParamStruct( ko_ColumnInfoParam );
          if ( parStruct ) {
            //     
            //    
            parStruct->header   = StringToOleStr("double");    // o- 
            parStruct->type     = DOUBLE_ATTR_TYPE;            //     - .
            parStruct->key      = 0;                           //  ,        
            parStruct->def      = StringToOleStr("123456789"); //   
            parStruct->flagEnum = 0;                           //   ,    
                                                               //       1  0 
            parStruct->SetFieldEnum( 0 );                      //     ()
            parStruct->SetColumns( 0 );                        //        

            pStruct->ksAddArrayItem( -1, parStruct );

            //   
            parStruct->header   = StringToOleStr("long");      // o- 
            parStruct->type     = LINT_ATTR_TYPE;              //     - .
            parStruct->key      = 0;                           //  ,        
            parStruct->def      = StringToOleStr("1000000");   //   
            parStruct->flagEnum = 0;                           //   ,    
                                                               //       1  0 
            parStruct->SetFieldEnum( 0 );                      //     ()
            parStruct->SetColumns( 0 );                        //        

            pStruct->ksAddArrayItem( -1, parStruct );

            //   
            parStruct->header   = StringToOleStr("char");      // o- 
            parStruct->type     = CHAR_ATTR_TYPE;              //     - .
            parStruct->key      = 0;                           //  ,        
            parStruct->def      = StringToOleStr("10");        //   
            parStruct->flagEnum = 0;                           //   ,    
                                                               //       1  0 
            parStruct->SetFieldEnum( 0 );                      //     ()
            parStruct->SetColumns( 0 );                        //        

            pStruct->ksAddArrayItem( -1, parStruct );


            pCol->ksAddArrayItem( -1, parCol2 );

            ksColumnInfoParam* parCol3 = (ksColumnInfoParam*)kompas->GetParamStruct( ko_ColumnInfoParam );
            if ( parCol3 ) {
              //   
              parCol3->header   = StringToOleStr( "string" ); // o- 
              parCol3->type     = STRING_ATTR_TYPE;           //     - .
              parCol3->key      = 0;                          //  ,        
              parCol3->def      = StringToOleStr( "text" );   //   
              parCol3->flagEnum = 0;                          //   ,    
                                                              //       1  0 
              parStruct->SetFieldEnum( 0 );                   //     ()
              parStruct->SetColumns( 0 );                     //        

              pCol->ksAddArrayItem( -1, parCol3 );

              kompas->ksMessageBoxResult();  //     

              //   
              ::ShowColumns( pCol, false ); //  

              kompas->ksMessageBoxResult();  //     

              //     2->1 1->3 3->2
              pCol->ksSetArrayItem( 0, parCol2 );
              pCol->ksSetArrayItem( 2, parCol1 );
              pCol->ksSetArrayItem( 1, parCol3 );

              //   
              ShowColumns( pCol, FALSE );    //  
            }
          }
        }
      }

      pCol->ksDeleteArray();
      pStruct->ksDeleteArray();
      pEnum->ksDeleteArray();

      kompas->ksMessageBoxResult();  //     
    }
  }
}

//------------------------------------------------------------------------------
//
// ---
void PolyLineArray() {
  if ( kompas ) {
    //   
    ksDynamicArray* pPoly = (ksDynamicArray*)kompas->GetDynamicArray( POLYLINE_ARR );
    if ( pPoly ) {
      ksMathPointParam* par = (ksMathPointParam*)kompas->GetParamStruct( ko_MathPointParam );
      if ( par ) {
        par->x = 10;
        par->y = 10;

        //   
        ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
        if ( arr ) {
          arr->ksAddArrayItem( -1, par );

          par->x = 100;
          par->y = 100;
          arr->ksAddArrayItem( -1, par );

          par->x = 1000;
          par->y = 1000;
          arr->ksAddArrayItem( -1, par );

          //      
          pPoly->ksAddArrayItem( -1, arr );

          kompas->ksMessageBoxResult();

          //   
          arr->ksClearArray();
          par->x = 20;
          par->y = 20;
          arr->ksAddArrayItem( -1, par );

          par->x = 200;
          par->y = 200;

          arr->ksAddArrayItem( -1, par );

          par->x = 2000;
          par->y = 2000;

          arr->ksAddArrayItem( -1, par );

          //      
          pPoly->ksAddArrayItem( -1, arr );

          kompas->ksMessageBoxResult();

          //   
          arr->ksClearArray();
          par->x = 30;
          par->y = 30;
          arr->ksAddArrayItem( -1, par );

          par->x = 300;
          par->y = 300;
          arr->ksAddArrayItem( -1, par );

          par->x = 3000;
          par->y = 3000;

          arr->ksAddArrayItem( -1, par );

          //      
          pPoly->ksAddArrayItem( -1, arr );

          kompas->ksMessageBoxResult();

          char buf[128];
          ::sprintf( buf, "n = %i", pPoly->ksGetArrayCount() );
	  kompas->ksMessage( StringToOleStr(buf) );
          pPoly->ksGetArrayItem( 1, arr );
          //  2-   
          int n = arr->ksGetArrayCount();
          for ( int i = 0; i < n; i++ ) {
            arr->ksGetArrayItem( i, par );
	    ::sprintf( buf, "i = %d  x = %5.1f y = %5.1f", i, par->x, par->y );
            kompas->ksMessage( StringToOleStr(buf) );
          }

          //   2 -    2- 
          par->x = 50;
          par->y = 50;
          arr->ksSetArrayItem( 1, par );

          par->x = 500;
          par->y = 500;
          arr->ksSetArrayItem( 0, par );

          pPoly->ksSetArrayItem( 1, arr );
          n = pPoly->ksGetArrayCount();

          //   
          ksDynamicArray* arr2 = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
          if ( arr2 ) {
            //   
            for ( int i = 0; i < n; i++ ) {
              pPoly->ksGetArrayItem( i, arr2 );
              for( int j = 0; j < arr2->ksGetArrayCount(); j++ ) {
                arr2->ksGetArrayItem( j, par );
                ::sprintf( buf, "j = %d  x = %5.1f y = %5.1f ", j, par->x, par->y );
                kompas->ksMessage( StringToOleStr(buf) );
              }
            }

            arr2->ksDeleteArray();
          }

          kompas->ksMessageBoxResult();
          //  
          arr->ksDeleteArray();
          pPoly->ksDeleteArray();
        }
      }
    }
  }
}

//------------------------------------------------------------------------------
//
// ---
void RectArray() {
  if ( kompas ) {
    //  
    ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( RECT_ARR );
    if ( arr ) {
      ksRectParam* par = (ksRectParam*)kompas->GetParamStruct( ko_RectParam );
      ksMathPointParam* mathPar = (ksMathPointParam*)kompas->GetParamStruct( ko_MathPointParam );
      if ( par && mathPar ) {
        mathPar->x = 10;
        mathPar->y = 10;
        par->SetpTop( mathPar );

        mathPar->x = 20;
        mathPar->y = -10;
        par->SetpBot( mathPar );

        //  
        arr->ksAddArrayItem( -1, par );

        mathPar->x = 20;
        mathPar->y = 50;
        par->SetpTop( mathPar );

        mathPar->x = 50;
        mathPar->y = 10;
        par->SetpBot( mathPar );
        arr->ksAddArrayItem( -1, par );

        mathPar->x = 20;
        mathPar->y = 150;
        par->SetpTop( mathPar );

        mathPar->x = 50;
        mathPar->y = 110;
        par->SetpBot( mathPar );
        arr->ksAddArrayItem( -1, par );

        kompas->ksMessageBoxResult();
        //  
        int n = arr->ksGetArrayCount();
        char buf[128];
        ::sprintf( buf, "n = %d", n );
	kompas->ksMessage( StringToOleStr(buf) );
        ksMathPointParam* mathPar2 = (ksMathPointParam*)kompas->GetParamStruct( ko_MathPointParam );
        if ( mathPar2 ) {
          for ( int i = 0; i < n; i++ ) {
            arr->ksGetArrayItem( i, par );
            mathPar  = (ksMathPointParam*)par->GetpTop();
            mathPar2 = (ksMathPointParam*)par->GetpBot();
            ::sprintf( buf, "i = %d  x1 = %5.1f y1 = %5.1f \n      x2 = %5.1f y2 = %5.1f ", i, mathPar->x, mathPar->y,
                       mathPar2->x, mathPar2->y );
            kompas->ksMessage( StringToOleStr(buf) );
          }

          //  
          mathPar->x  = -20;
          mathPar->y  = -50;
          par->SetpTop( mathPar );

          mathPar->x = 20;
          mathPar->y = -10;
          par->SetpBot( mathPar );
          arr->ksSetArrayItem( 0, par );

          mathPar->x  = 0;
          mathPar->y  = 0;
          par->SetpTop( mathPar );

          mathPar->x = 10;
          mathPar->y = -20;
          par->SetpBot( mathPar );
          arr->ksSetArrayItem( 1, par );

          mathPar->x  = 5;
          mathPar->y  = 5;
          par->SetpTop( mathPar );

          mathPar->x = 25;
          mathPar->y = 0;
          par->SetpBot( mathPar );
          arr->ksAddArrayItem( -1, par );
          //  
          int n = arr->ksGetArrayCount();

          for ( int i = 0; i < n; i++ ) {
            arr->ksGetArrayItem( i, par );
            mathPar  = (ksMathPointParam*)par->GetpTop();
            mathPar2 = (ksMathPointParam*)par->GetpBot();
	    ::sprintf( buf, "i = %d  x1 = %5.1f y1 = %5.1f \n  x2 = %5.1f y2 = %5.1f ", i, mathPar->x, mathPar->y,
                       mathPar2->x, mathPar2->y );

            kompas->ksMessage( StringToOleStr(buf) );
          }

          kompas->ksMessageBoxResult();
          //  
          arr->ksDeleteArray();
        }
      }
    }
  }
}

