//---------------------------------------------------------------------------

#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" IDispatch* far __export WINAPI CreateKompasObject();

KompasObject* kompas = NULL;

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

#define SPC_NAME  5

void TypeAttrBolt();
void CreateDet( ksDocument2D * doc, ksSpcDocument * spc );
void CreateStandart( ksDocument2D * doc, ksSpcDocument * spc );
void DecomposeSpc( ksDocument2D * doc );
void ShowSpc( ksDocument2D * doc );

reference  EditSpcObjDet( reference geom, ksDocument2D * doc, ksSpcDocument * spc );
void DrawPosLeader( reference spcObj, ksDocument2D * doc );
reference EditStandartSpcObj ( reference geom, ksDocument2D * doc, ksSpcDocument * spc, reference spcObj );

char buf[128];

//------------------------------------------------------------------------------
//
// ---
extern "C" void far __export __pascal  LibraryEntry( UINT Comm ) {
  kompas = (KompasObject*)::CreateKompasObject();
  if ( kompas ) {
    ksDocument2D * doc( (ksDocument2D*)kompas->Document2D() );
    ksSpcDocument * spc( (ksSpcDocument*)kompas->SpcDocument() );
    ksDocument2D * docActive( (ksDocument2D*)kompas->ActiveDocument2D() );
    if ( !docActive && !spc )
      return;

    if ( Comm == 2 || Comm == 3 ) {
      if ( docActive ) {
        switch ( Comm ) {
          case 2  : ::CreateDet( docActive, spc );        break; //   
          case 3  : ::CreateStandart( docActive, spc);    break; //  
        }
      }
			else
				kompas->ksError( StringToOleStr("    \n  /") );
    }

    switch ( Comm ) {
      case 1  : ::TypeAttrBolt();               break; //    
      case 4  : ::DecomposeSpc( doc );          break; //k   
      case 5  : ::ShowSpc( docActive );               break; // 
    }
   }
}

//------------------------------------------------------------------------------
//      ""
// ---
reference  EditSpcObjDet( reference geom, ksDocument2D * doc, ksSpcDocument * spc ) {
  reference spcObj = 0;
  //    ,      
  ksSpecification * specification = NULL;
  if ( doc )
    specification = (ksSpecification *)doc->GetSpecification();
  else
    if ( spc )
      specification = (ksSpecification *)spc->GetSpecification();

  if (!specification)
    return 0;

  if ( doc && doc->ksEditMacroMode( ) ) {
    //    
    spcObj = specification->ksGetSpcObjForGeom( StringToOleStr("graphic.lyt"), //  
                                   1,         //     
                                   0,         //  
                                   1, 1 );
    //   
    if ( !specification->ksSpcObjectEdit( spcObj ) )
      spcObj  = 0;
  }

  //  ,      
  if( spcObj || specification->ksSpcObjectCreate( StringToOleStr("graphic.lyt"), //  
                                   1,         //     
                                   20,  0,    //   
                                   0,0 )) {    // 

    ksUserParam * par( (ksUserParam*)kompas->GetParamStruct(ko_UserParam) );
 	  ksLtVariant * item( (ksLtVariant*)kompas->GetParamStruct(ko_LtVariant) );
		ksDynamicArray * arr( (ksDynamicArray*)kompas->GetDynamicArray(LTVARIANT_ARR) );
		if ( !par || !item || !arr )
			return 0;
		par->Init();
		par->SetUserArray( arr );
  	item->Init();
		item->set_strVal(StringToOleStr(""));//.SetDoubleVal( 0 );
		arr->ksAddArrayItem( -1, item );
    //
    specification->ksSpcChangeValue( 5/* */ , 1, par, STRING_ATTR_TYPE  );

    // 
    if ( geom )
      specification->ksSpcIncludeReference( geom, 1 );

    spcObj = specification->ksSpcObjectEnd( );
    //          
    //      Cursor  Placement
    if ( spcObj && specification->ksEditWindowSpcObject( spcObj ) )
      return spcObj;
  }
  return 0;
}

//------------------------------------------------------------------------------
//    
//   ,    
//     Cursor  Placement
// ---
void DrawPosLeader( reference spcObj, ksDocument2D * doc ) {
  if ( !doc )
    return;

  ksRequestInfo * info( (ksRequestInfo*)kompas->GetParamStruct(ko_RequestInfo) );
  if ( !info )
    return;

  ksSpecification * specification = (ksSpecification *)doc->GetSpecification();
  if (!specification)
    return ;

  info->Init();
  bool flag = false;
  reference posLeater = 0;
  double x1, y1;
  do {
    info->commandsString = StringToOleStr("!    !  ");
    info->set_prompt(StringToOleStr("   "));
    int j1 = doc->ksCursor( info, &x1, &y1, 0 );
    switch ( j1 ) {
      case 1: //   
        posLeater = doc->ksCreateViewObject( POSLEADER_OBJ );
        flag = false;
        break;
      case 2: // 
        info->set_prompt(StringToOleStr("  "));
        if( doc->ksCursor( info, &x1, &y1, 0 ) ) {
          posLeater = doc->ksFindObj( x1, y1, 100 );      //   -   x,y
          if ( !(posLeater && doc->ksGetObjParam( posLeater, 0, 0) == POSLEADER_OBJ )) {
             posLeater = 0;
             flag = true;
          }
          else
            flag = false;
          break;
        }
        else
          flag = false;
        break;
      case -1:
        posLeater = doc->ksFindObj( x1, y1, 100 );      //   -   x,y
        if ( !(posLeater && doc->ksGetObjParam( posLeater, 0, 0) == POSLEADER_OBJ )) {
           kompas->ksError( StringToOleStr("!     !") );
           posLeater = 0;
           flag = true;
        }
        else
          flag = false;
      break;
    }
  }  while( flag );

  //  ,     
  if ( posLeater  ) {
    //     
    if ( specification->ksSpcObjectEdit( spcObj ) ) {
      //  
      specification->ksSpcIncludeReference( posLeater, true );
      //  
      specification->ksSpcObjectEnd();
    }
  }
}

//------------------------------------------------------------------------------
//      " "
// ---
reference EditStandartSpcObj ( reference geom, ksDocument2D * doc, ksSpcDocument * spc, reference spcObj ) {
  //    ,      
   ksSpecification * specification = NULL;
  if ( doc )
    specification = (ksSpecification *)doc->GetSpecification();
  else
    if ( spc )
      specification = (ksSpecification *)spc->GetSpecification();

  if (!specification)
    return 0;


  if ( doc && doc->ksEditMacroMode( ) ) {
    //    
    spcObj = specification->ksGetSpcObjForGeom( StringToOleStr("graphic.lyt"), //  
                                   1,         //     
                                   0,         //  
                                   1, 1 );
    //   
    if ( !specification->ksSpcObjectEdit( spcObj ) )
      spcObj  = 0;
  }

  if( spcObj || specification->ksSpcObjectCreate( StringToOleStr("graphic.lyt"), //  
                                   1,         //     
                                   25,  0,    //       
                                   313277777065.0 , 0 )) { //       spc.lat

    int uBuf;
    ksUserParam * par( (ksUserParam*)kompas->GetParamStruct(ko_UserParam) );
 	  ksLtVariant * item( (ksLtVariant*)kompas->GetParamStruct(ko_LtVariant) );
		ksDynamicArray * arr( (ksDynamicArray*)kompas->GetDynamicArray(LTVARIANT_ARR) );
		if ( !par || !item || !arr )
			return 0;
		par->Init();
		par->SetUserArray( arr );
  	item->Init();
		item->set_strVal(StringToOleStr("111"));
		arr->ksAddArrayItem( -1, item );

    specification->ksSpcChangeValue( 5/* */ , 1, par, STRING_ATTR_TYPE  );
    //
    uBuf = 2;
    specification->ksSpcVisible( SPC_NAME, 2, 1 );
    arr->ksClearArray();
    item->Init();
    item->set_intVal( uBuf );
    arr->ksAddArrayItem( -1, item );
    specification->ksSpcChangeValue( SPC_NAME , 2, par, UINT_ATTR_TYPE  );

    // 
  	arr->ksClearArray();
   	item->Init();
	 	item->set_doubleVal(40);
	  arr->ksAddArrayItem( -1, item );
    specification->ksSpcChangeValue( SPC_NAME , 4, par, DOUBLE_ATTR_TYPE  );

   //  
   specification->ksSpcVisible( SPC_NAME, 5, 1 );
   specification->ksSpcVisible( SPC_NAME, 6, 1 );   //
   arr->ksClearArray();
   item->Init();
   item->set_floatVal(1);
   arr->ksAddArrayItem( -1, item );
   specification->ksSpcChangeValue( SPC_NAME , 6, par, FLOAT_ATTR_TYPE  );

   //   
   specification->ksSpcVisible( SPC_NAME, 7, 0 );

   // 
 	 arr->ksClearArray();
	 item->Init();
	 item->set_intVal(55);
	 arr->ksAddArrayItem( -1, item );
	 specification->ksSpcChangeValue( SPC_NAME , 9, par, UINT_ATTR_TYPE );

   //   
   specification->ksSpcVisible( SPC_NAME, 10, 0 );

   //  
   specification->ksSpcVisible( SPC_NAME, 11, 0 );

   //  
   specification->ksSpcVisible( SPC_NAME, 12, 0 );

   // 
 	 arr->ksClearArray();
	 item->Init();
	 item->set_floatVal(7808);
	 arr->ksAddArrayItem( -1, item );
	 specification->ksSpcChangeValue( SPC_NAME , 14, par, UINT_ATTR_TYPE );

   // 
   if ( geom )
     specification->ksSpcIncludeReference( geom, 1 );

   spcObj = specification->ksSpcObjectEnd( );
   //          
   //.      Cursor  Placement
   if ( spcObj )
     if ( specification->ksEditWindowSpcObject( spcObj ) )
       return spcObj;
 }
 return 0;
}

//------------------------------------------------------------------------------
//     
// ---
void TypeAttrBolt() {
	ksAttributeObject * attr( (ksAttributeObject*)kompas->GetAttributeObject() );
	ksAttributeTypeParam * type( (ksAttributeTypeParam*)kompas->GetParamStruct(ko_AttributeType) );
	ksColumnInfoParam * col( (ksColumnInfoParam*)kompas->GetParamStruct(ko_ColumnInfoParam) );
	if ( type && col && attr ) {
		type->Init();
		col->Init();
		type->set_header( StringToOleStr("111") );    // o- 
		type->set_rowsCount( 1 );									 // -   
		type->set_flagVisible( true );             // ,     
		type->set_password( StringToOleStr("") );         // ,      -     
		type->set_key1( 10 );
		type->set_key2( 20 );
		type->set_key3( 30 );
		type->set_key4( 0  );
		ksDynamicArray * arr( (ksDynamicArray*)type->GetColumns() );
		if ( arr ) {
    	//   1 " ."
			col->set_header( StringToOleStr(" .") ); // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 1 );                       //  ,        
			col->set_def( StringToOleStr("") );         //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //   2 ""
			col->set_header( StringToOleStr("") );// o- 
			col->set_type( UINT_ATTR_TYPE );         //     - .
			col->set_key( 3 );                       //  ,        
			col->set_def( StringToOleStr("1") );            //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //  3 ""
			col->set_header( StringToOleStr("") );    // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("M") );            //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //  4 ""
			col->set_header( StringToOleStr("") );   // o- 
			col->set_type( UINT_ATTR_TYPE );         //     - .
			col->set_key( 3 );                       //  ,        
			col->set_def( StringToOleStr("12") );           //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //  5 ""
			col->set_header( StringToOleStr("") );          // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("x") );            //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //  6 ""
			col->set_header( StringToOleStr("") );       // o- 
			col->set_type( FLOAT_ATTR_TYPE );        //     - .
			col->set_key( 3 );                       //  ,        
			col->set_def( StringToOleStr("1.25") );         //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //  7 " "
			col->set_header( StringToOleStr(" ") );// o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 3 );                       //  ,        
			col->set_def( StringToOleStr("-6g") );          //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

      //  8 ""
			col->set_header( StringToOleStr("") );          // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("x") );            //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  9 ""
			col->set_header( StringToOleStr("") );     // o- 
			col->set_type( UINT_ATTR_TYPE );         //     - .
			col->set_key( 3 );                       //  ,        
			col->set_def( StringToOleStr("60") );           //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  10 ". "
			col->set_header( StringToOleStr(". ") );// o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("58") );           //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  11 ""
			col->set_header( StringToOleStr("") );  // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr(".35") );         //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  12 ""
			col->set_header( StringToOleStr("") );  // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr(".16") );          //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  13 ""
			col->set_header( StringToOleStr("") );      // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("") );         //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  14 ""
			col->set_header( StringToOleStr("") );     // o- 
			col->set_type( UINT_ATTR_TYPE );         //     - .
			col->set_key( 2 );                       //  ,        
			col->set_def( StringToOleStr("7808") );         //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  15 ""
			col->set_header( StringToOleStr("") );          // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("-") );            //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );

			//  16 ""
			col->set_header( StringToOleStr("") );       // o- 
			col->set_type( STRING_ATTR_TYPE );       //     - .
			col->set_key( 0 );                       //  ,        
			col->set_def( StringToOleStr("70") );           //   
			col->set_flagEnum( false );              //   ,    
			arr->ksAddArrayItem( -1, col );
    }
		AnsiString nameFile = StringToOleStr(kompas->ksChoiceFile( StringToOleStr("*.lat"), NULL, false ));
		if ( ::strlen((char*)nameFile.c_str()) ) {
			//  
			double  numbType = attr->ksCreateAttrType( type,       //    
																								 StringToOleStr(nameFile) ); //    
			if ( numbType > 1 )  {
				char buf[128];
				::sprintf( buf, "numbType=%f ",numbType );
				kompas->ksMessage( StringToOleStr(buf) );
			}
			else
				kompas->ksMessageBoxResult(); //     
		}
		arr->ksDeleteArray(); //   
	}
}

//------------------------------------------------------------------------------
//    
// ---
void CreateDet( ksDocument2D * doc, ksSpcDocument * spc ) {
  //     1
  reference gr = 0;
  if ( doc )
  {
    gr = doc->ksNewGroup(0);
      doc->ksLineSeg ( 20, 30, 70, 30, 2 );
      doc->ksLineSeg ( 70, 30, 70, 80, 2 );
      doc->ksLineSeg ( 70, 80, 20, 80, 2 );
      doc->ksLineSeg ( 20, 80, 20, 30, 2 );
    doc->ksEndGroup();
  }
  //   
  reference spcObj = EditSpcObjDet( gr, doc, spc );
  if ( spcObj && spc )
    DrawPosLeader( spcObj, doc );
}

//------------------------------------------------------------------------------
//   
// ---
void CreateStandart( ksDocument2D * doc, ksSpcDocument * spc ) {
  reference spcObj = EditStandartSpcObj( 0, doc, spc, 0 );
  if ( spcObj && doc )
    DrawPosLeader( spcObj, doc );
}

//------------------------------------------------------------------------------
// k   
// ---
void DecomposeSpc( ksDocument2D * doc ) {
	ksSpcDocument * spc( (ksSpcDocument*)kompas->SpcActiveDocument() );
  if ( spc ) {
		//   
		reference pDoc = spc->get_reference();
		if ( pDoc == 0 )
			return;
    //   
    int pageCount = spc->ksGetSpcDocumentPagesCount();
    //    
	  ksRectParam * spcGabarit( (ksRectParam*)kompas->GetParamStruct(ko_RectParam) );
		if ( !spcGabarit )
			return;
    doc->ksGetObjGabaritRect( pDoc, spcGabarit );

    // 
	  ksDocumentParam * docPar( (ksDocumentParam*)kompas->GetParamStruct(ko_DocumentParam) );
		if ( !docPar )
			return;
		docPar->Init();
    docPar->set_regime(0);
    docPar->set_type(3);
    doc->ksCreateDocument ( docPar );
    for ( int i = 0; i < pageCount; i++ ) {
      //   i-  
      reference group = doc->ksDecomposeObj( pDoc,        //  
                                             0,  //  0- ,,,; 1-,,; 2-, , 
                                             0.4, // 
                                             i+1);  // 0 -      1-   
      if ( group ) {
        int column=i%3;
				ksMathPointParam * mathBop( (ksMathPointParam*)spcGabarit->GetpBot() );
				ksMathPointParam * mathTop( (ksMathPointParam*)spcGabarit->GetpTop() );
        if ( !mathBop || !mathTop )
          return;
        double x = ( mathTop->get_x() - mathBop->get_x() + 5)*column;
        int row = i/3;
        double y = ( mathTop->get_y() - mathBop->get_y() + 5)*row;
        // 
        doc->ksMoveObj( group, x, -y );
        //  
        doc->ksStoreTmpGroup( group );  // 
        doc->ksClearGroup( group, 1 );
        doc->ksDeleteObj( group );
      }
    }
    char buf[128];
    ::sprintf( buf, " %d  ", pageCount );
    kompas->ksMessage( StringToOleStr(buf) );
  }
  else
    kompas->ksError( StringToOleStr("   ") );
}

//------------------------------------------------------------------------------
//  
// ---
void ShowSpc( ksDocument2D * doc ) {
  ksSpcDocument * spc( (ksSpcDocument*)kompas->SpcActiveDocument() );
	if ( spc && spc->get_reference() ) {
		ksIterator * iter( (ksIterator*)kompas->GetIterator() );
    if ( !iter )
      return;
    ksSpecification * specification = (ksSpecification *)spc->GetSpecification();
    if (!specification)
      return ;

		iter->ksCreateSpcIterator( 0, 0, 0 );
		if ( iter->get_reference() ) {
			long obj = iter->ksMoveIterator( StringToOleStr("F") );
			if ( doc->ksExistObj(obj) ) {
				do {
          //      
          int count = specification->ksGetSpcTableColumn( 0, 0, 0 );

					char buf[128];
	  			::sprintf( buf, "-  = %i", count );
		  		kompas->ksMessage( StringToOleStr(buf) );

					//    
          for ( int i = 1; i <= count; i++ ) {
            //     ,    
    				ksSpcColumnParam * spcColPar( (ksSpcColumnParam*)kompas->GetParamStruct(ko_SpcColumnParam) );
            if ( !spcColPar ) {
              iter->ksDeleteIterator();
              return;
            }  
            if ( specification->ksGetSpcColumnType( obj,          // 
                                  i,      //  ,   1
                                  spcColPar )){
              // 
              long columnType = spcColPar->get_columnType();
							long ispoln = spcColPar->get_ispoln();
							long blok = spcColPar->get_block();
              char buf[255];
			        long res;
            	::sprintf( buf, "%s", WideCharToString(specification->ksGetSpcObjectColumnText( obj, columnType, ispoln, blok )) );
			        if ( res != -1 )
                kompas->ksMessage( StringToOleStr(buf) );
              //  ,       
              int colNumb = specification->ksGetSpcColumnNumb(  obj,         // 
                spcColPar->get_columnType(),
	  						spcColPar->get_ispoln(),
		  					spcColPar->get_block());
							::sprintf ( buf, "i = %d colNumb =%d", i, colNumb );
              kompas->ksMessage( StringToOleStr(buf) );
            }
          }
          obj = iter->ksMoveIterator( StringToOleStr("N") );
        } while ( obj );
			}
    }
    iter->ksDeleteIterator();
  }
	else
    kompas->ksError( StringToOleStr("   ") );
}
