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



/*---------------------- Pro/Toolkit Includes ------------------------*/
#include <ProToolkit.h>
#include <ProFeature.h>
#include <ProElemId.h>
#include <ProExtrude.h>
#include <ProModFeat.h>
#include <ProStdSection.h>
#include <ProElement.h>
#include <ProElempath.h>
#include <ProFeatType.h>
#include <ProFeatForm.h>
#include <ProSelection.h>
#include <ProSection.h>
#include <TestError.h>
#include <ProMessage.h>
#include <ProTKRunTime.h>
#include <ProUtil.h>
#include <ProDtmCrv.h>

#define C_LOG(a) ProTKPrintf ("Status for %s is = %d\n", a, status); \
                 ERROR_CHECK(a, "UgSktExtrusionCreate.c", status);

#define C_PRINT(a) ProTKPrintf ("%s\n", a);

static ProFileName message_file; 

/*---------------------- Function Prototypes -------------------------*/
ProError UserSectionPointBuild(ProSection, ProSelection *);

/*------------------------- Global Data -----------------------------*/

/*===============================================================*\
FUNCTION : ProDemoSketchedPointCreate
PURPOSE  : Demonstrates the creation of a Point in a Sketched feature.
\*===============================================================*/
ProError ProDemoSketchedPointCreate(void)
{
  ProReference REPDEP_ref2;
  ProReference REPDEP_ref1;
  ProErrorlist            errors;
  ProMdl                  model;
  ProModelitem            model_item;
  ProSelection            model_sel;
  ProFeature              feature;
  ProFeatureCreateOptions *opts = 0;
  ProElempath             path;
  ProElempathItem         path_items[2];
  ProAsmcomppath          comp_path;
  ProAsmcomppath         *p_comp_path = (ProAsmcomppath *)NULL;
  ProValue                value;
  ProSection              section;

  ProElement sketch_element; 
  ProElement created_elemtree; 
  
  ProElement pro_e_feature_tree;
  ProElement pro_e_feature_type;
  ProElement pro_e_curve_type;
  ProElement pro_e_std_feature_name;
  ProElement pro_e_std_section;
  ProElement pro_e_std_sec_setup_plane;
  ProElement pro_e_std_sec_plane;
  ProElement pro_e_std_sec_plane_view_dir;
  ProElement pro_e_std_sec_plane_orient_dir;
  ProElement pro_e_std_sec_plane_orient_ref;
  
  ProSelection *sketch_refs;

  ProName        wide_string;
  ProError       status;
  ProValueData   value_data;
  ProSelection  *p_select;
  int            n_select;

  ProStringToWstring (message_file, "utilities.txt"); 

  /*---------------------------------------------------------------*\
    Populating root element PRO_E_FEATURE_TREE 
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_FEATURE_TREE *** ");
  status = ProElementAlloc (PRO_E_FEATURE_TREE, &pro_e_feature_tree); 
  C_LOG (" ProElementAlloc ");

  /*---------------------------------------------------------------*\
    Populating element PRO_E_FEATURE_TYPE 
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_FEATURE_TYPE *** ");
  status = ProElementAlloc (PRO_E_FEATURE_TYPE, &pro_e_feature_type);
  C_LOG(" ProElementAlloc ");
  status = ProElementIntegerSet(pro_e_feature_type,PRO_FEAT_CURVE);
  C_LOG (" ProElementIntegerSet");
  status = ProElemtreeElementAdd (pro_e_feature_tree, NULL, pro_e_feature_type);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating element PRO_E_CURVE_TYPE
  \*---------------------------------------------------------------*/

  C_PRINT (" *** Processing Element PRO_E_CURVE_TYPE *** ");
  status = ProElementAlloc (PRO_E_CURVE_TYPE, &pro_e_curve_type);
  C_LOG (" ProElementAlloc ");
  status = ProElementIntegerSet(pro_e_curve_type,PRO_CURVE_TYPE_SKETCHED);
  C_LOG (" ProElementIntegerSet");
  status = ProElemtreeElementAdd (pro_e_feature_tree, NULL, pro_e_curve_type);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating optional element PRO_E_STD_FEATURE_NAME
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_FEATURE_NAME *** ");
  status = ProElementAlloc (PRO_E_STD_FEATURE_NAME, &pro_e_std_feature_name); 
  C_LOG (" ProElementAlloc ");
  ProStringToWstring (wide_string, "MY_PNT1");
  status = ProElementWstringSet(pro_e_std_feature_name,wide_string);
  C_LOG (" ProElementWstringSet");
  status = ProElemtreeElementAdd (pro_e_feature_tree, NULL, pro_e_std_feature_name);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating compound element PRO_E_STD_SECTION
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_SECTION *** ");
  status = ProElementAlloc (PRO_E_STD_SECTION, &pro_e_std_section);
  C_LOG (" ProElementAlloc");
  status = ProElemtreeElementAdd (pro_e_feature_tree, NULL, pro_e_std_section);
  C_LOG (" ProElemtreeElementAdd");

  sketch_refs = (ProSelection *)calloc (2, sizeof (ProSelection));

  /*---------------------------------------------------------------*\
    Populating element PRO_E_STD_SECTION 
			-> PRO_E_STD_SEC_SETUP_PLANE
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_SEC_SETUP_PLANE *** ");
  status = ProElementAlloc (PRO_E_STD_SEC_SETUP_PLANE, &pro_e_std_sec_setup_plane);
  C_LOG (" ProElementAlloc");
  status = ProElemtreeElementAdd (pro_e_std_section, NULL, pro_e_std_sec_setup_plane);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating element PRO_E_STD_SECTION 
			-> PRO_E_STD_SEC_SETUP_PLANE
			   -> PRO_E_STD_SEC_PLANE
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_SEC_PLANE *** ");
  status = ProMessageDisplay (message_file, "Select Surface for sketch placement");
  C_LOG (" ProMessageDisplay");
  ProTKPrintf ("Please select datum,surface,sldface,qltface_ID_5 type of Modelitem\n");
  status = ProSelect ("datum,surface,sldface,qltface", 1, NULL, NULL, 
                      NULL, NULL, &p_select, &n_select);
  C_LOG (" ProSelect");
  if ( n_select <= 0 )
    return -1; 
  else
  {
    status = ProSelectionCopy (p_select[0], &sketch_refs[0]);
    C_LOG (" ProSelectionCopy ");
  }
  status = ProElementAlloc (PRO_E_STD_SEC_PLANE, &pro_e_std_sec_plane);
  C_LOG (" ProElementAlloc ");
  status = ProSelectionToReference( p_select[0],&REPDEP_ref1 );
  status = ProElementReferenceSet(pro_e_std_sec_plane,REPDEP_ref1);
  C_LOG (" ProElementReferenceSet");
  status = ProElemtreeElementAdd (pro_e_std_sec_setup_plane, NULL, 
                                  pro_e_std_sec_plane);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating element PRO_E_STD_SECTION 
			-> PRO_E_STD_SEC_SETUP_PLANE
			   -> PRO_E_STD_SEC_PLANE_VIEW_DIR
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_SEC_PLANE_VIEW_DIR *** ");
  status = ProElementAlloc (PRO_E_STD_SEC_PLANE_VIEW_DIR, 
                            &pro_e_std_sec_plane_view_dir );
  C_LOG (" ProElementAlloc ");
  status = ProElementIntegerSet(pro_e_std_sec_plane_view_dir,PRO_SEC_VIEW_DIR_SIDE_ONE);
  C_LOG (" ProElementIntegerSet");
  status = ProElemtreeElementAdd (pro_e_std_sec_setup_plane, NULL, 
                                  pro_e_std_sec_plane_view_dir);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating element PRO_E_STD_SECTION 
			-> PRO_E_STD_SEC_SETUP_PLANE
			   -> PRO_E_STD_SEC_PLANE_ORIENT_DIR
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_SEC_PLANE_ORIENT_DIR *** ");
  status = ProElementAlloc (PRO_E_STD_SEC_PLANE_ORIENT_DIR, 
                            &pro_e_std_sec_plane_orient_dir);
  C_LOG (" ProElementAlloc ");
  status = ProElementIntegerSet(pro_e_std_sec_plane_orient_dir,PRO_SEC_ORIENT_DIR_UP);
  C_LOG (" ProElementIntegerSet");
  status = ProElemtreeElementAdd (pro_e_std_sec_setup_plane, NULL, 
                                  pro_e_std_sec_plane_orient_dir);
  C_LOG (" ProElemtreeElementAdd");

  /*---------------------------------------------------------------*\
    Populating element PRO_E_STD_SECTION 
			-> PRO_E_STD_SEC_SETUP_PLANE
			   -> PRO_E_STD_SEC_PLANE_ORIENT_REF
  \*---------------------------------------------------------------*/
  C_PRINT (" *** Processing Element PRO_E_STD_SEC_PLANE_ORIENT_REF *** ");
  status = ProMessageDisplay (message_file, "Select Surface for sketch orientation");
  C_LOG (" ProMessageDisplay");
  ProTKPrintf ("Please select datum,surface,sldface,qltface_ID_5 type of Modelitem\n");
  status = ProSelect ("datum,surface,sldface,qltface", 1, NULL, 
                      NULL, NULL, NULL, &p_select, &n_select);
  C_LOG (" ProSelect");
  if (n_select <= 0)
    return -1; 
  else
  {
    status = ProSelectionCopy(p_select[0], &sketch_refs[1]);
    C_LOG (" ProSelectionCopy ");
  }

  status = ProElementAlloc (PRO_E_STD_SEC_PLANE_ORIENT_REF, 
                            &pro_e_std_sec_plane_orient_ref);
  C_LOG (" ProElementAlloc ");
  status = ProSelectionToReference( p_select[0],&REPDEP_ref2 );
  status = ProElementReferenceSet(pro_e_std_sec_plane_orient_ref,REPDEP_ref2);
  C_LOG (" ProElementReferenceSet");
  status = ProElemtreeElementAdd (pro_e_std_sec_setup_plane, NULL, 
                                  pro_e_std_sec_plane_orient_ref);
  C_LOG (" ProElemtreeElementAdd" );

  /*---------------------------------------------------------------*\
    Creating incomplete feature in the current model.
  \*---------------------------------------------------------------*/
  status = ProMdlCurrentGet (&model);
  if ( status != PRO_TK_NO_ERROR )
    return ( status );
  status = ProMdlToModelitem (model, &model_item); 
  status = ProSelectionAlloc (p_comp_path, &model_item,
                              &model_sel);
  

  status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions),
    1, (ProArray*)&opts);

  opts[0]= PRO_FEAT_CR_INCOMPLETE_FEAT;

  status = ProFeatureWithoptionsCreate (model_sel, pro_e_feature_tree,
    opts, PRO_REGEN_NO_FLAGS, &feature, &errors);
  C_LOG (" ProFeatureWithoptionsCreate"); 

  status = ProArrayFree((ProArray*)&opts);
  
  /* Using the element tree from created feature */ 
  status = ProFeatureElemtreeExtract (&feature, NULL, PRO_FEAT_EXTRACT_NO_OPTS,
                                      &created_elemtree);
  C_LOG ("ProFeatureElemtreeExtract()");

  /*---------------------------------------------------------------*\
    Getting the initialized section element from the database.
  \*---------------------------------------------------------------*/
  /* path to PRO_E_SKETCHER element */ 
  path_items[0].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
  path_items[0].path_item.elem_id = PRO_E_STD_SECTION;
  path_items[1].type = PRO_ELEM_PATH_ITEM_TYPE_ID;
  path_items[1].path_item.elem_id = PRO_E_SKETCHER;
  status = ProElempathAlloc (&path);
  status = ProElempathDataSet (path, path_items, 2);

  status = ProElemtreeElementGet ( created_elemtree, path, &sketch_element);
  C_LOG (" ProElemtreeElementGet PRO_E_SKETCHER "); 


  status = ProElementSpecialvalueGet(sketch_element, NULL, (ProAppData *) &section);
  C_LOG(" ProElementSpecialvalueGet");
/*---------------------------------------------------------------*\
    Create the 3-D Point section and get the section handle 
\*---------------------------------------------------------------*/

  status = UserSectionPointBuild ((ProSection)section, sketch_refs); 
  C_LOG (" UserSectionPointBuild"); 

/*---------------------------------------------------------------*\
   Redefining the feature to make it complete.
\*---------------------------------------------------------------*/

  status = ProSelectionAsmcomppathGet (model_sel, &comp_path);
  C_LOG (" ProSelectionAsmcomppathGet"); 

  status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions),
    1, (ProArray*)&opts);

  opts[0]= PRO_FEAT_CR_DEFINE_MISS_ELEMS;

  status = ProFeatureWithoptionsRedefine (&comp_path, &feature, created_elemtree,
    opts, PRO_REGEN_NO_FLAGS, &errors);
  C_LOG (" ProFeatureWithoptionsRedefine"); 

  status = ProArrayFree((ProArray*)&opts);

/*---------------------------------------------------------------*\
    Free up the allocated memory.
\*---------------------------------------------------------------*/
  status = ProFeatureElemtreeFree (&feature, created_elemtree); 
  C_LOG (" ProFeatureElemtreeFree"); 

  status = ProElementFree (&pro_e_feature_tree); 
  C_LOG (" ProElementFree"); 

  return (status);
}

#undef C_LOG
#undef C_PRINT