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

#include <vcl.h>
#pragma hdrstop

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

#include <ldefin2d.h>
#include <ldefin3d.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 ConstrAxisOperations( ksDocument3D * doc );
void ConstrAxis2Point( ksDocument3D * doc );
void ConstrAxisEdge( ksDocument3D * doc );
//void ConstrAxisConeface( ksDocument3D * doc );
void ConstrPlane3Point( ksDocument3D * doc );
void CreateConstrElem( ksDocument3D * doc );

char buf[MAX_TEXT_LENGTH];

//------------------------------------------------------------------------------
//
// ---
extern "C" void far __export __pascal  LibraryEntry( UINT Comm ) {
  kompas = (KompasObject*)::CreateKompasObject();
  if ( kompas ) {
    ksDocument3D* doc = (ksDocument3D*)kompas->ActiveDocument3D();
    if ( doc ) {
      switch ( Comm ) {
        case 1  : ::ConstrAxisOperations( doc ); break; //   
        case 2  : ::ConstrAxis2Point( doc );	   break; //     
        case 3  : ::ConstrAxisEdge( doc );       break; //  ,   
//        case 4  : ::ConstrAxisConeface( doc );   break; //    
        case 5  : ::CreateConstrElem( doc );	   break; //  ,    ,      -
        case 6  : ::ConstrPlane3Point( doc );     break; //    
      }
    }
    else
      kompas->ksError( StringToOleStr("3D   ") );
    kompas->Release();
  }
}

//------------------------------------------------------------------------------
//   
// ---
void ConstrAxisOperations( ksDocument3D * doc ) {
	ksPart * part = (ksPart*)doc->GetPart(pNew_Part); //  
	if ( part ) {
    ksEntity * entitySketch = (ksEntity*)part->NewEntity(o3d_sketch);
		if ( entitySketch ) {
			//   
			ksSketchDefinition * sketchDef = (ksSketchDefinition*)entitySketch->GetDefinition();
			if ( sketchDef ) {
				//     XOY
				ksEntity * basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
				sketchDef->SetPlane( basePlane ); //   XOY   
				entitySketch->Create();           //  

				//   
				ksDocument2D * sketchEdit = (ksDocument2D*)sketchDef->BeginEdit();
          sketchEdit->ksCircle( 20, 0, 10, 1 );
					sketchEdit->ksLineSeg( 0, 0, 0, 5, 3 );
				sketchDef->EndEdit();                   //   

				ksEntity * entityRotate = (ksEntity*)part->NewEntity(o3d_baseRotated);
				if ( entityRotate ) {
					ksBaseRotatedDefinition * rotateDef = (ksBaseRotatedDefinition*)entityRotate->GetDefinition(); //    
					if ( rotateDef ) {
     				ksRotatedParam * rotproperty = (ksRotatedParam*)rotateDef->RotatedParam();
						if ( rotproperty ) {
							rotproperty->set_direction( dtBoth );
              rotproperty->set_toroidShape(false);
						}

						rotateDef->SetThinParam( true, dtBoth, 1, 1 ); //     
						rotateDef->SetSideParam( true, 180 );
            rotateDef->SetSideParam( false, 180 );
						rotateDef->SetSketch( entitySketch );          //   
						entityRotate->Create();                        //  

						sketchDef->EndEdit();      //   
						entitySketch->_Update();    //   
						entityRotate->_Update();    //    
					}
				}
				//     
				ksEntity * entityAxisOperation = (ksEntity*)part->NewEntity(o3d_axisOperation);
				if ( entityAxisOperation ) {
					ksAxisOperationsDefinition * axisOperation = (ksAxisOperationsDefinition*)entityAxisOperation->GetDefinition();
					if ( axisOperation ) {
						axisOperation->SetOperation(entityRotate);
						entityAxisOperation->Create();                        //  
					}
				}
				kompas->ksMessage( StringToOleStr(" ") );
			}
		}
	}
}

//------------------------------------------------------------------------------
//     
// ---
void ConstrAxis2Point( ksDocument3D * doc ) {
	ksPart * part = (ksPart*)doc->GetPart(pNew_Part); //  
	if ( part ) {
		ksEntity * entitySketch = (ksEntity*)part->NewEntity(o3d_sketch);
		if ( entitySketch ) {
			//   
			ksSketchDefinition * sketchDef = (ksSketchDefinition*)entitySketch->GetDefinition();
			if ( sketchDef ) {
				//     XOY
				ksEntity * basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
				sketchDef->SetPlane( basePlane ); //   XOY   
	//  				sketchDef.SetAngle( 45 );        //   
				entitySketch->Create();           //  

				//   
				ksDocument2D * sketchEdit = (ksDocument2D*)sketchDef->BeginEdit();
					//    - 
					sketchEdit->ksLineSeg(  50,  50, -50,  50, 1 );
					sketchEdit->ksLineSeg(  50, -50, -50, -50, 1 );

					sketchEdit->ksLineSeg(  50, -50,  50,  50, 1 );
					sketchEdit->ksLineSeg( -50, -50, -50,  50, 1 );
				sketchDef->EndEdit();                   //   

				ksEntity * entityExtr = (ksEntity*)part->NewEntity(o3d_baseExtrusion);
				if ( entityExtr ) {
					//     
					ksBaseExtrusionDefinition * extrusionDef = (ksBaseExtrusionDefinition*)entityExtr->GetDefinition(); //    
					if ( extrusionDef ) {
						extrusionDef->set_directionType( dtNormal );         //  
						extrusionDef->SetSideParam( true/* */, etBlind/*  */, 20, 0, false );
						extrusionDef->SetThinParam( true, dtBoth, 20, 20 ); //     
						extrusionDef->SetSketch( entitySketch ); //   
						entityExtr->Create();                    //  

						sketchDef->EndEdit();   //   
						entitySketch->_Update(); //   
						entityExtr->_Update();   //    
					}
				}
			}
		}

		ksEntityCollection * entityCollection = (ksEntityCollection*)part->EntityCollection( o3d_vertex );

		//     
		ksEntity * entityAxis2Point = (ksEntity*)part->NewEntity(o3d_axis2Points);
		if ( entityAxis2Point ) {
			ksAxis2PointsDefinition * axis2Point = (ksAxis2PointsDefinition*)entityAxis2Point->GetDefinition();
			if ( axis2Point ) {
				axis2Point->SetPoint( 1, entityCollection->GetByIndex(0) );
				axis2Point->SetPoint( 2, entityCollection->GetByIndex(9) );
				entityAxis2Point->Create();
			}
		}
		kompas->ksMessage( StringToOleStr("   ") );
	}
}

//------------------------------------------------------------------------------
//  ,   
// ---
void ConstrAxisEdge( ksDocument3D * doc ) {
	ksPart * part = (ksPart*)doc->GetPart(pNew_Part); //  
	if ( part ) {
		ksEntity * entitySketch = (ksEntity*)part->NewEntity(o3d_sketch);
		if ( entitySketch ) {
			//   
			ksSketchDefinition * sketchDef = (ksSketchDefinition*)entitySketch->GetDefinition();
			if ( sketchDef ) {
				//     XOY
				ksEntity * basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
				sketchDef->SetPlane( basePlane ); //   XOY   
	//  				sketchDef.SetAngle( 45 );        //   
				entitySketch->Create();           //  

				//   
				ksDocument2D * sketchEdit = (ksDocument2D*)sketchDef->BeginEdit();
					//    - 
					sketchEdit->ksLineSeg(  50,  50, -50,  50, 1 );
					sketchEdit->ksLineSeg(  50, -50, -50, -50, 1 );

					sketchEdit->ksLineSeg(  50, -50,  50,  50, 1 );
					sketchEdit->ksLineSeg( -50, -50, -50,  50, 1 );
				sketchDef->EndEdit();                   //   

				ksEntity * entityExtr = (ksEntity*)part->NewEntity(o3d_baseExtrusion);
				if ( entityExtr ) {
					//     
					ksBaseExtrusionDefinition * extrusionDef = (ksBaseExtrusionDefinition*)entityExtr->GetDefinition(); //    
					if ( extrusionDef ) {
						extrusionDef->set_directionType( dtNormal );         //  
						extrusionDef->SetSideParam( true/* */, etBlind/*  */, 20, 0, false );
						extrusionDef->SetThinParam( true, dtBoth, 20, 20 ); //     
						extrusionDef->SetSketch( entitySketch ); //   
						entityExtr->Create();                    //  
					}
				}
			}
		}

		ksEntityCollection * entityCollection = (ksEntityCollection*)part->EntityCollection( o3d_edge );

		if ( entityCollection && entityCollection->GetCount() > 1 ) {
			//    
			ksEntity * entityAxisEdge = (ksEntity*)part->NewEntity(o3d_axisEdge);
			if ( entityAxisEdge ) {
				ksAxisEdgeDefinition * axisEdge = (ksAxisEdgeDefinition*)entityAxisEdge->GetDefinition();
				if ( axisEdge ) {
					axisEdge->SetEdge( entityCollection->GetByIndex(0) );
					entityAxisEdge->Create();
				}
			}
			kompas->ksMessage( StringToOleStr("  ") );

			//     
			ksEntity * entityAxisEdge2 = (ksEntity*)part->NewEntity(o3d_axisEdge);
			if ( entityAxisEdge2 ) {
				ksAxisEdgeDefinition * axisEdge = (ksAxisEdgeDefinition*)entityAxisEdge2->GetDefinition();
				if ( axisEdge ) {
					axisEdge->SetEdge( entityCollection->GetByIndex(1) );
					entityAxisEdge2->Create();
				}
			}
			kompas->ksMessage( StringToOleStr("   ") );
		}
	}
}

/*
//------------------------------------------------------------------------------
//    
// ---
void ConstrAxisConeface( ksDocument3D * doc ) {
	ksPart * part = (ksPart *)doc->GetPart(pNew_Part); //  
	if ( part ) {
		ksEntity * entitySketch = (ksEntity*)part->NewEntity(o3d_sketch);
		if ( entitySketch ) {
			//   
			ksSketchDefinition * sketchDef = (ksSketchDefinition*)entitySketch->GetDefinition();
			if ( sketchDef ) {
				//     XOY
				ksEntity * basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
				sketchDef->SetPlane( basePlane ); //   XOY   
				entitySketch->Create();           //  

				//   
				ksDocument2D * sketchEdit = (ksDocument2D*)sketchDef->BeginEdit();
				  sketchEdit->ksCircle( 0, 0, 50, 1 );
				sketchDef->EndEdit();                   //   

				ksEntity * entityExtr = (ksEntity*)part->NewEntity(o3d_baseExtrusion);
				if ( entityExtr ) {
					//     
					ksBaseExtrusionDefinition * extrusionDef = (ksBaseExtrusionDefinition*)entityExtr->GetDefinition(); //    
					if ( extrusionDef ) {
						extrusionDef->set_directionType( dtNormal );         //  
						extrusionDef->SetSideParam( true , etBlind, 20, 30, false, false );
						extrusionDef->SetThinParam( true, dtBoth, 10, 10 ); //     
						extrusionDef->SetSketch( entitySketch ); //   
						entityExtr->Create();                    //  
					}
				}
			}
		}

		ksEntityCollection * entityCollection = (ksEntityCollection*)part->EntityCollection( o3d_face );
		ksEntity * entityConFace = NULL;

		for ( int i = 0, count = entityCollection->GetCount(); i < count; i++ ) {
			entityConFace = (ksEntity*)entityCollection->GetByIndex(i);
			ksFaceDefinition * face = (ksFaceDefinition *)entityConFace->GetDefinition();
			if ( face->IsCone() ) //    ,    
        break;
			else
				entityConFace = NULL;
    }


		//     
		ksEntity * entityAxisConFace = (ksEntity*)part->NewEntity(o3d_axisConeFace);
		if ( entityAxisConFace ) {
			ksAxisConefaceDefinition * axisConFace = (ksAxisConefaceDefinition*)entityAxisConFace->GetDefinition();
			if ( axisConFace ) {
				axisConFace->SetFace( entityConFace );
				entityAxisConFace->Create();
			}
		}
		entityConFace = NULL;//.DetachDispatch();
		kompas->ksMessage( StringToOleStr("   ") );
	}
}
*/

//------------------------------------------------------------------------------
//  ,    ,      -
// ---
void CreateConstrElem( ksDocument3D * doc ) {
	ksPart * part = (ksPart *)doc->GetPart(pNew_Part); //  
	if ( part ) {
		ksEntity * entity = (ksEntity*)part->NewEntity(o3d_planeOffset);
		if ( entity ) {
			//    
			ksPlaneOffsetDefinition * offsetDef = (ksPlaneOffsetDefinition*)entity->GetDefinition();
			if ( offsetDef ) {
				offsetDef->set_offset( 150 ); //    
				ksEntity * basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
				basePlane->set_name( StringToOleStr("XOY") ); //   
				basePlane->_Update();         //  

				offsetDef->SetPlane( basePlane ); //  
				offsetDef->set_direction( false );       //     
				entity->set_name( StringToOleStr(" ") ); //    
				entity->Create();                 //   

				kompas->ksMessage( StringToOleStr("   ") );

				offsetDef->set_offset( 50 );       //     
				basePlane = NULL;//.DetachDispatch();
				//    
				basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeYOZ);
        //.AttachDispatch( part.GetDefaultEntity(o3d_planeYOZ), FALSE );
				basePlane->set_name( StringToOleStr("YOZ") );
		  	basePlane->_Update();              //  

				offsetDef->set_direction( true );        //      
				offsetDef->SetPlane( basePlane );
				entity->_Update();                 //  

				basePlane = NULL;//.DetachDispatch();
				//    
				basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
        //AttachDispatch( part.GetDefaultEntity(o3d_planeXOY), FALSE );
				basePlane->set_name( StringToOleStr("XOY") );

				kompas->ksMessage( StringToOleStr("    ") );

				//     
				ksEntity * entityAxis = (ksEntity*)part->NewEntity(o3d_axis2Planes);
				if ( entityAxis ) {
					ksAxis2PlanesDefinition * axis2PlanesDef = (ksAxis2PlanesDefinition*)entityAxis->GetDefinition();
					if ( axis2PlanesDef ) {
						axis2PlanesDef->SetPlane( 1, entity );    //   1
						axis2PlanesDef->SetPlane( 2, basePlane ); //   2
						entityAxis->set_name( StringToOleStr("   ") ); //   
						entityAxis->Create();                   //  

						kompas->ksMessage( StringToOleStr("       ") );

						basePlane = NULL;//.DetachDispatch();
						//    
						basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOZ);
            //AttachDispatch( part.GetDefaultEntity(o3d_planeXOZ), FALSE );
						basePlane->set_name( StringToOleStr("XOZ") );

						axis2PlanesDef->SetPlane( 2,basePlane ); //   2
						entityAxis->_Update();

						kompas->ksMessage( StringToOleStr("      \n     45") );

						ksEntity * entityAnglePlane = (ksEntity*)part->NewEntity(o3d_planeAngle);
						if ( entityAnglePlane )  {
							//        
							ksPlaneAngleDefinition * planeAngleDef = (ksPlaneAngleDefinition*)entityAnglePlane->GetDefinition();
							if ( planeAngleDef ) {
								planeAngleDef->set_angle( 45 );        //     
								planeAngleDef->SetPlane( entity );    //  
								planeAngleDef->SetAxis( entityAxis ); //  
								entityAnglePlane->set_name( StringToOleStr("     ") );
								entityAnglePlane->Create();           //    

								kompas->ksMessage( StringToOleStr("    ") );

								planeAngleDef->SetPlane( basePlane ); //  
								entityAnglePlane->_Update();           //   
							}
						}
					}
				}
			}
		}
	}
}

//------------------------------------------------------------------------------
//    
// ---
void ConstrPlane3Point( ksDocument3D * doc ) {
	ksPart * part = (ksPart *)doc->GetPart(pNew_Part); //  
	if ( part ) {
		ksEntity * entitySketch = (ksEntity*)part->NewEntity(o3d_sketch);
		if ( entitySketch ) {
			//   
			ksSketchDefinition * sketchDef = (ksSketchDefinition*)entitySketch->GetDefinition();
			if ( sketchDef ) {
				//     XOY
				ksEntity * basePlane = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY);
				sketchDef->SetPlane( basePlane ); //   XOY   
				entitySketch->Create();           //  

				//   
				ksDocument2D * sketchEdit = (ksDocument2D*)sketchDef->BeginEdit(); 
					//    - 
					sketchEdit->ksLineSeg(  50,  50, -50,  50, 1 );
					sketchEdit->ksLineSeg(  50, -50, -50, -50, 1 );

					sketchEdit->ksLineSeg(  50, -50,  50,  50, 1 );
					sketchEdit->ksLineSeg( -50, -50, -50,  50, 1 );
				sketchDef->EndEdit();                   //   

				ksEntity * entityExtr = (ksEntity*)part->NewEntity(o3d_baseExtrusion);
				if ( entityExtr ) {
					//     
					ksBaseExtrusionDefinition * extrusionDef = (ksBaseExtrusionDefinition*)entityExtr->GetDefinition(); //    
					if ( extrusionDef ) {
						extrusionDef->set_directionType( dtNormal );         //  
						extrusionDef->SetSideParam( true/* */, etBlind/*  */, 20, 30, false );
						extrusionDef->SetThinParam( true, dtBoth, 10, 10 ); //     
						extrusionDef->SetSketch( entitySketch ); //   
						entityExtr->Create();                    //  
					}
				}
			}
		}

		ksEntityCollection * entityCollection = (ksEntityCollection*)part->EntityCollection( o3d_vertex );

		//    
		ksEntity * entityConstrPlane3Point = (ksEntity*)part->NewEntity( o3d_plane3Points );
		if ( entityConstrPlane3Point ) {
			ksPlane3PointsDefinition * constrPlane3Point = (ksPlane3PointsDefinition*)entityConstrPlane3Point->GetDefinition();
			if ( constrPlane3Point ) {
				constrPlane3Point->SetPoint(1, entityCollection->GetByIndex(0));
				constrPlane3Point->SetPoint(2, entityCollection->GetByIndex(1));
				constrPlane3Point->SetPoint(3, entityCollection->GetByIndex(2));
				entityConstrPlane3Point->Create();
			}
		}
		kompas->ksMessage( StringToOleStr("   ") );
	}
}



