/*
	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 "ProExtrude.h"

static ProFileName message_file; 

#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);

/*===============================================================*\
FUNCTION : UserSktExtrusionProtrusionExtSkt
PURPOSE  : Demonstrates the creation of the extruded protrusion
           with external sketch 
\*===============================================================*/
ProError UserSktExtrusionProtrusionExtSkt()
{
  ProErrorlist            errors;
  ProMdl                  model;
  ProModelitem            model_item;
  ProSelection            model_sel;
  ProFeature              feature;
  ProFeatureCreateOptions *opts = 0;
  ProElempath             path;
  ProElempathItem         path_items[2];
  ProSection              section;
  ProAsmcomppath          comp_path;
  ProAsmcomppath          *p_comp_path = NULL;

  ProElement pro_e_feature_tree;
  ProElement pro_e_feature_form;
  ProElement pro_e_ext_surf_cut_solid_type;
  ProElement pro_e_remove_material;
  ProElement pro_e_feat_form_is_thin;
  ProElement pro_e_std_direction;
  ProElement pro_e_std_matrlside;

  ProElement pro_e_std_ext_depth;
  ProElement pro_e_ext_depth_from;
  ProElement pro_e_ext_depth_from_type;
  ProElement pro_e_ext_depth_from_value;
  ProElement pro_e_ext_depth_to;
  ProElement pro_e_ext_depth_to_type;
  ProElement pro_e_ext_depth_to_value;
  
  /* External Sketch */
  ProElement pro_e_std_section;
  ProElement pro_e_use_sketch;
  ProReference external_sketch_ref;
  
  ProError 	status;
  ProSelection * p_select;
  int 		n_select;
  
  ProStringToWstring ( message_file, "msg_ugfeatcreat.txt" ); 

  log_file = PTApplsUnicodeFopen ( "ug_sketched_curve.log", "w" ); 

  status = ProMdlCurrentGet (&model);
  if ( status != PRO_TK_NO_ERROR ) return ( status );
  
  /*---------------------------------------------------------------*\
    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_FORM 
  \*---------------------------------------------------------------*/

  C_PRINT( " *** Processing Element PRO_E_FEATURE_FORM *** " );
  status = ProElementAlloc ( PRO_E_FEATURE_FORM, &pro_e_feature_form );
  C_LOG( " ProElementAlloc " );
  status = ProElementIntegerSet ( pro_e_feature_form, PRO_EXTRUDE );
  C_LOG( " ProElementIntegerSet" );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_feature_form );
  C_LOG( " ProElemtreeElementAdd" );
  
  /*---------------------------------------------------------------*\
    Populating element PRO_E_EXT_SURF_CUT_SOLID_TYPE
  \*---------------------------------------------------------------*/
  
  C_PRINT( " *** Processing Element PRO_E_EXT_SURF_CUT_SOLID_TYPE *** " );
  status = ProElementAlloc ( PRO_E_EXT_SURF_CUT_SOLID_TYPE, &pro_e_ext_surf_cut_solid_type );
  C_LOG( " ProElementAlloc " );
  status = ProElementIntegerSet ( pro_e_ext_surf_cut_solid_type, PRO_EXT_FEAT_TYPE_SOLID );
  C_LOG( " ProElementIntegerSet" );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_ext_surf_cut_solid_type );
  C_LOG( " ProElemtreeElementAdd" );
 
  /*---------------------------------------------------------------*\
    Populating  element PRO_E_REMOVE_MATERIAL
  \*---------------------------------------------------------------*/

  C_PRINT( " *** Processing Element PRO_E_REMOVE_MATERIAL *** " );
  status = ProElementAlloc ( PRO_E_REMOVE_MATERIAL, &pro_e_remove_material );
  C_LOG( " ProElementAlloc " );
  status = ProElementIntegerSet ( pro_e_remove_material, PRO_EXT_MATERIAL_ADD );
  C_LOG( " ProElementIntegerSet" );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_remove_material );
  C_LOG( " ProElemtreeElementAdd" );
  
  /*---------------------------------------------------------------*\
    Populating  element PRO_E_FEAT_FORM_IS_THIN
  \*---------------------------------------------------------------*/

  C_PRINT( " *** Processing Element PRO_E_FEAT_FORM_IS_THIN *** " );
  status = ProElementAlloc ( PRO_E_FEAT_FORM_IS_THIN, &pro_e_feat_form_is_thin );
  C_LOG( " ProElementAlloc " );
  status = ProElementIntegerSet ( pro_e_feat_form_is_thin, PRO_EXT_FEAT_FORM_NO_THIN );
  C_LOG( " ProElementIntegerSet" );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_feat_form_is_thin );
  C_LOG( " ProElemtreeElementAdd" );
  
  
  /*---------------------------------------------------------------*\
    Populating  compound element PRO_E_STD_EXT_DEPTH
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_STD_EXT_DEPTH *** " );
  status = ProElementAlloc ( PRO_E_STD_EXT_DEPTH, &pro_e_std_ext_depth );
  C_LOG( " ProElementAlloc" );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_std_ext_depth  );
  C_LOG( " ProElemtreeElementAdd" );

  /*---------------------------------------------------------------*\
    Populating  element PRO_E_STD_EXT_DEPTH
			-> PRO_E_EXT_DEPTH_FROM
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_EXT_DEPTH_FROM *** " );
  status = ProElementAlloc ( PRO_E_EXT_DEPTH_FROM, &pro_e_ext_depth_from );
  C_LOG( " ProElementAlloc" );
  status = ProElemtreeElementAdd ( pro_e_std_ext_depth, NULL, pro_e_ext_depth_from  );
  C_LOG( " ProElemtreeElementAdd" );

  /*---------------------------------------------------------------*\
    Populating  element PRO_E_STD_EXT_DEPTH
			-> PRO_E_EXT_DEPTH_FROM
			   -> PRO_E_EXT_DEPTH_FROM_TYPE
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_EXT_DEPTH_FROM_TYPE *** " );
  status = ProElementAlloc ( PRO_E_EXT_DEPTH_FROM_TYPE, &pro_e_ext_depth_from_type );
  C_LOG( " ProElementAlloc " );
  status = ProElementIntegerSet ( pro_e_ext_depth_from_type, PRO_EXT_DEPTH_FROM_NONE );
  C_LOG( " ProElementValueSet" );
  status = ProElemtreeElementAdd ( pro_e_ext_depth_from, NULL, pro_e_ext_depth_from_type );
  C_LOG( " ProElemtreeElementAdd" );

  /*---------------------------------------------------------------*\
    Populating  element PRO_E_STD_EXT_DEPTH
			-> PRO_E_EXT_DEPTH_TO
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_EXT_DEPTH_TO *** " );
  status = ProElementAlloc ( PRO_E_EXT_DEPTH_TO, &pro_e_ext_depth_to );
  C_LOG( " ProElementAlloc" );
  status = ProElemtreeElementAdd ( pro_e_std_ext_depth, NULL, pro_e_ext_depth_to  );
  C_LOG( " ProElemtreeElementAdd" );
  
  /*---------------------------------------------------------------*\
    Populating  element PRO_E_STD_EXT_DEPTH
			-> PRO_E_EXT_DEPTH_TO
			   -> PRO_E_EXT_DEPTH_TO_TYPE
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_EXT_DEPTH_TO_TYPE *** " );
  status = ProElementAlloc ( PRO_E_EXT_DEPTH_TO_TYPE, &pro_e_ext_depth_to_type );
  C_LOG( " ProElementAlloc " );
  status = ProElementIntegerSet ( pro_e_ext_depth_to_type, PRO_EXT_DEPTH_TO_BLIND );
  C_LOG( " ProElementIntegerSet" );
  status = ProElemtreeElementAdd ( pro_e_ext_depth_to, NULL, pro_e_ext_depth_to_type );
  C_LOG( " ProElemtreeElementAdd" );

   /*---------------------------------------------------------------*\
    Populating  element PRO_E_STD_EXT_DEPTH
			-> PRO_E_EXT_DEPTH_TO
			   -> PRO_E_EXT_DEPTH_TO_VALUE
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_EXT_DEPTH_TO_VALUE *** " );
  status = ProElementAlloc ( PRO_E_EXT_DEPTH_TO_VALUE, &pro_e_ext_depth_to_value );
  C_LOG( " ProElementAlloc " );
  status = ProElementDoubleSet ( pro_e_ext_depth_to_value, 50.000000 );
  C_LOG( " ProElementDoubleSet" );
  status = ProElemtreeElementAdd ( pro_e_ext_depth_to, NULL, pro_e_ext_depth_to_value );
  /*---------------------------------------------------------------*\
    Populating  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" );

  /*---------------------------------------------------------------*\
    Populating element PRO_E_STD_SECTION 
			-> PRO_E_SEC_USE_SKETCH
  \*---------------------------------------------------------------*/
  
  C_PRINT( " *** Processing Element PRO_E_SEC_USE_SKETCH *** " );
  status = ProMessageDisplay ( message_file, "USER Select Sketch :" ); 
  C_LOG( " ProMessageDisplay"  );

  status = ProSelect ( "feature", 1, NULL, NULL, 
		NULL, NULL, &p_select, &n_select );
  C_LOG( " ProSelect" );
  if ( n_select <= 0 ) return -1; 
  else
    {
      status = ProSelectionToReference ( p_select[0], &external_sketch_ref );
      C_LOG (" ProSelectionToReference ");
    }
  status = ProElementAlloc ( PRO_E_SEC_USE_SKETCH, &pro_e_use_sketch );
  C_LOG( " ProElementAlloc " );

  status = ProElementReferenceSet ( pro_e_use_sketch, external_sketch_ref );
  C_LOG( " ProElementReferenceSet" );

  status = ProElemtreeElementAdd ( pro_e_std_section, NULL, 
		pro_e_use_sketch );
  C_LOG( " ProElemtreeElementAdd" );

  /*---------------------------------------------------------------*\
    Creating feature in the current model.
  \*---------------------------------------------------------------*/
  status = ProMdlToModelitem( model, &model_item ); 
  status = ProSelectionAlloc ( NULL, &model_item,
			   &model_sel);
  

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

  opts[0]= PRO_FEAT_CR_DEFINE_MISS_ELEMS;

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

  status = ProArrayFree((ProArray*)&opts);
  
/*---------------------------------------------------------------*\
    Free up the allocated memory.
\*---------------------------------------------------------------*/
  
  status = ProElementFree (&pro_e_feature_tree ); 
  C_LOG (" ProElementFree"); 

  return (status);
}

#undef C_LOG
#undef C_PRINT