// slideWrk.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include <math.h>
#include "slideWrk.h"
#include <ldefin2d.h>

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

#include <ksConstants.h>

#ifndef __TESTMOVE_H
#include "testmove.h"
#endif

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

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CSlideWrkApp

BEGIN_MESSAGE_MAP(CSlideWrkApp, CWinApp)
	//{{AFX_MSG_MAP(CSlideWrkApp)
		// 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()

/////////////////////////////////////////////////////////////////////////////
// CSlideWrkApp construction

CSlideWrkApp::CSlideWrkApp()
{
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CSlideWrkApp object

CSlideWrkApp theApp;

//-------------------------------------------------------------------------------
//
// ---
char* WINAPI LIBRARYNAME(){
	return  " ";
}

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

KompasObject kompas( NULL );

//-------------------------------------------------------------------------------
// ,       
//-------------------------------------------------------------------------------
void TestShowDialog() {
	//      .exe ,     
	//   dll   define
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	kompas.ksEnableTaskAccess( 0 ); //    
	TestDlg *pDialog = new TestDlg();
	if ( pDialog ) {
		pDialog->DoModal();
		delete pDialog;
	}
	kompas.ksEnableTaskAccess( 1 ); //    
}

void WriteSlideStep( ksDocument2D& doc );
void DecomposeSlideStep( ksDocument2D& doc );

void Symmetry( float x, float y, float x1, float y1, float x2, float y2,
               float *xc, float *yc );


//-------------------------------------------------------------------------------
//
// ---
void GetKompas() {
	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 );
		}
	}
}


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

	GetKompas();
	if ( kompas.m_lpDispatch ) {
		ksDocument2D doc( kompas.ActiveDocument2D() );
		if ( doc.m_lpDispatch && doc.GetReference() ) {
			switch ( comm ) {
				case 1 : MoveSlide();               break; //    
				case 2 : WriteSlideStep( doc );			break; //  
				case 3 : TestShowDialog();					break; //  
				case 4 : DecomposeSlideStep( doc ); break; //  
			}
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// TestDlg dialog


TestDlg::TestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(TestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(TestDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
  IdSlide  = 100;
}


void TestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(TestDlg)
	DDX_Control(pDX, IDC_SHOW_STATIC, m_show);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(TestDlg, CDialog)
	//{{AFX_MSG_MAP(TestDlg)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// TestDlg message handlers

void TestDlg::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	char fName[_MAX_PATH];
  ::GetModuleFileName( theApp.m_hInstance, fName, 255 );
  char *c = ::strrchr( fName, '\\');
  if ( c )
    *(c + 1) = '\0';
  ::strcat( fName, "1.rc" );

  kompas.ksDrawSlideFromFile( (long)m_show.m_hWnd, fName );
	
	// Do not call CDialog::OnPaint() for painting messages
}


//-------------------------------------------------------------------------------
//
// ---
void WriteSlideStep( ksDocument2D& doc ) {
  CString name( kompas.ksSaveFile("*.rc", 0, 0, false) );
	if ( !name.IsEmpty() ) {
		ksRequestInfo info( kompas.GetParamStruct(ko_RequestInfo) );
		if ( info.m_lpDispatch ) {
			info.Init();
			info.SetCommandsString( "   " );

			double x, y;
			if ( doc.ksCursor(info, &x, &y, NULL) ) {
				long slideID;
				if ( kompas.ksReadInt("  ", 100, 0, 32000, &slideID ) ) {
					if ( !kompas.ksWriteSlide(name, slideID, x, y) )
						kompas.ksError( "  " );
					doc.ksClearGroup( 0, true );
				}
			}
		}
  }
}


static double cx1, cy1, cx2, cy2;
static int flag;

ksDocument2D docAct( NULL );

//-------------------------------------------------------------------------------
//
// ---
static void DrawRamka() {
  if( ::fabs(cy1 - cy2) > 0 ) {
    docAct.ksLineSeg( cx1, cy1, cx1, cy2, 1 );
    docAct.ksLineSeg( cx2, cy1, cx2, cy2, 1 );
  }
  if( ::fabs(cx1 - cx2) > 0 ) {
    docAct.ksLineSeg( cx1, cy1, cx2, cy1, 1 );
    docAct.ksLineSeg( cx1, cy2, cx2, cy2, 1 );
  }
}

//------------------------------------------------------------------------------
//   ,   Cursor
// ---
int WINAPI CALLBACKPROCCURSOR( int comm, double* x, double*y, LPDISPATCH rInfo,
															 LPDISPATCH rPhan, int dynamic ) {
	ksRequestInfo info( rInfo );
	ksPhantom     phan( rPhan );
	if ( info.m_lpDispatch && phan.m_lpDispatch ) {
		phan.SetPhantom( 1 );
		ksType1 t1( phan.GetPhantomParam() );
		if( !dynamic ) { //
			if ( !flag ) {// 1 
				flag++;
				cx1 = *x; cy1= *y;
				info.SetCommandsString( "   " );
			}
			else {
				flag++;
				cx2 = *x; cy2 = *y;
				return 0;
			}
		}
		else {
			if ( flag > 0 ) {
				cx2 = *x; cy2 = *y;
				t1.SetXBase( cx2 ); 
				t1.SetYBase( cy2 );
				
				if ( docAct.ksExistObj(t1.GetGr()) )
					docAct.ksDeleteObj( t1.GetGr() );

				t1.SetGr( docAct.ksNewGroup(1) ); //  
					DrawRamka();
				docAct.ksEndGroup();
			}
		}
	}
	return 1;
}


//-------------------------------------------------------------------------------
//
// ---
void DecomposeSlideStep( ksDocument2D& doc ) {
	docAct.AttachDispatch( doc, false );
	ksRequestInfo info( kompas.GetParamStruct(ko_RequestInfo) );
	ksPhantom     phan( kompas.GetParamStruct(ko_Phantom)     );
  ksIterator    iter( kompas.GetIterator()                  );
	if ( info.m_lpDispatch && phan.m_lpDispatch && iter.m_lpDispatch ) {
		phan.Init();
		info.Init();
		info.SetCommandsString( "   " );
		info.SetDynamic( 1 );
		info.SetCallBackC( "CALLBACKPROCCURSOR", (long)theApp.m_hInstance, 0 );
		phan.SetPhantom( 1 );
		ksType1 t1( phan.GetPhantomParam() );
		if ( t1.m_lpDispatch ) {
			t1.Init();
			t1.SetScale_( 1 );
			t1.SetGr( doc.ksNewGroup(1) );
			doc.ksEndGroup();

		  flag = 0;
			double x, y;
			doc.ksCursor( info, &x, &y, phan );
			
			if ( doc.ksExistObj(t1.GetGr()) ) 
				doc.ksDeleteObj( t1.GetGr() );

			if ( flag == 2 ) {
				doc.ksClearGroup( 0, true );
				if ( doc.ksSelectGroup(0, 1, cx1, cy1, cx2, cy2) ) {
					if ( iter.ksCreateIterator(SELECT_GROUP_OBJ, 0) ) {
						t1.SetGr( doc.ksNewGroup(1) );
						doc.ksEndGroup();
						reference rObj;
						reference gr;
						if ( doc.ksExistObj(rObj = iter.ksMoveIterator("F")) ) {
							do {
								gr = doc.ksDecomposeObj(rObj, 0, 0.2, false );
								doc.ksAddObjGroup( t1.GetGr(), gr );
								doc.ksClearGroup( gr, false );
								doc.ksDeleteObj( gr );
							} while( doc.ksExistObj(rObj = iter.ksMoveIterator("N")) );
						}

						info.Init();
						t1.SetXBase( cx1 );
						t1.SetYBase( cy1 );
						info.SetCommandsString( "   " );
						if ( doc.ksCursor(info, &x, &y, phan) ) {
							doc.ksMtr( x - cx1, y - cy1, 0, 1, 1 );
							doc.ksTransformObj( t1.GetGr() );
							doc.ksDeleteMtr();
							doc.ksStoreTmpGroup( t1.GetGr() );
						}

						doc.ksClearGroup( t1.GetGr(), true );
						doc.ksDeleteObj( t1.GetGr() ); 
					}
					doc.ksClearGroup( 0, true );
				}
				else
					kompas.ksError( "" );
			}
		}
	}
}

