/*
	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, "UgSktFirstFeatureCreate.c", status );

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

ProError UserSectionFirstFeatureBuild ( ProSection * section );

/*===============================================================*\
FUNCTION : UgSktFirstFeatureCreate
PURPOSE  : Demonstrates the creation of the first extruded protrusion
           feature
\*===============================================================*/
ProError UgSktFirstFeatureCreate()
{
  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;
  ProValue                value;
  ProValue                new_value;

  ProElement sketch_element; 
  ProElement created_elemtree; 
  
  ProElement pro_e_feature_tree;
  ProElement pro_e_feature_type;
  ProElement pro_e_feature_form;

  ProElement pro_e_feat_form_is_thin;
  ProElement pro_e_thickness;

  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;
  
  ProElement pro_e_sketcher;
  
  ProError 	status;
  ProValueData 	value_data;
  ProSelection * p_select;
  int 		n_select;
  
  ProStringToWstring ( message_file, "utilities.txt" ); 

  log_file = PTApplsUnicodeFopen ( "ug_sketched_curve.log", "w" ); 
  
  /*---------------------------------------------------------------*\
    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_FIRST_FEAT);
  C_LOG( " ProElementIntegerSet" );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_feature_type );
  C_LOG( " ProElemtreeElementAdd" );

  /*---------------------------------------------------------------*\
    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  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_BLIND);
  C_LOG( " ProElementIntegerSet" );
  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_FROM
			   -> PRO_E_EXT_DEPTH_FROM_VALUE
  \*---------------------------------------------------------------*/
  C_PRINT( " *** Processing Element PRO_E_EXT_DEPTH_FROM_VALUE *** " );
  status = ProElementAlloc ( PRO_E_EXT_DEPTH_FROM_VALUE, &pro_e_ext_depth_from_value );
  C_LOG( " ProElementAlloc " );
  status = ProElementDecimalsSet( pro_e_ext_depth_from_value,4 );
  status = ProElementDoubleSet(pro_e_ext_depth_from_value,120.000000);
  C_LOG( " ProElementDoubleSet" );
  status = ProElemtreeElementAdd ( pro_e_ext_depth_from, NULL, pro_e_ext_depth_from_value );
  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 = ProElementDecimalsSet( pro_e_ext_depth_to_value,4 );
  status = ProElementDoubleSet(pro_e_ext_depth_to_value,0.0);
  C_LOG( " ProElementDoubleSet" );
  status = ProElemtreeElementAdd ( pro_e_ext_depth_to, NULL, pro_e_ext_depth_to_value );
  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_SKETCHER;

  status = ProElempathAlloc (&path);
  status = ProElempathDataSet (path, path_items, 1);
  
  status = ProElemtreeElementGet ( created_elemtree, path, &sketch_element);
  C_LOG (" ProElemtreeElementGet PRO_E_SKETCHER "); 

  status = ProElementSpecialvalueGet(sketch_element, NULL, (ProAppData *) &section);
  C_LOG(" ProElementSpecialvalueGet");
  
/*---------------------------------------------------------------*\
   Creating a 3-D section 
\*---------------------------------------------------------------*/
  
  status = UserSectionFirstFeatureBuild (( ProSection * )(&section) );
  C_LOG ("UserSectionFirstFeatureBuild"); 

/*---------------------------------------------------------------*\
   Allocating and assigning new ProValue to sketcher element
	:: Wildfire requirement
\*---------------------------------------------------------------*/

  status = ProElementSpecialvalueSet(sketch_element, (ProAppData) section);
  C_LOG("ProElementSpecialvalueSet");  

  ProElempathFree (&path);

/*---------------------------------------------------------------*\
   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);
}

ProError UserSectionFirstFeatureBuild ( ProSection * section_here )
{
  Pro2dLinedef line; 
  ProError status; 
  int line_id[4]; 

  ProName section_name; 

  ProWSecerror section_errors1; 
  ProWSecerror section_errors2; 
  ProWSecerror section_errors3; 
  int n_sec; 
  ProMsg error_message;  
  char error_message_s[100];

  int i, error_id; 


  status = ProSecerrorAlloc ( &section_errors1 ); 
  C_LOG (" ProSecerrorAlloc"); 

  status = ProSecerrorAlloc ( &section_errors2 ); 
  C_LOG (" ProSecerrorAlloc"); 

  status = ProSecerrorAlloc ( &section_errors3 ); 
  C_LOG (" ProSecerrorAlloc"); 

  status = ProSection2DAlloc ( section_here ); 
  C_LOG (" ProSection2DAlloc"); 

  ProTKPrintf("The status for ProSection2DAlloc is = %d\n", status );

  line.type = PRO_2D_LINE;
  line.end1[0] = 0;
  line.end1[1] = 0;
  line.end2[0] = 100; 
  line.end2[1] = 0; 

  status = ProSectionEntityAdd ( *section_here, (Pro2dEntdef*)&line, &line_id[0] ) ;
  C_LOG (" ProSectionEntityAdd"); 

  line.type = PRO_2D_LINE;
  line.end1[0] = 100;
  line.end1[1] = 0;
  line.end2[0] = 100; 
  line.end2[1] = 100; 

  status = ProSectionEntityAdd ( *section_here, (Pro2dEntdef*)&line, &line_id[1] ) ;
  C_LOG (" ProSectionEntityAdd"); 

  line.type = PRO_2D_LINE;
  line.end1[0] = 100;
  line.end1[1] = 100;
  line.end2[0] = 0; 
  line.end2[1] = 100; 

  status = ProSectionEntityAdd ( *section_here, (Pro2dEntdef*)&line, &line_id[2] ) ;
  C_LOG (" ProSectionEntityAdd"); 

  line.type = PRO_2D_LINE;
  line.end1[0] = 0;
  line.end1[1] = 100;
  line.end2[0] = 0; 
  line.end2[1] = 0; 

  status = ProSectionEntityAdd ( *section_here, (Pro2dEntdef*)&line, &line_id[3] ) ;
  C_LOG (" ProSectionEntityAdd"); 

  status = ProSectionEpsilonSet( *section_here, 0.1 );
  C_LOG (" ProSectionEpsilonSet("); 

  status = ProSectionAutodim ( *section_here, &section_errors1 ); 
  C_LOG (" ProSectionAutodim"); 

  if ( status != PRO_TK_NO_ERROR )
    {
      status = ProSecerrorCount ( &section_errors1, &n_sec ); 
      ProTKPrintf("The status for ProSecerrorCount is = %d\n", status );
      ProTKPrintf("Number of errors in the ProSectionAutodim = %d \n",n_sec ); 
      for ( i = 0; i < n_sec; i++ )
	{
	  status = ProSecerrorMsgGet (section_errors1, i, error_message);
	  ProTKPrintf("The status for ProSecerrorMsgGet is = %d\n", status );
	  ProWstringToString (error_message_s, error_message);
	  status = ProSecerrorItemGet ( section_errors1, i, &error_id);
	  ProTKPrintf("The status for ProSecerrorMsgGet is = %d\n", status );
	  ProTKPrintf(" %s : Problem ID : %d \n", error_message_s, error_id );
	}
    }


  status = ProSectionRegenerate ( *section_here, &section_errors3 ); 
  C_LOG (" ProSectionRegenerate"); 

  if ( status != PRO_TK_NO_ERROR )
    {
      status = ProSecerrorCount ( &section_errors3, &n_sec ); 
      ProTKPrintf("The status for ProSecerrorCount is = %d\n", status );
      ProTKPrintf("Number of errors in ProSectionRegenerate = %d \n",n_sec ); 

    }

  return ( status ); 

}

#undef C_LOG
#undef C_PRINT