//////////////////////////////////////////////////////////////////////////////// 
// 
// step2.cpp - 
// 
// 1.                        - Intersect2Line
// 2.                        - Intersect2Curve
// 3.                  - IntersectLineSegArc
// 4.                    - TanLinePointCircle
// 5.                   - TanLineAngCircle
// 6.                          - RotatePoint
// 7.                        - SymmetryPoint
// 8.      - Couplin2Lines
// 9.                        - Perpendicular
// 
//////////////////////////////////////////////////////////////////////////////// 
#include "stdafx.h"
#include "step2.h"
#include <ldefin2d.h>

#ifdef __LIGHT_VERSION__
#include <klAPI5.h>
#else
#include <kAPI5.h>
#endif

#include <ksConstants.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CStep2App

BEGIN_MESSAGE_MAP(CStep2App, CWinApp)
	//{{AFX_MSG_MAP(CStep2App)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStep2App construction

CStep2App::CStep2App()
{
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CStep2App object

CStep2App    theApp;
KompasObject kompas( NULL );

void Intersect2Line( ksDocument2D& doc, ksMathematic2D& mat );
void Intersect2Curve( ksDocument2D& doc, ksMathematic2D& mat );
void IntersectLineSegArc( ksDocument2D& doc, ksMathematic2D& mat );
void TanLinePointCircle( ksDocument2D& doc, ksMathematic2D& mat );
void TanLineAngCircle( ksDocument2D& doc, ksMathematic2D& mat );
void RotatePoint( ksMathematic2D& mat );
void SymmetryPoint( ksMathematic2D& mat );
void Couplin2Lines( ksDocument2D& doc, ksMathematic2D& mat );
void Perpendicular( ksMathematic2D& mat );

//-------------------------------------------------------------------------------
//
// ---
void GetKompas() {
	if ( !kompas.m_lpDispatch ) {
		CString filename;
		if( ::GetModuleFileName(NULL, filename.GetBuffer(255), 255) ) {
			filename.ReleaseBuffer( 255 );
			CString libname;

      #ifdef __LIGHT_VERSION__
        libname.LoadString( IDS_STRING5 );  //klAPI5.dll
      #else
        libname.LoadString( IDS_STRING4 );  //kAPI5.dll
      #endif
      
			filename.Replace( filename.Right(filename.GetLength() - (filename.ReverseFind('\\') + 1)), 
												libname );

			HINSTANCE hAppAuto = LoadLibrary( filename ); //  kAPI5.dll
			if(  hAppAuto ) {
				typedef LPDISPATCH ( WINAPI *FCreateKompasObject )(); 
				FCreateKompasObject pCreateKompasObject = 
					(FCreateKompasObject)GetProcAddress( hAppAuto, "CreateKompasObject" );	
				if ( pCreateKompasObject ) 
					kompas = pCreateKompasObject();
				FreeLibrary( hAppAuto );
			}
		}
	}
}

//-------------------------------------------------------------------------------
//   
// ---
unsigned int WINAPI LIBRARYID(){
	return IDS_LIBID;
}

//-------------------------------------------------------------------------------
// LIBRARYENTRY
// ---
void WINAPI LIBRARYENTRY( unsigned int comm ) {
	//      .exe ,     
	//   dll   define
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	GetKompas();
	if ( kompas.m_lpDispatch ) {
		ksDocument2D doc( kompas.ActiveDocument2D() );
		ksMathematic2D mat( kompas.GetMathematic2D() );
		if ( doc.m_lpDispatch && doc.GetReference() ) {
			switch ( comm ) {
			case 1  : ::Intersect2Line( doc, mat );      break; //  
			case 2  : ::Intersect2Curve( doc, mat );     break; //  
			case 3  : ::IntersectLineSegArc( doc, mat ); break; //    
			case 4  : ::TanLinePointCircle( doc, mat );  break; //   
			case 5  : ::TanLineAngCircle( doc, mat );    break; //   
			case 6  : ::RotatePoint( mat );              break; //  
			case 7  : ::SymmetryPoint( mat );						 break; //  
			case 8  : ::Couplin2Lines( doc, mat );       break; //     
			case 9  : ::Perpendicular( mat );						 break; // 
			}
		}
	}
}

//-------------------------------------------------------------------------------
//
// ---
void DrawPoints( ksDocument2D& doc, ksDynamicArray& arr ) {
	ksMathPointParam par( kompas.GetParamStruct(ko_MathPointParam) );
	if ( par.m_lpDispatch ) {
		int count = arr.ksGetArrayCount();
		char buf[255];
		::sprintf( buf, " : %d,", count );
		kompas.ksMessage( buf );
		for ( int i = 0; i < count; i++ ) {
			if ( arr.ksGetArrayItem(i, par) ) {
				::sprintf( buf, ": %d, x=%4.2f, y=%4.2f ", i, par.GetX(), par.GetY() );
				kompas.ksMessage( buf );
				doc.ksPoint( par.GetX(), par.GetY(), 0 );
			}
		}
	}
}

//-------------------------------------------------------------------------------
//  
// ---
void Intersect2Line( ksDocument2D& doc, ksMathematic2D& mat ) {
  doc.ksLine( 10,10, 0 );
  doc.ksLine( 15, 5, 90 );

	ksDynamicArray arr( kompas.GetDynamicArray(POINT_ARR) );
	if ( arr.m_lpDispatch && mat.ksIntersectLinLin(10, 10, 0, 15, 5, 90, arr) ) 
		::DrawPoints( doc, arr );
}

//-------------------------------------------------------------------------------
//  
// ---
void Intersect2Curve( ksDocument2D& doc, ksMathematic2D& mat ) {
  reference pp1, pp2;
  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( kompas.GetDynamicArray(POINT_ARR) );
	if ( arr.m_lpDispatch && mat.ksIntersectCurvCurv(pp1, pp2, arr) ) 
		::DrawPoints( doc, arr );
}

//-------------------------------------------------------------------------------
//    
// ---
void IntersectLineSegArc( ksDocument2D& doc, ksMathematic2D& mat ) {
  doc.ksLineSeg( 0, 40, 100, 40, 1 );
  doc.ksArcByPoint( 50, 40, 20, 30, 40, 70, 40, 1, 1 );

	ksDynamicArray arr( kompas.GetDynamicArray(POINT_ARR) );
	if ( arr.m_lpDispatch  
				&& mat.ksIntersectLinSArc( 0, 40,                       //   
																	 100, 40,                     //   
																	 50, 40,                      //  
																	 20,                          //  
																	 mat.ksAngle(50, 40, 30, 40), //      
																	 mat.ksAngle(50, 40, 70, 40), 
																	 1,                           //  
																	 arr) )                       //   
		::DrawPoints( doc, arr );
}

//-------------------------------------------------------------------------------
//
// ---
void DrawPointsAndLines( ksDocument2D& doc, ksDynamicArray& arr, ksMathematic2D& mat ) {
	ksMathPointParam par( kompas.GetParamStruct(ko_MathPointParam) );
	if ( par.m_lpDispatch ) {
		int count = arr.ksGetArrayCount();
		char buf[255];
		::sprintf( buf, " : %d,", count );
		kompas.ksMessage( buf );
		for ( int i = 0; i < count; i++ ) {
			if ( arr.ksGetArrayItem(i, par) ) {
				::sprintf( buf, ": %d, x=%4.2f, y=%4.2f ", i, par.GetX(), par.GetY() );
				kompas.ksMessage( buf );
				doc.ksPoint( par.GetX(), par.GetY(), 0 );
        doc.ksLine( 10, 50, mat.ksAngle(10, 50, par.GetX(), par.GetY()) );
			}
		}
	}
}

//-------------------------------------------------------------------------------
//   
// ---
void TanLinePointCircle( ksDocument2D& doc, ksMathematic2D& mat ) {
  doc.ksPoint( 10, 50, 0 );
  doc.ksCircle( 50, 10, 40, 1 );

	ksDynamicArray arr( kompas.GetDynamicArray(POINT_ARR) );
	if ( arr.m_lpDispatch && mat.ksTanLinePointCircle( 10, 50, 50, 10, 40, arr) ) //   
		::DrawPointsAndLines( doc, arr, mat );
}

//-------------------------------------------------------------------------------
//
// ---
void DrawPointsAndLines1( ksDocument2D& doc, ksDynamicArray& arr, ksMathematic2D& mat ) {
	ksMathPointParam par( kompas.GetParamStruct(ko_MathPointParam) );
	if ( par.m_lpDispatch ) {
		int count = arr.ksGetArrayCount();
		char buf[255];
		::sprintf( buf, " : %d,", count );
		kompas.ksMessage( buf );
		for ( int i = 0; i < count; i++ ) {
			if ( arr.ksGetArrayItem(i, par) ) {
				::sprintf( buf, ": %d, x=%4.2f, y=%4.2f ", i, par.GetX(), par.GetY() );
				kompas.ksMessage( buf );
				doc.ksPoint( par.GetX(), par.GetY(), 0 );
        doc.ksLine( par.GetX(), par.GetY(), -45 );
			}
		}
	}
}

//-------------------------------------------------------------------------------
//
// ---
void TanLineAngCircle( ksDocument2D& doc, ksMathematic2D& mat ) {
  doc.ksCircle( 50, 10, 40, 1 );
	ksDynamicArray arr( kompas.GetDynamicArray(POINT_ARR) );
	if ( arr.m_lpDispatch && mat.ksTanLineAngCircle( 50, 10, 40, -45, arr) ) //   
		::DrawPointsAndLines1( doc, arr, mat );
}

//-------------------------------------------------------------------------------
//
// ---
void RotatePoint( ksMathematic2D& mat ) {
  double x, y;
  mat.ksRotate( 60, 50, 50, 50, 180, &x, &y );

	char buf[255];
  ::sprintf( buf,"x=%4.2f, y=%4.2f", x, y );
  kompas.ksMessage( buf );
}

//-------------------------------------------------------------------------------
//
// ---
void SymmetryPoint( ksMathematic2D& mat ) {
  double x, y;
  mat.ksSymmetry( 55, 60, 60, 50, 50, 50,  &x, &y );

	char buf[255];
  ::sprintf( buf,"x=%4.2f, y=%4.2f", x, y );
  kompas.ksMessage( buf );
}

//-------------------------------------------------------------------------------
//
// ---
void Couplin2Lines( ksDocument2D& doc, ksMathematic2D& mat ) {
	ksCON con( kompas.GetParamStruct(ko_CON) );
	double rad = 20;
	if ( con.m_lpDispatch && mat.ksCouplingLineLine(100, 100, 45,  //  
																									100, 100, -45, //  
																									rad, con) ) {

	  doc.ksLine( 100, 100, 45  );
		doc.ksLine( 100, 100, -45 );
		for ( int i = 0, count = con.GetCount(); i < count; 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 );
		}
	}
}

//-------------------------------------------------------------------------------
//
// ---
void Perpendicular( ksMathematic2D& mat ) {
  double xp, yp;
  mat.ksPerpendicular( 50, 50, 60, 10, 100, 10, &xp, &yp);
	char buf[255];
  ::sprintf( buf,"xp=%4.3f, yp=%4.3f", xp, yp );
  kompas.ksMessage( buf );
}
