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

#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;
}

void WalkFromView( ksDocument2D * doc );
void WalkFromMacro( ksDocument2D * doc );
void WalkFromDoc();
void WalkViewDoc( ksDocument2D * doc );
void WalkGroup( ksDocument2D * doc );
void WalkLayer( ksDocument2D * doc );
void WalkFromGroup( ksDocument2D * doc );
void WalkFromDocWithAttr( ksDocument2D * doc );
void WalkFromObjWithAttr( ksDocument2D * doc );

char buf[128];

//------------------------------------------------------------------------------
//
// ---
extern "C" void far __export __pascal  LibraryEntry( UINT Comm ) {
  kompas = (KompasObject*)::CreateKompasObject();
  if ( kompas ) {
		if ( Comm == 3 )
			::WalkFromDoc(); //  
		else {
      ksDocument2D* doc = (ksDocument2D*)kompas->ActiveDocument2D();
      if ( doc && doc->get_reference() ) {
        switch ( Comm ) {
          case 1  : ::WalkFromView( doc );        break; //  
          case 2  : ::WalkFromMacro( doc );       break; //  
          case 4  : ::WalkViewDoc( doc );         break; //  
          case 5  : ::WalkGroup( doc );           break; //     
          case 6  : ::WalkLayer( doc );           break; //  
          case 7  : ::WalkFromGroup( doc );       break; //  
          case 8  : ::WalkFromDocWithAttr( doc ); break; //      
          case 9  : ::WalkFromObjWithAttr( doc ); break; //   
        }
      }
      else
        kompas->ksError( StringToOleStr("    \n  /") );
    }
    kompas->Release();
  }
}

//------------------------------------------------------------------------------
//  
// ---
static void UserLightObj( reference obj, char *c, int count, ksDocument2D * doc ) {
  doc->ksLightObj( obj, 1 );
  ::sprintf(buf, c, count );
  kompas->ksMessage( StringToOleStr(buf) );
  doc->ksLightObj( obj, 0 );
}

//------------------------------------------------------------------------------
//   
// ---
void WalkFromView( ksDocument2D * doc ) {
  //           
  reference obj;
  int count  = 0;
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
	if ( iter->ksCreateIterator( ALL_OBJ, 0 ) ) {
    if ( doc->ksExistObj( obj = iter->ksMoveIterator( StringToOleStr("F") )) ){
      do {
        doc->ksLightObj( obj, 1 );
        count ++;
        ::sprintf( buf, " = %d", count );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksLightObj( obj, 0 );
      } while( doc->ksExistObj ( obj = iter->ksMoveIterator( StringToOleStr("N") )) );
    }
    iter->ksDeleteIterator();
  }
}

//------------------------------------------------------------------------------
//   
// ---
void WalkFromMacro( ksDocument2D * doc ) {
  //          
  reference obj, macro;
  char s[50],s1[50];
  int count  = 0, count1=0 ;
  ::strcpy(s," =%d");
  ::strcpy(s1," =%d");
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
	if ( iter->ksCreateIterator( MACRO_OBJ, 0 ) ) {
    if ( doc->ksExistObj( macro = iter->ksMoveIterator( StringToOleStr("F") )) ){
      do {
        count ++;
        UserLightObj( macro, s, count, doc ); //  
				ksIterator * iter2 = (ksIterator*)kompas->GetIterator(); //      
        iter2->ksCreateIterator( ALL_OBJ, macro );
	      if ( iter2->get_reference() ) {
          if ( doc->ksExistObj( obj = iter2->ksMoveIterator( StringToOleStr("F") )) ){
            do {
              count1++;
              UserLightObj( obj, s1, count1, doc ); //   
						}  while ( doc->ksExistObj ( obj = iter2->ksMoveIterator( StringToOleStr("N") )) );
          }
        }
      } while( doc->ksExistObj ( macro = iter->ksMoveIterator( StringToOleStr("N") )) );
		}
    iter->ksDeleteIterator();
  }
}

//------------------------------------------------------------------------------
//   
// ---
void WalkFromDoc() {
  ksDocument2D * doc = (ksDocument2D*)kompas->Document2D();
	if ( doc ) {
		reference pDoc;
		ksDocumentParam * docPar = (ksDocumentParam*)kompas->GetParamStruct(ko_DocumentParam);
    if ( !docPar )
      return;
		ksSheetPar * sheetPar = (ksSheetPar*)docPar->GetLayoutParam();
    if ( !sheetPar )
      return;
		ksStandartSheet * stSheet = (ksStandartSheet*)sheetPar->GetSheetParam();
    if ( !stSheet )
      return;

		docPar->Init();
		sheetPar->Init();
		stSheet->Init();

		docPar->set_comment(StringToOleStr("create document"));
		docPar->set_author(StringToOleStr("Misha"));
		docPar->set_regime(0);
		docPar->set_type(1);
		sheetPar->set_layoutName(StringToOleStr(""));
		sheetPar->set_shtType(1);
		stSheet->set_format(3);
		stSheet->set_multiply(1);
		stSheet->set_direct(0);

		docPar->set_fileName(StringToOleStr("a.cdw"));
		doc->ksCreateDocument( docPar );
		docPar->set_fileName(StringToOleStr("b.cdw"));
		doc->ksCreateDocument( docPar );
		docPar->set_fileName(StringToOleStr("c.cdw"));
		doc->ksCreateDocument( docPar );

		int count=0;
		ksIterator * iter = (ksIterator*)kompas->GetIterator();
		if ( iter->ksCreateIterator( DOCUMENT_OBJ, 0 ) ) { //     
			pDoc = iter->ksMoveIterator( StringToOleStr("F") );
			if ( pDoc ){
				do {
					doc->reference = pDoc;
					if ( doc->ksSetObjParam( pDoc, 0, DOCUMENT_STATE )) { //  pDoc
						count ++;
						ksViewParam * viewPar = (ksViewParam*)kompas->GetParamStruct(ko_ViewParam);
						if ( !viewPar )
							return;

						viewPar->Init();

						long number = count;
						viewPar->set_x(10);
						viewPar->set_y(20);
						viewPar->set_scale_(1);
						viewPar->set_angle(0);
						viewPar->set_color(RGB(10,20,10));
						viewPar->set_state(stACTIVE);
						viewPar->set_name(StringToOleStr("user view"));

						doc->ksCreateSheetView( viewPar, &number); //   
						doc->ksLayer( count ); //  
						switch ( count ) {
							case 1: doc->ksLineSeg( 20, 10, 40, 10, 1 );            break; //    
							case 2: doc->ksCircle ( 50, 50, 20, 1 );                break; //    
							case 3: doc->ksArcByAngle( 50, 50, 20, 45, 135, 1, 1 ); break; //     
						}
						::sprintf(buf, " %d ", count );
						kompas->ksMessage( StringToOleStr(buf) );
					}
					pDoc = iter->ksMoveIterator( StringToOleStr("N") );
				} while ( pDoc );
			}
      iter->ksDeleteIterator();
		}
	}
}

//------------------------------------------------------------------------------
//   
// ---
void WalkViewDoc( ksDocument2D * doc ) {
	ksDocumentParam * docPar = (ksDocumentParam*)kompas->GetParamStruct(ko_DocumentParam);
  if ( !docPar )
    return;
	ksSheetPar * sheetPar = (ksSheetPar*)docPar->GetLayoutParam();
  if ( !sheetPar )
    return;
	ksStandartSheet * stSheet = (ksStandartSheet*)sheetPar->GetSheetParam();
  if ( !stSheet )
    return;

	docPar->Init();
	sheetPar->Init();
  stSheet->Init();

	docPar->set_comment(StringToOleStr("create document"));
	docPar->set_author(StringToOleStr("Misha"));
	docPar->set_regime(0);
	docPar->set_type(1);
	sheetPar->set_layoutName(StringToOleStr(""));
	sheetPar->set_shtType(1);
	stSheet->set_format(3);
	stSheet->set_multiply(1);
	stSheet->set_direct(0);

  docPar->set_fileName(StringToOleStr("a.cdw"));
  doc->ksCreateDocument( docPar );

  // 5 
  for( int i = 0; i < 5; i++ ) {
		ksViewParam * viewPar = (ksViewParam*)kompas->GetParamStruct(ko_ViewParam);
		if ( !viewPar )
			return;

    viewPar->Init();

    long number = 0;
		viewPar->set_x(10);
		viewPar->set_y(20);
		viewPar->set_scale_(1);
		viewPar->set_angle(0);
		viewPar->set_color(RGB(10,20,10));
		viewPar->set_state(stACTIVE);
    viewPar->set_name(StringToOleStr("user view"));

    doc->ksCreateSheetView( viewPar, &number); //   
  }

	reference  pView;
	int count =0;
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
	if ( iter->ksCreateIterator( VIEW_OBJ, 0 ) ) { //       
    pView = iter->ksMoveIterator( StringToOleStr("F") );
    if ( pView ){
      do  {
    		ksLtVariant * var = (ksLtVariant*)kompas->GetParamStruct(ko_LtVariant);
		    if ( !var )
					return;

				var->Init();

				var->set_intVal( stCURRENT );
        if ( doc->ksSetObjParam( pView, var, VIEW_LAYER_STATE )) {
          switch (count) {
            case 1: doc->ksLineSeg( 20, 20, 40, 20, 1 ); break;
            case 2: doc->ksCircle( 40, 20, 30, 1 );      break;
            case 3: doc->ksArcByAngle( 50, 50, 20, 45, 135, 1, 1 ); break;
            case 4:
              doc->ksMtr(40,0,0,1,1);
              doc->ksLineSeg( 10, 10, 30, 30, 1 );
              doc->ksLineSeg( 30, 30, 60, 10, 1 );
              doc->ksLineSeg( 60, 10, 10, 10, 1 );
              doc->ksDeleteMtr();
            break;
            case 5:
              doc->ksCircle( 30, 30, 20, 1 );
              doc->ksCircle( 30, 30, 10, 1 );
              doc->ksHatch( 0, 45, 2, 0, 0, 0);
                doc->ksCircle( 30, 30, 20, 1 );
                doc->ksCircle( 30, 30, 10, 1 );
              doc->ksEndObj();
            break;
          }
        }
        count++;
        pView = iter->ksMoveIterator ( StringToOleStr("N") );
      } while ( pView );
    }
    iter->ksDeleteIterator();
  }
}

//------------------------------------------------------------------------------
//      
// ---
void WalkGroup( ksDocument2D * doc ) {
	reference  pNameGrp;
	int count =0;
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
	if ( iter->ksCreateIterator( NAME_GROUP_OBJ, 0 ) ) { //        
    pNameGrp = iter->ksMoveIterator( StringToOleStr("F") );
    if ( pNameGrp ){
      do  {
        doc->ksLightObj( pNameGrp, 1 );   // 
        count ++;
        ::sprintf(buf," = %d", count );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksLightObj( pNameGrp, 0 );   // 
      } while( (pNameGrp = iter->ksMoveIterator( StringToOleStr("N") ))!=0 );
    }
    iter->ksDeleteIterator();
  }
  //       
  doc->ksNewGroup(0);
    doc->ksCircle( 30, 30, 20, 1 );
    doc->ksCircle( 30, 30, 10, 1 );
    doc->ksHatch( 0, 45, 2, 0, 0, 0);
      doc->ksCircle( 30, 30, 20, 1 );
      doc->ksCircle( 30, 30, 10, 1 );
    doc->ksEndObj();
  doc->ksEndGroup();

  //    
  count = 0;
  reference pWorkGrp;
  iter->ksCreateIterator( WORK_GROUP_OBJ, 0 ); //        
	if ( iter->get_reference() ) {
    pWorkGrp = iter->ksMoveIterator( StringToOleStr("F") );
    if ( pWorkGrp ){
      do {
        doc->ksLightObj( pWorkGrp, 1 );   // 
        count ++;
        ::sprintf(buf," = %d", count );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksLightObj( pWorkGrp, 0 );   // 
      } while ( ( pWorkGrp = iter->ksMoveIterator( StringToOleStr("N") ) )!=0  );
    }
  }
}

//------------------------------------------------------------------------------
//   
// ---
void WalkLayer( ksDocument2D * doc ) {
	ksDocumentParam * docPar = (ksDocumentParam*)kompas->GetParamStruct(ko_DocumentParam);
  if ( !docPar )
    return;
	ksSheetPar * sheetPar = (ksSheetPar*)docPar->GetLayoutParam();
  if ( !sheetPar )
    return;
	ksStandartSheet * stSheet = (ksStandartSheet*)sheetPar->GetSheetParam();
  if ( !stSheet )
    return;

	docPar->Init();
	sheetPar->Init();
  stSheet->Init();

	docPar->set_comment(StringToOleStr("create document"));
	docPar->set_author(StringToOleStr("Misha"));
	docPar->set_regime(0);
	docPar->set_type(1);
	sheetPar->set_layoutName(StringToOleStr(""));
	sheetPar->set_shtType(1);
	stSheet->set_format(3);
	stSheet->set_multiply(1);
	stSheet->set_direct(0);

  docPar->set_fileName(StringToOleStr("a.cdw"));
  doc->ksCreateDocument( docPar );

  // 5 

  for( int i = 0; i < 5; i++ ) {
    doc->ksLayer( i );
    doc->ksCircle( 30, 30, 5 + i * 10, 1 );
  }

  reference pLayer;
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
  iter->ksCreateIterator( LAYER_OBJ, 0 ); //   
	if ( iter->get_reference() ) {
    pLayer = iter->ksMoveIterator( StringToOleStr("F") );
		int count = 0;
    if ( pLayer ){
      do {
        doc->ksLightObj( pLayer, 1 );   // 
        ::sprintf(buf," = %d", count );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksLightObj( pLayer, 0 );   // 
        count ++;
      } while( (pLayer = iter->ksMoveIterator ( StringToOleStr("N") )) !=0 );
    }
  }
}

//------------------------------------------------------------------------------
//   
// ---
void WalkFromGroup( ksDocument2D * doc ) {
  doc->ksMtr( 20, 10, 0, 1, 1 );
  reference pGrp = doc->ksNewGroup(0);
    doc->ksLineSeg( 10, 50, 50, 50, 1 );
    doc->ksLineSeg( 10, 10, 50, 10, 1 );
    doc->ksLineSeg( 10, 10, 10, 50, 1 );
    doc->ksLineSeg( 50, 10, 50, 50, 1 );
    doc->ksCircle( 30, 30, 20, 1 );
    doc->ksCircle( 30, 30, 10, 1 );
    doc->ksHatch( 0, 45, 2, 0, 0, 0);
      doc->ksCircle( 30, 30, 20, 1 );
      doc->ksCircle( 30, 30, 10, 1 );
    doc->ksEndObj();
  doc->ksEndGroup();
  doc->ksDeleteMtr();

  reference obj;
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
  iter->ksCreateIterator( ALL_OBJ, pGrp ); //     
	if ( iter->get_reference() ) {
    obj = iter->ksMoveIterator( StringToOleStr("F") );
		int count = 0;
    if ( doc->ksExistObj(obj) ){
      do {
        doc->ksLightObj( obj, 1 );
        count ++;
        ::sprintf(buf," = %d", count );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksLightObj( obj, 0 );
      } while( doc->ksExistObj ( obj = iter->ksMoveIterator( StringToOleStr("N") )) );
    }
  }
}

//------------------------------------------------------------------------------
//       
// ---
void WalkFromDocWithAttr( ksDocument2D * doc ) {
	ksAttributeObject * attr = (ksAttributeObject*)kompas->GetAttributeObject();
	if ( !attr )
		return;

  reference pObj, pAttr;
  char buf[128];
  ksIterator * iter = (ksIterator*)kompas->GetIterator();
  iter->ksCreateAttrIterator( 0, 10, 0,0,0,0 ); //       10
	if ( iter->get_reference() ) {
    pAttr = iter->ksMoveAttrIterator( StringToOleStr("F"), &pObj );
		int count = 0;
    long rowsCount, columnsCount;
    if ( pAttr && doc->ksExistObj(pObj) ){
      do {
        doc->ksLightObj( pObj, 1 );
        count ++;
        //    
        if(attr->ksGetAttrTabInfo( pAttr, &rowsCount, &columnsCount )) {
          ::sprintf(buf," = %d rowsCount=%d columnsCount=%d", count,rowsCount,columnsCount );
          kompas->ksMessage( StringToOleStr(buf) );
				}
        else
          kompas->ksMessageBoxResult();  //   -     

        doc->ksLightObj( pObj, 0 );

        pAttr = iter->ksMoveAttrIterator( StringToOleStr("N"), &pObj );
			} while( pAttr && doc->ksExistObj(pObj));
		}
  }
}

//------------------------------------------------------------------------------
//    
// ---
void WalkFromObjWithAttr( ksDocument2D * doc ) {
  double x, y;
  int j;
  reference pObj;
 	ksRequestInfo * info = (ksRequestInfo*)kompas->GetParamStruct(ko_RequestInfo);
	ksAttributeObject * attr = (ksAttributeObject*)kompas->GetAttributeObject();
	if ( !info || !attr )
		return;

	info->Init();

	info->set_prompt(StringToOleStr(" "));
  do {
    j = doc->ksCursor( info, &x ,&y, 0 );
    if ( j ) {
      if( doc->ksExistObj(pObj = doc->ksFindObj( x, y, 1e6 )) ){
        int count = 0;
        char buf[128];
        long rowsCount, columnsCount;
        doc->ksLightObj( pObj, 1 );

        reference pAttr;
        ksIterator * iter = (ksIterator*)kompas->GetIterator();
        if ( !iter )
          return;
	      if ( iter->ksCreateAttrIterator( pObj, 10, 0,0,0,0 ) ) { //       10
          pAttr = iter->ksMoveAttrIterator( StringToOleStr("F"), 0 );
          if ( pAttr ) {
            do {
              count ++;
              //    
              if( attr->ksGetAttrTabInfo ( pAttr, &rowsCount, &columnsCount ) ) {
                ::sprintf(buf," = %d rowsCount=%d columnsCount=%d", count,rowsCount,columnsCount );
                kompas->ksMessage( StringToOleStr(buf) );
							}
              else
                kompas->ksMessageBoxResult();  //   -     
              pAttr = iter->ksMoveAttrIterator( StringToOleStr("N"), 0 );
						} while( pAttr );
					}
        }
        doc->ksLightObj( pObj, 0 );
      }
    }
  } while(j);
}



