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

#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProParameter.h>
#include <ProSelbuffer.h>
#include <ProFeature.h>
#include <ProAnnotationFeat.h>
#include <ProAnnotationElem.h>

#include <PTAFExamples.h>

static int AE_Feat_Type = -1;
static double AE_Param_Value = -1;
static ProBoolean is_AE_Layer_Created = PRO_B_FALSE;

/*====================================================================*\
    FUNCTION :	 PTAFExTestforSelectionsInBuffer()
    PURPOSE  :   Test for number of selections in the buffer	
\*====================================================================*/
ProError PTAFExTestforSelectionsInBuffer ()
{
  ProSelection *sel_array=NULL;
  int sel_size;
  
/*---------------------------------------------------------------------*\
Get the ProSelections from the Selection buffer
\*---------------------------------------------------------------------*/
  status = ProSelbufferSelectionsGet(&sel_array);
  
  PT_TEST_LOG_SUCC(" ProSelbufferSelectionsGet ");

/*---------------------------------------------------------------------*\
If no items in the Selection buffer
\*---------------------------------------------------------------------*/
  if (status == PRO_TK_E_NOT_FOUND) {
    return status;
  }

/*---------------------------------------------------------------------*\
If the Array of ProSelections contains more than one ProSelection, then that is not valid
\*---------------------------------------------------------------------*/
  status = ProArraySizeGet((ProArray) sel_array, &sel_size);
	
/*---------------------------------------------------------------------*\
If more than 1 item in the selection buffer
\*---------------------------------------------------------------------*/
  if (sel_size != 1) return PRO_TK_GENERAL_ERROR;
  
  ProSelectionarrayFree(sel_array); 
  
  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
    FUNCTION :	 PTAFExAEParameterFilterAction()
    PURPOSE  :   Filter function for visit to check for "FTYPE" parameter
\*====================================================================*/
ProError PTAFExAEParameterFilterAction(ProParameter *param, ProAppData dummy)
{
  ProCharName param_name;
  
/*---------------------------------------------------------------------*\
Get the name of the parameter
\*---------------------------------------------------------------------*/
  ProWstringToString(param_name, param->id);
  
  if (strcmp("FTYPE", param_name) == 0) return PRO_TK_NO_ERROR;
  else return PRO_TK_CONTINUE;
}
	

/*====================================================================*\
    FUNCTION :	 PTAFExAEParameterValueFilterAction()
    PURPOSE  :   Filter function for visit to check for "VALUE" parameter
\*====================================================================*/
ProError PTAFExAEParameterValueFilterAction(ProParameter *param, ProAppData dummy)
{
  ProCharName param_name;
  
/*---------------------------------------------------------------------*\
Get the name of the parameter
\*---------------------------------------------------------------------*/
  ProWstringToString(param_name, param->id);
  
  if (strcmp("VALUE", param_name) == 0) return PRO_TK_NO_ERROR;
  else return PRO_TK_CONTINUE;
}
	
/*====================================================================*\
    FUNCTION :	 PTAFExAEParameterVisitAction()
    PURPOSE  :   Visit function for "FTYPE" parameter	
\*====================================================================*/
ProError PTAFExAEParameterVisitAction (ProParameter *param, 
				       ProError err, 
				       ProAppData dummy)
{
  ProCharLine str_param_val;
  ProParamvalue param_val;
  ProParamvalueType param_type;
  ProCharName param_name;
  ProLine w_str_param_val;
  ProUnititem units;

/*---------------------------------------------------------------------*\
Get the name of the parameter
\*---------------------------------------------------------------------*/
  ProWstringToString(param_name, param->id);
  
  
  if (strcmp("FTYPE", param_name) != 0) return PRO_TK_NO_ERROR;
  
/*---------------------------------------------------------------------*\
Get the value of the parameter
\*---------------------------------------------------------------------*/
  status = ProParameterValueWithUnitsGet(param, &param_val, &units);
  PT_TEST_LOG_SUCC("PTAFExAEParameterVisitAction::ProParameterValueWithUnitsGet");

/*---------------------------------------------------------------------*\
Get the type of the ParameterValue
\*---------------------------------------------------------------------*/
  status = ProParamvalueTypeGet(&param_val, &param_type);
  PT_TEST_LOG_SUCC("PTAFExAEParameterVisitAction::ProParamvalueTypeGet");

/*---------------------------------------------------------------------*\
Get the value of the ParameterValue
\*---------------------------------------------------------------------*/
  status = ProParamvalueValueGet(&param_val, param_type, w_str_param_val);
  PT_TEST_LOG_SUCC("PTAFExAEParameterVisitAction::ProParamvalueValueGet");
  
  ProWstringToString(str_param_val, w_str_param_val);

/*---------------------------------------------------------------------*\
Compare the parametervalue 
\*---------------------------------------------------------------------*/
  if (strcmp(str_param_val, "round") == 0) {
    AE_Feat_Type = PTAFEX_PRO_FEAT_ROUND;
    return PRO_TK_CONTINUE;
  }
  
  else if (strcmp(str_param_val, "chamfer") == 0) {
    
    AE_Feat_Type = PTAFEX_PRO_FEAT_CHAMFER;
    return PRO_TK_CONTINUE;
  }
  
  else if (strcmp(str_param_val, "draft") == 0) {
    
    AE_Feat_Type = PTAFEX_PRO_FEAT_DRAFT;
    return PRO_TK_CONTINUE;
  }
  
  AE_Feat_Type = PTAFEX_PRO_FEAT_NONE;
  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
  FUNCTION :	 PTAFExAEParameterValueVisitAction()
  PURPOSE  :   Visit function for "VALUE" parameter	
\*====================================================================*/
ProError PTAFExAEParameterValueVisitAction (ProParameter *param, 
					    ProError status, 
					    ProAppData dummy)
{
  double value=-1;
  ProParamvalue param_val;
  ProError err;
  ProParamvalueType param_type;
  ProCharName param_name;
  ProUnititem units;
	
/*---------------------------------------------------------------------*\
Get the name of the parameter
\*---------------------------------------------------------------------*/
  ProWstringToString(param_name, param->id);
  if (strcmp("VALUE", param_name) != 0) return PRO_TK_NO_ERROR;
  
/*---------------------------------------------------------------------*\
Get the value of the parameter
\*---------------------------------------------------------------------*/
 ProParameterValueWithUnitsGet(param, &param_val, &units);
  
/*---------------------------------------------------------------------*\
Get the type of the ParameterValue
\*---------------------------------------------------------------------*/
  ProParamvalueTypeGet(&param_val, &param_type);

/*---------------------------------------------------------------------*\
Get the value of the ParameterValue
\*---------------------------------------------------------------------*/
  err = ProParamvalueValueGet(&param_val, param_type, &value);
  
  AE_Param_Value = value;
  
  return PRO_TK_NO_ERROR;
}


/*====================================================================*\
  FUNCTION :	 PTAFExGetAEFromSelectionbuffer()
  PURPOSE  :   Get the Annotation Element from the Selection buffer	
\*====================================================================*/
ProError PTAFExGetAEFromSelectionbuffer(ProAnnotationElem *annot_elem)
{
  ProError err;
  ProSelection *sel_array=NULL;
  int sel_size;
  ProType annot_elem_type = PRO_ANNOTATION_ELEM;

/*---------------------------------------------------------------------*\
Get the ProSelections from the Selection buffer
\*---------------------------------------------------------------------*/
  err = ProSelbufferSelectionsGet(&sel_array);
  
  if (err == PRO_TK_E_NOT_FOUND) return PRO_TK_E_NOT_FOUND;

/*---------------------------------------------------------------------*\
If the Array of ProSelections contains more than one ProSelection, then that is not valid
\*---------------------------------------------------------------------*/
  err = ProArraySizeGet((ProArray*) sel_array, &sel_size);
  
  if (sel_size != 1) {
/*---------------------------------------------------------------------*\
Too many objects in the selection buffer	
\*---------------------------------------------------------------------*/
    return PRO_TK_GENERAL_ERROR;
  }

/*---------------------------------------------------------------------*\
Get the ProModelItem from the ProSelection
\*---------------------------------------------------------------------*/
  err = ProSelectionModelitemGet(sel_array[0], annot_elem);
  
  if (annot_elem->type != annot_elem_type) {

/*---------------------------------------------------------------------*\
The object in the buffer is not suitable for this operation, since it is not an AE
\*---------------------------------------------------------------------*/
    return PRO_TK_GENERAL_ERROR;  
  }

  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
  FUNCTION :	 PTAFExGetFeatureValue()
  PURPOSE  :   Get the value from the parameter "VALUE" in the
				 Annotation Element	
\*====================================================================*/
ProError PTAFExGetFeatureValue(ProAnnotationElem *annot_elem, double *value)
{
  ProError err;
  int dummy=0;

/*---------------------------------------------------------------------*\
Visit all the parameters in the annotation element
Looking for the value
\*---------------------------------------------------------------------*/
  err = ProParameterVisit(annot_elem, NULL, (ProParameterAction)PTAFExAEParameterValueVisitAction, (ProAppData)dummy);	
  *value = AE_Param_Value;
  
  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
  FUNCTION : PTAFExGetFeatureType()
  PURPOSE : Get the value from the parameter "FTYPE" in the Annotation Element	
\*====================================================================*/
ProError PTAFExGetFeatureType(ProAnnotationElem *annot_elem, int *feat_type)
{
  int dummy=0;
  
/*---------------------------------------------------------------------*\
Visit all the parameters in the annotation element
\*---------------------------------------------------------------------*/
  status = ProParameterVisit(annot_elem, NULL, (ProParameterAction)PTAFExAEParameterVisitAction, (ProAppData)dummy);
  PT_TEST_LOG_SUCC("PTAFExGetFeatureType::ProParameterVisit");
  *feat_type = AE_Feat_Type;
  
  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
  FUNCTION :   PTContourAction()
  PURPOSE  :   Callback to visiting surface contours
\*====================================================================*/
static ProError PTContourAction (ProContour  p_contour,
                             ProError    status,
			  ProAppData  app_data)
{
  return PRO_TK_NO_ERROR;
}


/*====================================================================*\
  FUNCTION : PTAFSurfaceIsDatum()
  PURPOSE : Determine if a surface is a datum surface or not.
\*====================================================================*/
ProBoolean PTAFSurfaceIsDatum(ProGeomitem* item)
{
  ProSurface surf;
  
  ProGeomitemToSurface (item, &surf);
  status = ProSurfaceContourVisit (surf, PTContourAction,
				   PRO_NO_FUNCTION, NULL);
  
  if (status == PRO_TK_E_NOT_FOUND)
    return PRO_B_TRUE;
  else
    return PRO_B_FALSE;
}



/*====================================================================*\
  FUNCTION : PTTestFeatureCreate_low()
  PURPOSE : Create a feature using a given element tree	
\*====================================================================*/
ProError PTTestFeatureCreate_low ( ProMdl model , ProElement elemtree  )
{

  ProModelitem model_item; 
  ProSelection model_selection;
  ProFeatureCreateOptions complete_options[] 
    = { PRO_FEAT_CR_DEFINE_MISS_ELEMS }; 
  ProFeature created_feature; 
  ProErrorlist p_errors; 

  status = ProMdlToModelitem ( model, &model_item ); 
  PT_TEST_LOG_SUCC (" ProMdlToModelitem"); 

  status = ProSelectionAlloc ( NULL, &model_item, &model_selection ); 
  PT_TEST_LOG_SUCC (" ProSelectionAlloc"); 

  status = ProFeatureCreate ( model_selection, elemtree, 
				  complete_options, 1,
				  &created_feature, &p_errors ); 
  PT_TEST_LOG_SUCC (" ProFeatureCreate"); 
 
  return status; 
}