//================================================================
// 3DPanel header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2025-Mar-12 17:35:25
//
// Copyright (C) 1996-2026 By Gabor Nagy. All rights reserved.
//================================================================
#ifndef _E3D_InputPick_h
#define _E3D_InputPick_h

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif

//================================================================
// Pick new input Geometry
//================================================================
static void E3dPickCB_Input(E3dPickCallbackStruct* PPickStruct, EPointer PClientData,  const EIndex PNumOfItems, E3dItem* PPickedItems)
{
	XeApp_Sync(Xe_App);

	_E3dTmp*  LTmp = &_Tmp;

	if(PPickStruct->Reason == E3dCR_ABORT)
	{
		E_DeleteChk(LTmp->Models[0]);
		E_DeleteChk(LTmp->Geometries[0]);
		LTmp->Operation = 0;
		LTmp->InputID = 0;
		return;
	}

// Cancel
//
	if(PPickStruct->Button == Button3)
	{
		E3dp_PickEnd();
		E_DeleteChk(LTmp->Models[0]);
		E_DeleteChk(LTmp->Geometries[0]);
		LTmp->Operation = 0;
		LTmp->InputID = 0;
		return;
	}

	E3dScene*  LScene = E3d_Scene;

	E3dObject*  LDstObject = E_DynamicCast(PClientData, E3dObject);

	switch(PPickStruct->Button)
	{
		case Button1:
//printf("%s() %s:%d  %sPNumOfItems%s %lld\n", __FUNCTION__, __FILE__, __LINE__, ECodeGreen, ECodeNormal, (long long)PNumOfItems);fflush(stdout);
			if(PNumOfItems > 0)
			{
				E3dItem*  LItem = PPickedItems;

{ char  s[512];printf("%s() %s:%d [%s]\n", __FUNCTION__, __FILE__, __LINE__, E3d_ItemFlagsToString(LItem->Item.Type, s));fflush(stdout); }
				if(LItem->Item.Type == E3dItemMESH || LItem->Item.Type == E3dItemMODEL)
				{
					EChangeFlags  LChanged = 0;
					E3dInfo*      LInfo = (E3dInfo*)E3dObjectComponent_ByClass(LDstObject, _ObjectComponent_class, FALSE);

					const char*   LInputName = NULL;

					E3dModel*   LInputModel = NULL;
					E3dObject*  LInputObject = NULL;

					switch(LItem->Item.Type)
					{
						case E3dItemMODEL:
							{
								E3dObjItem*  LObjItem = (E3dObjItem*)LItem;

								LInputModel = (E3dModel*)LObjItem->Node;if(LInputModel)
								{
									E3dObject**  LObjects = LInputModel->Objects.Items;

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

										if(EObject_IsSubClass(LObject, E3dMesh)) { LInputObject = LObject;break; }
									}

									if(LInputObject)
									{
										if(LInputObject != LDstObject)
										{
											if(LInfo)
											{
												const EIndex  LInputID = LTmp->InputID;if(LInputID >= 0)
												{
													if((E3dGeometry*)LInputObject != LInfo->Geometries[LInputID])
													{
														if(LInfo->Geometries[LInputID]) E3dBaseObject_RemoveOutput((E3dBaseObject*)LInfo->Geometries[LInputID], &LInfo->InputInterface);
														E_AssignToMember(LInputObject, LInfo,Geometries[LInputID]);
														E3dBaseObject_AddOutput((E3dBaseObject*)LInputObject, &LInfo->InputInterface);
													}
													if(LInputModel != LInfo->Models[LInputID])
													{
														if(LInfo->Models[LInputID]) E3dBaseObject_RemoveOutput((E3dBaseObject*)LInfo->Models[LInputID], &LInfo->InputInterface);
														E_AssignToMember(LInputModel,  LInfo,Models[LInputID]);
														E3dBaseObject_AddOutput((E3dBaseObject*)LInputModel, &LInfo->InputInterface);
													}
												}
											}
											E3dSel_ObjectSelect(LScene, LInputObject, TRUE, FALSE);
										}
										else
										{
											E3dp_PrintMessage(ELogMESSAGE, 3000, E3dLng_Input_as_output, LInputObject->Name);
											return;
										}
									}
								}
							}
						break;

						default:
							{
								E3dObjItem*  LObjItem = (E3dObjItem*)LItem;
								LInputObject = LObjItem->Object;
								E3dWindow*  L3DWindow = PPickStruct->E3DWindow;

								if(EObject_IsSubClass(LInputObject, E3dMesh))
								{
									if(LDstObject)
									{
										if(EObject_IsSubClass(LDstObject, E3dMesh))
										{
											if(LInputObject != LDstObject)
											{
												E3dModel*  LTInputModel = E3dObject_GetVisibleModel(LInputObject);

// On the Schematics view, it's possible to pick non-visible and non-selected Objects, so if LTInputModel is NULL, just pick the first Model of LInputObject
//
												const E3dViewClass*  LViewClass = L3DWindow->ViewMode->Class;
												if(LTInputModel == NULL && LViewClass == E3dSchematicsView_class)
												{
													LTInputModel = LInputObject->Models.Items[0];
												}

//printf("%s() %s:%d  [%p:%s]/<%s>\n", __FUNCTION__, __FILE__, __LINE__, LTInputModel, LTInputModel ? LTInputModel->Name : "", LInputObject->Name);fflush(stdout);

												const EIndex  LInputID = LTmp->InputID;if(LInputID >= 0)
												{
													if((E3dGeometry*)LInputObject != LInfo->Geometries[LInputID])
													{
														if(LInfo->Geometries[LInputID]) E3dBaseObject_RemoveOutput((E3dBaseObject*)LInfo->Geometries[LInputID], &LInfo->InputInterface);
														E_AssignToMember(LInputObject, LInfo,Geometries[LInputID]);
														E3dBaseObject_AddOutput((E3dBaseObject*)LInputObject, &LInfo->InputInterface);
													}
													if(LTInputModel != LInfo->Models[LInputID])
													{
														if(LInfo->Models[LInputID]) E3dBaseObject_RemoveOutput((E3dBaseObject*)LInfo->Models[LInputID], &LInfo->InputInterface);
														E_AssignToMember(LTInputModel, LInfo,Models[LInputID]);
														E3dBaseObject_AddOutput((E3dBaseObject*)LTInputModel, &LInfo->InputInterface);
													}
												}

												E3dSel_ObjectSelect(LScene, LInputObject, TRUE, FALSE);
											}
											else
											{
												E3dp_PrintMessage(ELogMESSAGE, 3000, E3dLng_Input_as_output, LInputObject->Name);
												return;
											}
										}
									}
									else
									{
										E3dSel_ObjectSelect(LScene, LInputObject, TRUE, FALSE);
									}
								}
							}
						break;
					}


					if(LInputObject)
					{
// End picking before E3dp_PrintMessage() etc.
//
						E3dp_PickEnd();

						if(LDstObject)
						{
							const E3dpPrefs*  LPrefs = &E3dp_Prefs;

							E3dBaseObject_AddOutput((E3dBaseObject*)LInputObject, &LInfo->InputInterface);

							switch(LTmp->InputID)
							{
								case 0:  LInputName = "-A";break;
								case 1:  LInputName = "-B";break;
								case 2:  LInputName = "-C";break;
							}

							if(LInputModel) E3dp_PrintMessage(ELogMESSAGE, 3000, "%s: Picked Model '%s' for input%s", _ToolName, LInputModel->Name, LInputName);
							else
							{
								if(EObject_IsSubClass(LInputObject, E3dMesh))
								{
//									E3dp_PrintMessage(ELogMESSAGE, 3000, "%s: Picked Mesh '%s' for input%s", _ToolName, LInputObject->Name, LInputName);
//printf("%s() %s:%d  [%p:%s]/<%s>\n", __FUNCTION__, __FILE__, __LINE__, LInputModel, LInputModel ? LInputModel->Name : "", LInputObject->Name);fflush(stdout);
									E3dp_PrintCompoundMessageVa(ELogMESSAGE, 5000,  XeFONT, XeFontDEFAULT,  XeTEXT, _ToolName,  XeTEXT, ": Picked Mesh ",  E3dp_ObjectS(LInputObject->Name ? LInputObject->Name : ""),  XeTEXT, " for input",  XeTEXT, LInputName,  0);
								}
							}

							LInfo->InputChangeCount++;
							if(EObject_IsSubClass(LDstObject, E3dSpline))
							{
								E3dObject_CustomUpdate(LDstObject, LInfo,  0,  &LChanged);
								E3dSpline*  LSpline = (E3dSpline*)LDstObject;
								LChanged |= E3dSpline_CallOutputs(LSpline, E3dChgSplineSHAPE|E3dChgSplineCONNECTIVITY, FALSE);
							}
							else E3dObject_CustomUpdate(LDstObject, LInfo,  E3dCallOUTPUTS,  &LChanged);
						}
						else
						{
// We just picked the second Geometry and there is no result Geometry yet, so create it here.
//
							if(LTmp->Models[0] && LTmp->Geometries[0])
							{
								if(LInputModel == NULL) LInputModel = E3dObject_GetSelectingModel(LInputObject, FALSE);

								_Create(LTmp->Models[0], LTmp->Geometries[0],  (E3dGeometry*)LInputObject, LInputModel,  LTmp);
							}
						}

						E3dWindows_RedrawByChangeFlags(LScene, LChanged);

						E_DeleteChk(LTmp->Models[0]);
						E_DeleteChk(LTmp->Geometries[0]);
						EClr_p(LTmp);

						E3dObjectPanel_Update(NULL, LDstObject,  NULL, NULL);
					}
				}
			}
		break;
	}
}

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration
#endif

#endif	// _E3D_InputPick_h
