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

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

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

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

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

//------------------------------------------------------------------------------
//
// ---
void DrawPoint( ksDocument2D* doc, ksDynamicArray* arr, KompasObject* kompas ) {
  if ( doc && arr && kompas ) {
    ksMathPointParam* point = (ksMathPointParam*)kompas->GetParamStruct( ko_MathPointParam );
    if ( point ) {
      char buf[128];
      for ( int i = 0, count = arr->ksGetArrayCount(); i < count; i++ ) {
        arr->ksGetArrayItem( i, point );
        sprintf( buf, " %i: kp = %d xp = %6.2f yp = %6.2f ", i + 1, arr->ksGetArrayCount(), point->x, point->y );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksPoint( point->x, point->y, 0 );
      }
    }
  }
}

//------------------------------------------------------------------------------
//
// ---
void DrawPoint_Line( ksDocument2D* doc, ksDynamicArray* arr, KompasObject* kompas, ksMathematic2D* math, double angle ) {
  if ( doc && arr && kompas ) {
    ksMathPointParam* point = (ksMathPointParam*)kompas->GetParamStruct( ko_MathPointParam );
    if ( point ) {
      char buf[128];
      for ( int i = 0, count = arr->ksGetArrayCount(); i < count; i++ ) {
        arr->ksGetArrayItem( i, point );
        sprintf( buf, " %i: kp = %d xp = %6.2f yp = %6.2f ", i + 1, arr->ksGetArrayCount(), point->x, point->y );
        kompas->ksMessage( StringToOleStr(buf) );
        doc->ksPoint( point->x, point->y, 0 );
        if ( math )
          doc->ksLine( 10, 50, math->ksAngle(10, 50, point->x, point->y) );
        else
          doc->ksLine( point->x, point->y, angle );
      }
    }
  }
}


//------------------------------------------------------------------------------
//
// ---
extern "C" void far __export __pascal  LibraryEntry( unsigned int comm ){
  KompasObject* kompas = (KompasObject*)::CreateKompasObject();
  if ( kompas ) {
    ksDocument2D* doc = (ksDocument2D*)kompas->Document2D();
    ksMathematic2D* math = (ksMathematic2D*)kompas->GetMathematic2D();
    if ( doc && math ) {
      char buf[128];
      switch ( comm ) {
        case 1 : { //  
          int kp;
          double x,y;
          doc->ksLine( 10,10, 0 );
          doc->ksLine( 15, 5, 90 );
          ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
          if ( arr ) {
            math->ksIntersectLinLin( 10, 10, 0, 15, 5, 90, arr );
            ::DrawPoint( doc, arr, kompas );
          }
        }

        break;

        case 2 : {    //  
          reference pp1, pp2;
          int i, kp;
          double xp[2], yp[2];
          doc->ksBezier( 0, 0 );
      	    doc->ksPoint( 0,  10, 0 );
	          doc->ksPoint( 10, 20, 0 );
      	    doc->ksPoint( 20, 10, 0 );
	          doc->ksPoint( 10, 0,  0 );
    	      doc->ksPoint( 0,  10, 0 );
	        pp1 = doc->ksEndObj();

	        doc->ksMtr( 0, 10, 0, 1, 1 );
	          doc->ksBezier( 0, 0 );
    	        doc->ksPoint( 0,  10, 0 );
	            doc->ksPoint( 10, 20, 0 );
	            doc->ksPoint( 20, 10, 0 );
	            doc->ksPoint( 10, 0,  0 );
	            doc->ksPoint( 0,  10, 0 );
            pp2 = doc->ksEndObj();
          doc->ksDeleteMtr();

          ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
          if ( arr ) {
            math->ksIntersectCurvCurv( pp1, pp2, arr );
            ::DrawPoint( doc, arr, kompas );
          }
        }

        break;

        case 3 : { //    
          int i;
          doc->ksLineSeg( 0, 40, 100, 40, 1 );
          doc->ksArcByPoint( 50, 40, 20, 30, 40, 70, 40, 1, 1 );
          ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
          if ( arr ) {
            math->ksIntersectLinSArc( 0, 40,   //   
                                      100, 40, //   
                                      50, 40,  //  
                                      20,      //  
                                      math->ksAngle(50, 40, 30, 40), //      
                                      math->ksAngle(50, 40, 70, 40),
                                      1,       //  
                                      arr );   //   
            ::DrawPoint( doc, arr, kompas );
          }
          break;
        }

        case 4 : { //   
          doc->ksPoint( 10, 50, 0 );
          doc->ksCircle( 50, 10, 40, 1 );
          ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
          if ( arr ) {
            math->ksTanLinePointCircle( 10, 50,
                                        50, 10, 40,
                                        arr );
            ::DrawPoint_Line( doc, arr, kompas, math, 0 );
          }
        }
        break;

        case 5: { //   
          doc->ksCircle( 50, 10, 40, 1 );
          ksDynamicArray* arr = (ksDynamicArray*)kompas->GetDynamicArray( POINT_ARR );
          if ( arr ) {
            math->ksTanLineAngCircle( 50, 10, 40, -45, arr );
            ::DrawPoint_Line( doc, arr, kompas, NULL, -45 );
          }
        }

        break;

        case 6: { //  
          double x, y;
          math->ksRotate( 60, 50, 50, 50, 180, &x, &y );
          ::sprintf( buf,"x = %4.2f y = %4.2f", x, y );
          kompas->ksMessage( StringToOleStr(buf) );
        }

        break;

        case 7: { //  
          double x, y;
          math->ksSymmetry( 55, 60, 60, 50, 50, 50,  &x, &y );

          ::sprintf( buf, "x = %4.2f y = %4.2f  ", x, y );
          kompas->ksMessage( StringToOleStr(buf) );
        }

        break;

        case 8: { //     
          double rad = 20;
          ksCON* con = (ksCON*)kompas->GetParamStruct( ko_CON );
          if ( con ) {
            math->ksCouplingLineLine( 100,100,45,  //  
                                      100,100,-45, //  
                                      rad, con );
            doc->ksLine( 100, 100, 45);
            doc->ksLine( 100, 100, -45);

            for ( short i = 0 ; i < 4; i++ ) {
              doc->ksCircle( con->GetXc(i), con->GetYc(i), rad, 2 );
              doc->ksPoint( con->GetX1(i), con->GetY1(i), i );
              doc->ksPoint( con->GetX2(i), con->GetY2(i), i );
            }
          }
        }

        break;

        case 9: {  // 
          double xp, yp;
          math->ksPerpendicular( 50, 50, 60, 10, 100, 10, &xp, &yp );
          ::sprintf( buf," xp = %4.3f yp = %4.3f", xp, yp );
          kompas->ksMessage( StringToOleStr(buf) );
        }
        break;

      }
    }
    kompas->Release();
  }
}
