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

#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 GetSetPartName( ksDocument3D * doc );
void FixAndStandartComponent( ksDocument3D * doc );
void GetSetColorProperty( ksDocument3D * doc );
void GetSetArrayVariable( ksDocument3D * doc );
void GetSetPlacmentComponent( ksDocument3D * doc );
void GetSetEntity( ksDocument3D * doc );
void CreateSketch( ksDocument3D * doc );
void GetArraySketch( ksDocument3D * doc );
void GetSetUserParamComponent( ksDocument3D * doc );
void CreateDocument3D();
void DocIterator();
void UseEntityCollection();

char buf[MAX_TEXT_LENGTH];

//------------------------------------------------------------------------------
//
// ---
extern "C" void far __export __pascal  LibraryEntry( UINT Comm ) {
  kompas = (KompasObject*)::CreateKompasObject();
  if ( kompas ) {
    switch ( Comm ) {
		  case 1 :  ::CreateDocument3D();     break;  //  
			case 2 :  ::DocIterator();          break;  //   
			case 3 :  ::UseEntityCollection();  break;  //   

      default : {
				ksDocument3D* doc = (ksDocument3D*)kompas->ActiveDocument3D();
				if ( doc ) {
					switch ( Comm ) {
						case 4  : ::GetSetPartName( doc );	         break; // /  
						case 5  : ::FixAndStandartComponent( doc );	 break; //     
						case 6  : ::GetSetColorProperty( doc );      break; //      
						case 7  : ::GetSetArrayVariable( doc );  		 break; //      
						case 8  : ::GetSetPlacmentComponent( doc );	 break; //        
						case 9  : ::GetSetEntity( doc );             break; //   ksEntity        
						case 10  : ::CreateSketch( doc );             break; //  
						case 11 : ::GetArraySketch( doc );           break; //   ( )     ksEntityCollection ( IEntityCollection )
						case 12 : ::GetSetUserParamComponent( doc ); break; //       
					}
				}
        else
          kompas->ksError( StringToOleStr("3D   ") );
			}
    }
    kompas->Release();
  }
}

//------------------------------------------------------------------------------
//     
// ---
void GetSetPartName( ksDocument3D * doc ) {
  ksPart * part = (ksPart*)doc->GetPart(pTop_Part); //  
  if ( part ) {
		::sprintf( buf, "  %s", WideCharToString(part->get_name()) );
		kompas->ksMessage( StringToOleStr(buf) );
		part->set_name( StringToOleStr("") );
		part->_Update();
	}
}

//------------------------------------------------------------------------------
//     
// ---
void FixAndStandartComponent( ksDocument3D * doc ) {
	if ( doc->IsDetail() ) {
		kompas->ksError(StringToOleStr("    "));
		return;
  }
  ksPart * part = (ksPart*)doc->GetPart(0); //    
	if ( part ) {
		//     -       - fixedComponent
		int fix = part->get_fixedComponent();
		//     -       - standardComponent
		int stand = part->get_standardComponent();
		kompas->ksMessage( fix ? StringToOleStr(" ") : StringToOleStr("  ") );
		//     -       - fixedComponent
		part->set_fixedComponent(!fix);
		kompas->ksMessage( stand ? StringToOleStr(" ") : StringToOleStr(" ") );
		//     -       - standardComponent
		part->set_standardComponent(!stand);
	}
}

//------------------------------------------------------------------------------
//      
// ---
void GetSetColorProperty( ksDocument3D * doc ) {
  ksPart * part = (ksPart*)doc->GetPart(pTop_Part); //  
  if ( part ) {
		ksColorParam * colorPr = (ksColorParam*)part->ColorParam();
		if ( colorPr ) {
			::sprintf( buf, "  = %d\n  = %g\n = %g\n  = %g\n = %g\n = %g\n = %g",
				colorPr->get_color(), colorPr->get_ambient(), colorPr->get_diffuse(),
				colorPr->get_specularity(), colorPr->get_shininess(),
				colorPr->get_transparency(), colorPr->get_emission() );
			kompas->ksMessage( StringToOleStr(buf) );
			colorPr->set_color(5421504);
			colorPr->set_transparency(0.5);
			colorPr->set_ambient(0.1);
			colorPr->set_diffuse(0.1);
			part->_Update();
			::sprintf( buf, "  = %d\n  = %g\n = %g\n  = %g\n = %g\n = %g\n = %g",
				colorPr->get_color(), colorPr->get_ambient(), colorPr->get_diffuse(),
				colorPr->get_specularity(), colorPr->get_shininess(),
				colorPr->get_transparency(), colorPr->get_emission() );
			kompas->ksMessage( StringToOleStr(buf) );
		}
  }
/*	//      
  double ambient, diffuse, specularity, shininess, transparency, emission;
	long color;
	part.GetAdvancedColor( &color, &ambient, &diffuse, &specularity, &shininess, &transparency, &emission );
	::sprintf( buf, "  = %d\n  = %g\n = %g\n  = %g\n = %g\n = %g\n = %g", //"color = %d\nambient = %g\ndiffuse = %g\nspecularity = %g\nshininess = %g\ntransparency = %g\nemission = %g",
	           color, ambient, diffuse, specularity, shininess, transparency, emission );
	kompas.ksMessage(buf);
	color = 9421504; transparency = 0.5; ambient = 0.1; diffuse = 0.1;
	part.SetAdvancedColor( color, ambient, diffuse, specularity, shininess, transparency, emission );
	part.GetAdvancedColor( &color, &ambient, &diffuse, &specularity, &shininess, &transparency, &emission );
	::sprintf( buf, "  = %d\n  = %g\n = %g\n  = %g\n = %g\n = %g\n = %g", //"color = %d\nambient = %g\ndiffuse = %g\nspecularity = %g\nshininess = %g\ntransparency = %g\nemission = %g",
	           color, ambient, diffuse, specularity, shininess, transparency, emission );
	kompas.ksMessage(buf);
	part.Update();

*/
}

//------------------------------------------------------------------------------
//      
// ---
void GetSetArrayVariable( ksDocument3D * doc ) {
	if ( doc->IsDetail() ) {
		kompas->ksError(StringToOleStr("    "));
		return;
  }
  ksPart * part = (ksPart*)doc->GetPart(0); //    
  if ( part ) {
		//     
		ksVariableCollection * varCol = (ksVariableCollection*)part->VariableCollection();
		if ( varCol ) {
      ksVariable * var = (ksVariable*)kompas->GetParamStruct(ko_VariableParam);
			if ( !var )
				return;
			for ( int i = 0, count = varCol->GetCount(); i < count; i++ ) {
				var = (ksVariable*)varCol->GetByIndex(i);
				::sprintf( buf, "       %d\n           %s\n   %g\n       %s", i, var->get_name(), var->get_value(), var->get_note() );
				kompas->ksMessage( StringToOleStr(buf) );
        var->set_note(StringToOleStr("qwerty"));
        double d = 0;
        kompas->ksReadDouble( StringToOleStr(" "), 10, 0, 100, &d );
        var->set_value(d);
				var = NULL;
			}

			for ( int j = 0, count2 = varCol->GetCount(); j < count2; j++ ) { //   
				var = (ksVariable*)varCol->GetByIndex(j);
				::sprintf( buf, "       %d\n           %s\n   %g\n       %s", j, var->get_name(), var->get_value(), var->get_note() );
				kompas->ksMessage( StringToOleStr(buf) );
				var = NULL;
			}
			part->RebuildModel();  //  
		}
	}
}

//------------------------------------------------------------------------------
//       
// ---
void GetSetPlacmentComponent( ksDocument3D * doc ) {
	if ( doc->IsDetail() ) {
		kompas->ksError(StringToOleStr("    "));
		return;
  }
  ksPart * part = (ksPart*)doc->GetPart(0); //    
  if ( part ) {
		ksPlacement * plac = (ksPlacement*)part->GetPlacement();
		if ( plac ) {
			double x, y, z;
			plac->GetOrigin( &x, &y, &z );
			::sprintf( buf, "x = %g\ny = %g\nz = %g", x, y, z );
			kompas->ksMessage( StringToOleStr(buf) );
			plac->SetOrigin( 20, 20, 20 );
			part->UpdatePlacement();
			part->_Update();
		}
	}
}

//------------------------------------------------------------------------------
//      
// ---
void GetSetEntity( ksDocument3D * doc ) {
  ksPart * part = (ksPart*)doc->GetPart(pTop_Part); //  
  if ( part ) {
		ksEntity * planeXOY = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY); // 1-   XOY
		if ( planeXOY ) {
			kompas->ksMessage( StringToOleStr(planeXOY->get_name()) );
			planeXOY->set_name( StringToOleStr("plane") );
			planeXOY->_Update();
		}
	}
}

//------------------------------------------------------------------------------
//  
// ---
void CreateSketch( ksDocument3D * doc ) {
  ksPart * part = (ksPart*)doc->GetPart(pTop_Part); //  
	if ( part ) {
		ksEntity * planeXOY = (ksEntity*)part->GetDefaultEntity(o3d_planeXOY); // 1-   XOY
		ksEntity * entity = (ksEntity*)part->NewEntity(o3d_sketch);
		if ( planeXOY && entity ) {
			ksSketchDefinition * sketch = (ksSketchDefinition*)entity->GetDefinition();
			if ( sketch ) {
				sketch->SetPlane( planeXOY );
				entity->Create();
				ksDocument2D * sketchDoc = (ksDocument2D*)sketch->BeginEdit();
  				sketchDoc->ksLineSeg( 0, 0, 100, 100, 1 );
				sketch->EndEdit();
			}
		}
	}
}

//------------------------------------------------------------------------------
//   
// ---
void GetArraySketch( ksDocument3D * doc ) {
  ksPart * part = (ksPart*)doc->GetPart(pTop_Part); //  
  if ( part ) {
		ksEntityCollection * entityCollection = (ksEntityCollection*)part->EntityCollection( o3d_sketch );
		ksEntity * currentEntity = NULL;
		if ( entityCollection ) {
			for ( int i = 0; i < entityCollection->GetCount(); i++ ) {
				currentEntity = (ksEntity*)entityCollection->GetByIndex(i);
				kompas->ksMessage( currentEntity->get_name() );
				currentEntity = NULL;
			}
		}
	}
}

//------------------------------------------------------------------------------
//       
// ---
void GetSetUserParamComponent( ksDocument3D * doc ) {
	if ( doc->IsDetail() ) {
		kompas->ksError(StringToOleStr("    "));
		return;
  }
  ksPart * part = (ksPart*)doc->GetPart(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 || !part )
		return;

	par->Init();
	par->SetUserArray( arr );
	item->Init();
	  item->set_doubleVal( 12.12 );
	  arr->ksAddArrayItem( -1, item );
	item->Init();
  	item->set_doubleVal( 21.21 );
		arr->ksAddArrayItem( -1, item );
  item->Init();
	  item->set_intVal(666);
	  arr->ksAddArrayItem( -1, item );
  item->Init();
	  item->set_intVal(999);
	  arr->ksAddArrayItem( -1, item );

	part->SetUserParam(par); //   
	part->_Update();

	::sprintf( buf, "   %d", part->GetUserParamSize() ); //   
	kompas->ksMessage( StringToOleStr(buf) );

	ksUserParam * par2 = (ksUserParam*)kompas->GetParamStruct(ko_UserParam);
  ksLtVariant * item2 = (ksLtVariant*)kompas->GetParamStruct(ko_LtVariant);
	ksDynamicArray * arr2 = (ksDynamicArray*)kompas->GetDynamicArray(LTVARIANT_ARR);
	if ( !par2 || !item2 || !arr2 )
		return;

	par2->Init();
	par2->SetUserArray( arr2 );
	item2->Init();
	  item2->set_doubleVal( 0 );
	  arr2->ksAddArrayItem( -1, item2 );
	item2->Init();
  	item2->set_doubleVal( 0 );
		arr2->ksAddArrayItem( -1, item2 );
  item2->Init();
	  item2->set_intVal( 0 );
	  arr2->ksAddArrayItem( -1, item2 );
  item2->Init();
	  item2->set_intVal( 0 );
	  arr2->ksAddArrayItem( -1, item2 );

	part->GetUserParam( par2 ); //  e 

	struct {
		double a, b;
		int c, d;
	} d;
  arr2->ksGetArrayItem( 0, item2 );
	d.a = item2->get_doubleVal();
  arr2->ksGetArrayItem( 1, item2 );
	d.b = item2->get_doubleVal();
  arr2->ksGetArrayItem( 2, item2 );
	d.c = item2->get_intVal();
  arr2->ksGetArrayItem( 3, item2 );
	d.d = item2->get_intVal();
	::sprintf( buf, "  \na = %g\nb = %g\nc = %d\nd = %d", d.a, d.b, d.c, d.d );
	kompas->ksMessage( StringToOleStr(buf) ); //     
}

//------------------------------------------------------------------------------
//  3D 
// ---
void CreateDocument3D() {
//	ksPart * part = (ksPart*)doc->GetPart(pNew_Part); //  
	ksDocument3D * doc = (ksDocument3D*)kompas->Document3D();
  if ( doc->Create(false/**/, true/**/) ) {
    doc->set_author(StringToOleStr(""));                //  
    doc->set_comment(StringToOleStr("  3D")); //   
		doc->set_fileName( StringToOleStr("c:\\example.m3d") );  //   
    doc->UpdateDocumentParam();             //   
		doc->Save();                            //  
		kompas->ksMessage( StringToOleStr("    ") );
    doc->SaveAs( StringToOleStr("c:\\example_1.m3d") );     //     

		//  
		::sprintf( buf, " : %s", WideCharToString(doc->get_author()) );
		kompas->ksMessage(StringToOleStr(buf));
		//   
		::sprintf( buf, "  : %s", WideCharToString(doc->get_comment()) );
		kompas->ksMessage(StringToOleStr(buf));
    //  
		::sprintf( buf, " : %s", WideCharToString(doc->get_fileName()) );
		kompas->ksMessage(StringToOleStr(buf));

		doc->close(); //  
	}
}

//------------------------------------------------------------------------------
//   
// ---
void DocIterator() {
	ksDocument3D * doc = NULL;
	ksDynamicArray * arrDoc = (ksDynamicArray*)kompas->GetDynamicArray(CHAR_STR_ARR); //      
	//       
  if ( arrDoc && kompas->ksChoiceFiles( StringToOleStr("*.m3d"),StringToOleStr(" (*.m3d)|*.m3d|  (*.*)|*.*|"), arrDoc, false) ) {
    ksChar255 * item = (ksChar255*)kompas->GetParamStruct(ko_Char255);
		if ( item ) {
			//     
      for ( int i = 0, count = arrDoc->ksGetArrayCount(); i < count; i++ ) {
				if ( arrDoc->ksGetArrayItem(i, item) ) {
					//   
					doc = (ksDocument3D*)kompas->Document3D();//, FALSE/* */ );
					doc->Open( item->get_str(), false ); //     
					doc = NULL;//->DetachDispatch(); //  
				}
			}
		}

		//    
    ::sprintf( buf, " %i ", arrDoc->ksGetArrayCount() );
    kompas->ksMessage( StringToOleStr(buf) );

		//    
		ksIterator * iter =(ksIterator*)kompas->GetIterator();
		if ( iter ) {
			if ( iter->ksCreateIterator(D3_DOCUMENT_OBJ/* */, 0) ) {
				reference ref; //  
				if ( ref == iter->ksMoveIterator(StringToOleStr("F")) ) { //     
					do { //     
						//   
						doc = (ksDocument3D*)kompas->ksGet3dDocumentFromRef(ref);
						if ( doc ) {
							//  
							::sprintf( buf, " : %s", WideCharToString(doc->get_author()) );
							kompas->ksMessage(StringToOleStr(buf));
							//   
							::sprintf( buf, "  : %s", WideCharToString(doc->get_comment()) );
							kompas->ksMessage(StringToOleStr(buf));
							//   
							::sprintf( buf, " : %s", WideCharToString(doc->get_fileName()) );
							kompas->ksMessage(StringToOleStr(buf));
							//  
							::sprintf( buf, " : %s", doc->IsDetail() ? "" : "" );
							kompas->ksMessage(StringToOleStr(buf));
							//  
							doc = NULL;//->DetachDispatch();
						}
					} while ( ref == iter->ksMoveIterator(StringToOleStr("N")) );

				  iter->ksDeleteIterator(); //  
				}
			}
		}
	}
}

//------------------------------------------------------------------------------
//  
// ---
void UseEntityCollection() {
  ksDocument3D * doc = (ksDocument3D*)kompas->ActiveDocument3D(); //    
	if ( doc ) {
		ksPart * part = (ksPart*)doc->GetPart(pNew_Part);       //  
		if ( part ) {
			long count1;
			long count2;
			long count;

			//  
      ksEntityCollection * collect = (ksEntityCollection*)part->EntityCollection(o3d_face);
			if ( collect ) {
				count = collect->GetCount();
				count1 = 0; //   
				count2 = 0; //   
				ksColorParam * colorPr = NULL; //   
				if ( collect && count ) {
					for ( int i = 0; i < count; i++ ) {
						ksEntity * ent = (ksEntity*)collect->GetByIndex(i);
						colorPr = (ksColorParam*)ent->ColorParam();
						//   
						ksFaceDefinition * faceDef = (ksFaceDefinition *)ent->GetDefinition();
						if ( faceDef ) {
							if ( faceDef->IsCone()/* -*/ ) {
								colorPr->set_color( RGB(255, 255, 0) );
								count2++;   //   
							}

							if ( faceDef->IsPlanar()/* -*/ ) {
								colorPr->set_color( RGB(0, 255, 255) );
								count1++;   //   
							}

							colorPr = NULL;//.DetachDispatch();
							ent->_Update(); //  
						}
					}
				}
			}

			//    
			if ( count == 0 )
				kompas->ksMessage(StringToOleStr("    ") );
			else {
				::sprintf( buf, " %i   %i  ", count2, count1 );
				kompas->ksMessage( StringToOleStr(buf) );
			}

			count1 = 0;
			count2 = 0;
			//  
      ksEntityCollection * collect2 = (ksEntityCollection*)part->EntityCollection(o3d_edge);
			count = collect2->GetCount();
			if ( collect2 && count ) {
        for ( int i = 0; i < count; i++ ) {
					ksEntity * ent = (ksEntity*)collect2->GetByIndex(i);
					ksEdgeDefinition * edgeDef = (ksEdgeDefinition *)ent->GetDefinition();
					if ( edgeDef ) {
						if ( edgeDef->IsStraight() )
              count1++; //   
						else
              count2++; //   
					}
				}
			}

			//    
			if ( count == 0 )
				kompas->ksMessage( StringToOleStr("    ") );
			else {
				::sprintf( buf, " %i   %i  ", count1, count2 );
				kompas->ksMessage( StringToOleStr(buf) );
			}
		}
	}
}




