/*
	Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/


/*====================================================================*\
FILE    : PTMechExCopy.c
PURPOSE : Test Pro/TOOLKIT functions for Mechanica 
\*====================================================================*/

/*--------------------------------------------------------------------*\
  Pro/Toolkit includes -- include this first
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProMdl.h>
#include <ProMechItem.h>
#include <ProMechConstraint.h>
#include <ProUtil.h>
#include <ProMessage.h>

#include <PTMechExamples.h>

static ProError status;
static ProCharLine msgbuf;
static ProFileName msgfile;

/*================================================================*\
  FUNCTION: PTMechExDispconstrPostfilter 
  PURPOSE:  Selection filter to ensure that only displacement constrs are selected
\*================================================================*/
static ProError PTMechExDispconstrPostfilter (ProSelection selection, ProAppData app_data)
{
	ProModelitem mech_item;
	ProMechConstrType constr_type;

	status = ProSelectionModelitemGet (selection, (ProModelitem*)&mech_item);
    PT_TEST_LOG_SUCC ("ProSelectionModelitemGet()");

	if (mech_item.type != PRO_SIMULATION_CONSTRAINT)
		return (PRO_TK_CONTINUE);

   status = ProMechconstrTypeGet (&mech_item, &constr_type);
      PT_TEST_LOG_SUCC ("ProMechconstrTypeGet()");
      
/*--------------------------------------------------------------------*\
  Check if the selection is of valid type 
\*--------------------------------------------------------------------*/
  
      if ((constr_type != PRO_MECH_CONSTR_DISPLACEMENT) || ( status != PRO_TK_NO_ERROR))
  		return (PRO_TK_CONTINUE);

	return (PRO_TK_NO_ERROR);
}
/*================================================================*\
  FUNCTION: PTMechExConstrCopy 
  PURPOSE:  Copies the displacement data from one ref to another 
\*================================================================*/

ProError PTMechExConstrCopy()
{
  ProSelFunctions sel_funcs;
  ProMechConstrType  constr_type;
  ProMechDisplacementType type;
  ProMechDisplacementConstr* trans_datas;
  ProMechDisplacementConstr* rot_datas;
  ProMechGeomref csys_data;
  int i,n_sels;
  ProSelection* sels;
  ProMechDisplacementData data; 
  ProLine buffer; 
  char line [PRO_LINE_SIZE];
  PTMechExGeomRef *array_refs;
  ProMechGeomrefType reftype;
  ProMechGeomrefSubType refsubtype;
  ProModelitem mech_item,model_item;
  ProMechItem tk_constraint_item;
  ProMechGeomref *array_geomrefs;
  ProMechStatus mech_status;
  ProCharLine constrset_name;
  ProMdl constraint_part;

  
  sel_funcs.pre_filter = NULL;
  sel_funcs.post_filter = PTMechExDispconstrPostfilter;
  sel_funcs.post_selact = NULL;
  sel_funcs.app_data = NULL;

  status = ProMdlCurrentGet(&constraint_part);
  PT_TEST_LOG_SUCC ("ProMdlCurrentGet");

/*--------------------------------------------------------------------*\
  Select the displacement constraint to get the data 
\*--------------------------------------------------------------------*/
  
  status = ProMessageDisplay(msgfile, "PTMechEx Select the displacement constraint");
  PT_TEST_LOG_SUCC("ProMessageDisplay()");
  
  while(1)
    {
      status =ProSelect ("sim_load",
			 1,
			 NULL, 
			 &sel_funcs,
			 NULL,
			 NULL,
			 &sels,
			 &n_sels);
      PT_TEST_LOG_SUCC ("ProSelect()");
      
      if( status != PRO_TK_NO_ERROR || n_sels <= 0 )
	break;
      
      status = ProSelectionModelitemGet (sels[0], &mech_item);
      PT_TEST_LOG_SUCC ("ProSelectionModelitemGet()");
      
      status = ProModelitemInit (mech_item.owner,
				 mech_item.id,
				 mech_item.type,
				 &mech_item);
      PT_TEST_LOG_SUCC ("ProModelitemInit()");
      
/*--------------------------------------------------------------------*\  
  Get displacement data from the mech item
\*--------------------------------------------------------------------*/

      status = ProMechconstrDisplacementdataGet (&mech_item, &data);
      PT_TEST_LOG_SUCC ("ProMechconstrDisplacementdataGet()");
      
      status = ProMechdisplacementdataTypeGet (data, &type);
      PT_TEST_LOG_SUCC ("ProMechdisplacementdataTypeGet()");

/*--------------------------------------------------------------------*\  
  Create new mech item
\*--------------------------------------------------------------------*/
      
      status = ProMechitemCreate ( (ProSolid) constraint_part,
				   PRO_SIMULATION_CONSTRAINT,
				   &tk_constraint_item);
      PT_TEST_LOG_SUCC ("ProMechitemCreate");
      
      status = ProMechitemNameSet ( &tk_constraint_item, L"tk_created_constr");
      PT_TEST_LOG_SUCC ("ProMechitemNameSet");

/*--------------------------------------------------------------------*\  
  Select the new references
\*--------------------------------------------------------------------*/
 
      status = ProMessageDisplay(msgfile, "PTMechEx Select references");
      PT_TEST_LOG_SUCC("ProMessageDisplay");

      status = ProSelect("surface,edge,curve,point",-1, NULL, NULL, NULL, NULL, &sels, &n_sels);
      PT_TEST_LOG_SUCC ("ProSelect()");

      if( status != PRO_TK_NO_ERROR || n_sels <= 0 )
	 break;
      
      status =ProArrayAlloc (n_sels,sizeof (PTMechExGeomRef),1, (ProArray *) &array_refs);
      PT_TEST_LOG_SUCC ("ProArrayAlloc");

/*--------------------------------------------------------------------*\  
  Poppulate the new references with type/subtype 
\*--------------------------------------------------------------------*/
      
      for ( i =0 ; i<n_sels; i++)
	{
	  ProSelectionModelitemGet(sels[i],&model_item);
	  
	  switch (model_item.type)
	    {
	    case PRO_EDGE :
	      reftype = PRO_MECH_EDGE;
	      refsubtype =PRO_MECH_CURVE_NORMAL; 
	      break;
	      
	    case PRO_CURVE :
	      reftype = PRO_MECH_CURVE;
	      refsubtype = PRO_MECH_CURVE_NORMAL;
	      break;
	      
	    case PRO_POINT :
	      reftype = PRO_MECH_POINT;
	      refsubtype =PRO_MECH_POINT_SINGLE;
	      break;
	      
	    case PRO_SURFACE :
	      reftype = PRO_MECH_SURFACE;
	      refsubtype = PRO_MECH_SURFACE_NORMAL;
	      break;
	    }	
	  
	  array_refs[i].type = reftype;
	  array_refs[i].subtype = refsubtype;
	  array_refs[i].id = model_item.id;
	  array_refs[i].path = NULL;
        } 
/*--------------------------------------------------------------------*\  
  Create array of the geom refs from the array of refs
\*--------------------------------------------------------------------*/
      
      status = PTMechExGeomReferenceArrayCreate ( n_sels, array_refs, &array_geomrefs);
      PT_TEST_LOG_SUCC ("PTMechExGeomReferenceArrayCreate"); 

/*--------------------------------------------------------------------*\  
  Set the array of geom ref to the newly created constraint
\*--------------------------------------------------------------------*/

      status = ProMechconstrReferencesSet (&tk_constraint_item,array_geomrefs);
      PT_TEST_LOG_SUCC ("ProMechconstrReferencesGet()");
      
/*--------------------------------------------------------------------*\  
  Set the displacement data to the newly created constraint
\*--------------------------------------------------------------------*/
      
      status = ProMechconstrDisplacementdataSet (&tk_constraint_item,data);
      PT_TEST_LOG_SUCC ("ProMechconstrDisplacementdataSet");
      
/*--------------------------------------------------------------------*\  
  Get the name of the constraint set from where the displacement conatrsint selected
\*--------------------------------------------------------------------*/

      status = PTMechExConstraintsetNameGet(&mech_item,constrset_name); 
      PT_TEST_LOG_SUCC ("PTMechExConstraintsetNameGet");

/*--------------------------------------------------------------------*\  
  Add the newly  created constraint in to the constrait set
\*--------------------------------------------------------------------*/
      
      status = PTMechExConstraintAddinConstraintset (constraint_part,constrset_name, 
						   &tk_constraint_item);
      PT_TEST_LOG_SUCC ("PTMechExConstraintAddinConstraintset");
      
      status = ProMechitemStatusGet (&tk_constraint_item, &mech_status);
      PT_TEST_LOG_SUCC ("ProMechitemStatusGet");

/*--------------------------------------------------------------------*\
  Print Message from the result 
\*--------------------------------------------------------------------*/
      
      if (mech_status == PRO_MECH_ACTIVE)
	{
	  status = ProMessageDisplay(msgfile, "PTMechEx New displacement constraint created successfuly");
	  PT_TEST_LOG_SUCC("ProMessageDisplay()");
	}
      else
	{
	  status = ProMessageDisplay(msgfile, "PTMechEx New displacement constraint creation failed", msgbuf);
	  PT_TEST_LOG_SUCC("ProMessageDisplay()");
	} 
      
      status = ProMechitemUpdateComplete (&tk_constraint_item);
      PT_TEST_LOG_SUCC ("ProMechitemUpdateComplete");

    }

   return PRO_TK_NO_ERROR;
}