//================================================================
// EQUINOX-3D plugin
//
// Common code for picking controlling Splines
//
// AUTHOR:  Gabor Nagy
// DATE:    2026-Jan-07 22:53:21
//
// Copyright (C) 1996-2026 By Gabor Nagy. All rights reserved.
//================================================================


static void E3d_ScalingBySplineInit(E3dScalingBySpline* PP)
{
	PP->Active     = FALSE;
	PP->OrigSpline = NULL;
	PP->Model      = NULL;
}


static void E3d_ScalingBySplineFreeContents(E3dScalingBySpline* PP, EInterface* PInputInterface)
{
	if(PP->OrigSpline)
	{
		if(PInputInterface) E3dBaseObject_RemoveOutput((E3dBaseObject*)PP->OrigSpline, PInputInterface);
		E_DeleteChk(PP->OrigSpline);
		E_DeleteChk(PP->Model);
	}
}


static inline void E3d_ScalingBySplineCopyContents(const E3dScalingBySpline* PSrc, E3dScalingBySpline* PDst,  EInterface* PInputInterface)
{
	E3d_ScalingBySplineInit(PDst);PDst->Active = PSrc->Active;
	if(PSrc->OrigSpline)
	{
		if(PInputInterface) E3dBaseObject_AddOutput((E3dBaseObject*)PSrc->OrigSpline, PInputInterface);
		E_Assign(PSrc->OrigSpline, PDst->OrigSpline);
		E_Assign(PSrc->Model,  PDst->Model);
	}
}


//================================================================
// Pick scaling Spline callback
//================================================================
static void _PickCB_ScaleBySpline(E3dPickCallbackStruct* PPickStruct, EPointer PClientData,  const EIndex PNumOfItems, E3dItem* PPickedItems)
{
	XeApp_Sync(Xe_App);

	if(PPickStruct->Reason == E3dCR_ABORT)
	{
		_TmpInfo = NULL;
		_TmpPanel = NULL;
		_TmpScalingBySpline = NULL;
		_TmpScalingBySplineIndex = -1;
		return;
	}

// Cancel
//
	if(PPickStruct->Button == XeButton3)
	{
		E3dp_PickEnd();
		_TmpInfo = NULL;
		_TmpPanel = NULL;
		_TmpScalingBySpline = NULL;
		_TmpScalingBySplineIndex = -1;
		return;
	}

	E3dScalingBySpline*  LScalingBySpline = _TmpScalingBySpline;
	E3dScene*            LScene = E3d_Scene;

	switch(PPickStruct->Button)
	{
		case XeButton1:
			if(PNumOfItems && _TmpInfo)
			{
				E3dItem*  LItem = PPickedItems;
				E3dInfo*  LInfo = _TmpInfo;

//char s[256];printf("%s() %s:%d [%s]\n", __FUNCTION__, __FILE__, __LINE__, E3d_ItemFlagsToString(LItem->Item.Type, s));fflush(stdout);

				if(LItem->Item.Type == E3dItemSPLINE || LItem->Item.Type == E3dItemSPLINE_SEGMENT || LItem->Item.Type == E3dItemMODEL)
				{
					E3dModel*   LModel  = NULL;
					E3dSpline*  LSpline = NULL;

					if(LItem->Item.Type == E3dItemMODEL)
					{
						E3dObjItem*  LObjItem = (E3dObjItem*)LItem;

						LModel = (E3dModel*)LObjItem->Node;

						if(LModel)
						{
							EIndex  LObjI = 0;const EIndex  LObjN = LModel->Objects.Count;E3dObject**  LObjects = LModel->Objects.Items;for(;LObjI < LObjN;LObjI++)
							{
								E3dObject*  LObject = LObjects[LObjI];

								if(EObject_IsSubClass(LObject, E3dSpline)) LSpline = (E3dSpline*)LObject;
							}
						}
					}
					else
					{
						E3dObjItem*  LObjItem = (E3dObjItem*)LItem;
						E3dObject*   LObject = LObjItem->Object;

						if(EObject_IsSubClass(LObject, E3dSpline))
						{
							LSpline = (E3dSpline*)LObject;
							LModel  = LObject->Models.Items[0];
//						LObject->Selection = E3dObjectSelOBJECT;
						}
					}

					if(LInfo && LSpline)
					{
//printf("%s() %s:%d  %p %p Picked %s/%s\n", __FUNCTION__, __FILE__, __LINE__, _TmpInfo, LScalingBySpline, LModel->Name, LSpline->Name);fflush(stdout);
						if(LSpline != LScalingBySpline->OrigSpline)
						{
							if(LScalingBySpline->OrigSpline) E3dBaseObject_RemoveOutput((E3dBaseObject*)LScalingBySpline->OrigSpline, &LInfo->InputInterface);
							E_Assign(LSpline, LScalingBySpline->OrigSpline);

							if(LScalingBySpline->OrigSpline) E3dBaseObject_AddOutput((E3dBaseObject*)LScalingBySpline->OrigSpline, &LInfo->InputInterface);
						}
						if(LModel != LScalingBySpline->Model) E_Assign(LModel, LScalingBySpline->Model);

						E3dp_PrintMessage(ELogMESSAGE, 3000, "Picked %s/%s", LModel->Name, LSpline->Name);
						EChangeFlags  LChanged = 0;

						if(_TmpPanel && !LScalingBySpline->Active)
						{
							XeComponentClassDrawer*  LDrawer = XeInfoPanel_GetFolderByClass((XeInfoPanel*)_TmpPanel, TmpComponentClass);
							E3dResourcesGUI*         LResourcesGUI = (E3dResourcesGUI*)(LDrawer->ResourcesGUI);

							LScalingBySpline->Active = TRUE;
							XeToggleButton_SetState(LResourcesGUI->ScaleBySplineWs[_TmpScalingBySplineIndex],  TRUE, FALSE);
						}
						LInfo->InputChangeCount++;
						TmpUpdateObject();
					}

					E3dp_PickEnd();

					E3dWindows_RedrawByChangeFlags(LScene, TmpCHANGEFLAGS);
				}
				_TmpInfo = NULL;
				_TmpPanel = NULL;
				_TmpScalingBySpline = NULL;
				_TmpScalingBySplineIndex = -1;
			}
		break;
	}
}



#define _PickSpline(pText) do\
{\
	_TmpInfo = LInfo;\
	_TmpPanel = LPanel;\
	const E3dpPrefs*  LPrefs = &E3dp_Prefs;\
	const uint32_t    LLabelRGBAp8Color = Xe_ForegroundRGBA8pColor;\
	E3dp_PickRequest(XeString_NewVa(TRUE,\
	 XeFONT, XeFontDEFAULT, XeCOLOR_RGBA, LLabelRGBAp8Color,  XeTEXT,  "Extrude along Spline    ",\
	 E3dp_LMouseButtonS,     XeTEXT, pText,\
	 E3dp_RMouseButtonEscS,  XeTEXT, ": cancel",\
	 0), E3dItemSPLINE|E3dItemMODEL,  _PickCB_ScaleBySpline, NULL,  0, FALSE);\
} while(0)


// Create GUI
//static inline void _ScaleUBySplineGUI(E3dInfo* PInfo, E3dResourcesGUI* PResourcesGUI, XeWidget PParentW)
#define _ScaleBySplineGUI(pCoordinate, pInfo, pPanel, pResourcesGUI, pParentW)\
{\
	EXeStart;\
	EXeSetArg(XeNShadowThickness, 0);\
	EXeSetArg(XeNHighlightThickness, 0);\
	EXeSetArg(XeNSet, pInfo->Scale##pCoordinate##BySpline.Active);\
	EXeSetArg(XeNResizableX, FALSE);EXeSetArg(XeNAlignmentX, XeAlignBEGINNING);\
	XeToolTip8(_Scale##pCoordinate##ToolTip);\
	pResourcesGUI->ScaleBySplineWs[E3dSCALESPL_##pCoordinate] = LW = XeWidget_ManagedNew("Scale "#pCoordinate" by Spline", XeToggleButton_class, pParentW, Args, ArgCnt);\
	XeAddCallback(LW, XeNValueChangedCallback, _DCB_Scale##pCoordinate##BySpline, (EPointer)pPanel);\
\
	EXeStart;\
	EXeSetArg(XeNMarginSizeX, 0);EXeSetArg(XeNSpacingLeft, 6);\
	EXeSetArg(XeNShadowThickness, 0);EXeSetArg(XeNLabelType, XeIMAGE);EXeSetArg(XeNImageSizeYPtr, &Xe_IconSize);EXeSetImages2(_Xe_Theme->Image_Find);\
	EXeSetArg(XeNResizableX, FALSE);EXeSetArg(XeNAlignmentX, XeAlignBEGINNING);\
	EXeSetArg(XeNResizableY, FALSE);\
	XeToolTip8("Select scaling Spline (so you can find it).");\
	pResourcesGUI->ScaleBySplineShowWs[E3dSCALESPL_##pCoordinate] = LW = XeWidget_ManagedNew("Show", XePushButton_class, pParentW, Args, ArgCnt);\
	XeAddCallback(LW, XeNActivateCallback, _DCB_Scale##pCoordinate##BySplineShow, (EPointer)pPanel);\
\
	EXeStart;\
	EXeSetArg(XeNMarginSizeX, 0);\
	EXeSetArg(XeNShadowThickness, 0);EXeSetArg(XeNLabelType, XeIMAGE);EXeSetArg(XeNImageSizeYPtr, &Xe_IconSize);EXeSetImages2(_Xe_Theme->Image_Replace);\
	EXeSetArg(XeNResizableX, FALSE);EXeSetArg(XeNAlignmentX, XeAlignBEGINNING);\
	EXeSetArg(XeNResizableX, FALSE);EXeSetArg(XeNAlignmentX, XeAlignBEGINNING);\
	EXeSetArg(XeNResizableY, FALSE);\
	XeToolTip8("Pick a new Spline to scale by.");\
	pResourcesGUI->ScaleBySplinePickWs[E3dSCALESPL_##pCoordinate] = LW = XeWidget_ManagedNew("Pick", XePushButton_class, pParentW, Args, ArgCnt);\
	XeAddCallback(LW, XeNActivateCallback, _DCB_Scale##pCoordinate##BySplinePick, (EPointer)pPanel);\
}
