/*======================================================================================================*/
/* Telespace map plugin, GUI										*/
/*													*/
/* Plugin for EQUINOX-3D										*/
/*													*/
/* - Mover object class											*/
/*													*/
/* AUTHOR:	Gabor Nagy										*/
/* DATE:	2002-Dec-17 15:26:24									*/
/*													*/
/* EQUINOX-3D(TM), 3DPanel(TM) and 3DLib(TM) Copyright (C) 1995 By Gabor Nagy. All rights reserved.	*/
/*======================================================================================================*/
#include <stdio.h>

#include <EMalloc.h>
#include <EPlugins.h>


#include <E3D/EMacros.h>
#include <E3D/3DWindow.h>

#include <EGUI/PushButton.h>
#include <EGUI/Dialog.h>

#include <Xe/Matrix.h>
#include <Xe/Scale.h>
#include <Xe/ToggleButton.h>


#include "Map.h"

#include "Mover.h"


extern int	TSMap_EditProc(E3dModel* LModel, E3dModelInfo* LInfo);


// Mover Object
//
#define ROffset(field) (void*)(EPtrOffset(E3dMoverInfo, field))
EResource _MoverResources[]=
{
 { "TranslationVelocity X",	EResFLOAT32,	ROffset(TVx), NULL },
 { "TranslationVelocity Y",	EResFLOAT32,	ROffset(TVy), NULL },
 { "TranslationVelocity Z",	EResFLOAT32,	ROffset(TVz), NULL },

 { "RotationVelocity X",	EResFLOAT32,	ROffset(RVx), NULL },
 { "RotationVelocity Y",	EResFLOAT32,	ROffset(RVy), NULL },
 { "RotationVelocity Z",	EResFLOAT32,	ROffset(RVz), NULL },

 { "",		EResNULL,	NULL, NULL }
};
#undef ROffset

// Class template
//
E3dMoverInfo		TSMap_MoverInfo;



static Widget		_TranslationVelocityX,
			_TranslationVelocityY,
			_TranslationVelocityZ,
			_RotationVelocityX,
			_RotationVelocityY,
			_RotationVelocityZ;


static Arg		Args[256];
static Cardinal		ArgCnt;


enum
{
 CR_SET_TV_X,
 CR_SET_TV_Y,
 CR_SET_TV_Z,

 CR_SET_TA_X,
 CR_SET_TA_Y,
 CR_SET_TA_Z,

 CR_SET_RV_X,
 CR_SET_RV_Y,
 CR_SET_RV_Z,

 CR_SET_RA_X,
 CR_SET_RA_Y,
 CR_SET_RA_Z,

 CR_SET_DRAG_X,
 CR_SET_DRAG_Y,
 CR_SET_DRAG_Z
};


#define _M_SetFloat(mField)\
 for(LC=0;LC<_NumOfTelespaceModels;LC++)\
 {\
  LInfo=(E3dMoverInfo*)E3d_ModelInfoByClass(TSMap_EditedModels[LC], TSMap_MoverInfo.Class);\
\
  if(LInfo)\
  {\
   LInfo->mField=((XeScaleCallbackStruct*)LCallData)->FloatValue;\
   break;\
  }\
 }



/*==============================================*/
/* Widget callback handler for the Mover class	*/
/*==============================================*/
static void _CB_Mover(Widget LI, XtPointer LClientData, XtPointer LCallData)
{
 E3dMoverInfo*	LInfo;
 unsigned int	LC;


 switch((int)LClientData)
 {
  case CR_SET_TV_X:
   _M_SetFloat(TVx);
  break;

  case CR_SET_TV_Y:
   _M_SetFloat(TVy);
  break;

  case CR_SET_TV_Z:
   _M_SetFloat(TVz);
  break;

  case CR_SET_RV_X:
   _M_SetFloat(TVx);
  break;

  case CR_SET_RV_Y:
   _M_SetFloat(TVy);
  break;

  case CR_SET_RV_Z:
   _M_SetFloat(TVz);
  break;
 }
}


/*==============================================*/
/* Update GUI from the class record		*/
/*==============================================*/
void TS_MoverUpdateGUI()
{
 E3dMoverInfo*	LInfo;
 unsigned int	LC;


 for(LC=0;LC<_NumOfTelespaceModels;LC++)
 {
  LInfo=(E3dMoverInfo*)E3d_ModelInfoByClass(TSMap_EditedModels[LC], TSMap_MoverInfo.Class);

  if(LInfo)
  {
   XeScaleSetValueD(_TranslationVelocityX, LInfo->TVx, False);
   XeScaleSetValueD(_TranslationVelocityY, LInfo->TVy, False);
   XeScaleSetValueD(_TranslationVelocityZ, LInfo->TVz, False);
   XeScaleSetValueD(_RotationVelocityX, LInfo->RVx, False);
   XeScaleSetValueD(_RotationVelocityY, LInfo->RVy, False);
   XeScaleSetValueD(_RotationVelocityZ, LInfo->RVz, False);

   break;
  }
 }
}


static Widget CreateSlider(char* LName, int InitValue, int MaxValue, XtPointer LClientData, Widget LMatrixW)
{
 Widget		w;

 EXtStart;
 EXtSetArg(XeNscaleLengthInPixels, 200);
 EXtSetArg(XeNtextFieldDigits, 8);EXtSetArg(XeNdecimalPoints, 2);
 
 EXtSetArg(XeNminimum, 0);EXtSetArg(XeNmaximum, MaxValue*100.0);
 EXtSetArg(XeNvalue, (int)(InitValue*100.0));

 EXtSetArg(XeNincrement, 10);
 EXtSetArg(XeNorientation, XeHORIZONTAL);
 E3dp_SetScaleArgs(Args, &ArgCnt);

 w = XtCreateManagedWidget(LName, xeScaleWidgetClass, LMatrixW, Args, ArgCnt);
 XtAddCallback(w, XeNvalueChangedCallback, (XtCallbackProc)_CB_Mover, LClientData);

 return(w);
}


/*==============================================*/
/* Create Matrix widget				*/
/*==============================================*/
Widget TS_MoverCreateMatrix(Widget LParentW)
{
 Widget		LMatrixW;
 Widget		LWAs[16];
 Widget		LTWs[42];	// For TextField traversal
 unsigned int	LWAN, LTrN;


 EXtStart;
 EXtSetArg(XeNshadowThickness, 0);
 EXtSetArg(XeNbackground, EGUI_BackgroundColor);
 EXtSetArg(XeNorientation, XeVERTICAL);
 EXtSetArg(XeNxSpacing, 4);EXtSetArg(XeNySpacing, 4);
 LMatrixW=XtCreateWidget("MoverMatrixW", xeMatrixWidgetClass, LParentW, Args, ArgCnt);


// Create Scale widgets (sliders with labels and TextFields)
//
 LWAN=0;
 LTrN=0;
 LWAs[LWAN++]=LTWs[LTrN++]=_TranslationVelocityX = CreateSlider("Translation Velocity X", TSMap_MoverInfo.TVx, 100, (XtPointer)CR_SET_TV_X, LMatrixW);
 LWAs[LWAN++]=LTWs[LTrN++]=_TranslationVelocityY = CreateSlider("Translation Velocity Y", TSMap_MoverInfo.TVy, 100, (XtPointer)CR_SET_TV_Y, LMatrixW);
 LWAs[LWAN++]=LTWs[LTrN++]=_TranslationVelocityZ = CreateSlider("Translation Velocity Z", TSMap_MoverInfo.TVz, 100, (XtPointer)CR_SET_TV_Z, LMatrixW);

 LWAs[LWAN++]=LTWs[LTrN++]=_RotationVelocityX = CreateSlider("Rotation Velocity X", TSMap_MoverInfo.RVx, 360, (XtPointer)CR_SET_RV_X, LMatrixW);
 LWAs[LWAN++]=LTWs[LTrN++]=_RotationVelocityY = CreateSlider("Rotation Velocity Y", TSMap_MoverInfo.RVy, 360, (XtPointer)CR_SET_RV_Y, LMatrixW);
 LWAs[LWAN++]=LTWs[LTrN++]=_RotationVelocityZ = CreateSlider("Rotation Velocity Z", TSMap_MoverInfo.RVz, 360, (XtPointer)CR_SET_RV_Z, LMatrixW);

// Ident Scale widgets from left, so the slider parts are aligned
//
 XeIndentWidgetsFromLeft(LWAs, LWAN, 4);

// Set up TextField traversal
//
 XeRingTraversal(LTWs, LTrN);

 return(LMatrixW);
}


/*==============================================*/
/* EditProc for the "Telespace" Model type	*/
/*==============================================*/
static int _EditProc(E3dModel* LModel, E3dModelInfo* LInfo)
{
 TSTmpl_EditProc(E3dMover, TSMap_Mover);
}


/*==============================================*/
/* Initialize class				*/
/*==============================================*/
void TS_MoverInit()
{
 E3dModelClass	LMoverClass=
   {
    "Mover",			// Name
    sizeof(E3dMoverInfo),	// StructSize
    _EditProc,			// EditProc
    NULL,			// RemoveProc
    NULL,			// DestroyProc
    _MoverResources		// Resources
   };

 TSMap_MoverInfo.Class=E3d_ModelClassRegister(&LMoverClass);

 TSMap_MoverInfo.TVx = 0.0f;
 TSMap_MoverInfo.TVy = 0.0f;
 TSMap_MoverInfo.TVz = 0.0f;

 TSMap_MoverInfo.RVx = 0.0f;
 TSMap_MoverInfo.RVy = 0.0f;
 TSMap_MoverInfo.RVz = 0.0f;
}


/*==============================================*/
/* Deactivate class				*/
/*==============================================*/
void TS_MoverDeactivate()
{
 if(TSMap_MoverInfo.Class) E3d_ModelClassDeactivate(TSMap_MoverInfo.Class);
}
