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


/*---------------------- Pro/Toolkit Includes ------------------------*/
#include <ProToolkit.h>
#include <ProMdl.h>
#include <ProElement.h>
#include <ProFeatType.h>
#include <ProFeatForm.h>
#include <ProFeature.h>
#include <ProSection.h>
#include <ProRemoveSurf.h>
 
/*---------------------- Pro/Develop Includes ------------------------*/

/*---------------------- Application Includes ------------------------*/
#include <TestError.h>
#include <UtilTree.h>
#include <UtilFeats.h>

/*---------------------- Application Typedefs ------------------------*/


/*---------------------- Prototypes ----------------------------------*/
ProError UtilCreateRemoveSurfaceFeature(ProMdl model, ProSelection *p_sel);
ProError CreateFeature(ProAsmcomppath *p_comp_path ,ProMdl model, 
                           ProElement pro_e_feature_tree, 
                           ProFeature *feature);
ProError FeatRemoveSurfExample();


/*===============================================================*\
FUNCTION : FeatRemoveSurfExample
PURPOSE  : Example to create a remove surface feature

returns : 
PRO_TK_NO_ERROR - Successfully executed
\*===============================================================*/
ProError FeatRemoveSurfExample()
{
    ProError status;
    ProMdl model;
    ProSelection *surf_sels = NULL;
    int	n_select = 0;
  
    status = ProMdlCurrentGet (&model);
    ERROR_CHECK( "FeatRemoveSurfExample", "ProMdlCurrentGet", status );    
    if(status != PRO_TK_NO_ERROR)
        return status;
    
    ProStringToWstring ( message_file, "msg_ugfeatcreat.txt" );     
    status = ProMessageDisplay ( message_file, "USER Select remove surfaces :" ); 
    ERROR_CHECK("ProMessageDisplay", "FeatRemoveSurfExample", status);
    
    status = ProSelect ( "surface", -1, NULL, NULL, 
		 NULL, NULL, &surf_sels, &n_select );
    ERROR_CHECK("ProSelect", "FeatRemoveSurfExample", status);		 
    if ( n_select <= 0 ) return PRO_TK_GENERAL_ERROR; 
    
    status = UtilCreateRemoveSurfaceFeature(model, surf_sels);
    if(PRO_TK_NO_ERROR != status)
        status = ProMessageDisplay ( message_file,
                     "USER Feature created successfully" );
    else        
        status = ProMessageDisplay ( message_file,
                     "USER Feature creation failed");
    return status;
}

/*===============================================================*\
FUNCTION : UtilCreateRemoveSurfaceFeature
PURPOSE  : Create a remove surface feature from the selection input.
\*===============================================================*/
ProError UtilCreateRemoveSurfaceFeature(ProMdl model, ProSelection *p_sel)
{
    ProFeature              feature;
    ProSection              section;
    ProAsmcomppath          *p_comp_path = NULL;
    int no_sels;
    int i;
    ProValueData 	value_data;
      
    ProSrfcollinstr instr;
    ProReference reference;
    ProSrfcollref isntr_ref;
    ProName wide_string;
  
    ProError status, rem_surf_status;

    ProElement pro_e_feature_tree;
    ProElement pro_e_std_feature_name;
    ProElement pro_e_rm_surf_ref_type;
    ProElement pro_e_rm_surf_srf_refs;
    ProElement pro_e_std_excl_cntrs;
  
 
    ProCollection srf_collection = NULL;
    ProCollection collection;

   if(p_sel == NULL)
   {
     return PRO_TK_BAD_INPUTS;
   }

   /*
   PRO_E_FEATURE_TREE
   |
   |
   |-- PRO_E_FEATURE_TYPE
   |
   |-- PRO_E_STD_FEATURE_NAME
   |
   |-- PRO_E_RM_SURF_REF_TYPE
   |
   |-- PRO_E_RM_SURF_ATTACH_TYPE  */
   /*-----------------------------------------------------*\ 
   Populating root element PRO_E_FEATURE_TREE  
   \*-----------------------------------------------------*/
   status = ProElementAlloc ( PRO_E_FEATURE_TREE, &pro_e_feature_tree );

   /*-----------------------------------------------------*\ 
   Populating root element PRO_E_FEATURE_TYPE  
   \*-----------------------------------------------------*/   
   value_data.v.i = PRO_FEAT_RM_SURF; 
   status = ProUtilElemtreeElementAdd( pro_e_feature_tree, PRO_E_FEATURE_TYPE,
                                 ELEM_VALUE_TYPE_INT, &value_data.v.i);        
      
   
   /*-----------------------------------------------------*\
   Populating element PRO_E_STD_FEATURE_NAME 
   \*-----------------------------------------------------*/
   /*status = ProElementAlloc ( PRO_E_STD_FEATURE_NAME,
      &pro_e_std_feature_name );
   ProStringToWstring ( wide_string, "REMOVE_1" );
   status = ProElementWstringSet (  pro_e_std_feature_name,
      wide_string );
   status = ProElemtreeElementAdd ( pro_e_feature_tree,
      NULL, pro_e_std_feature_name ); */

   /*-----------------------------------------------------*\ 
   Populating element PRO_E_RM_SURF_REF_TYPE  
   \*-----------------------------------------------------*/
   value_data.v.i = PRO_RM_SURF_SRF_REF; 
   status = ProUtilElemtreeElementAdd( pro_e_feature_tree, PRO_E_RM_SURF_REF_TYPE,
                                 ELEM_VALUE_TYPE_INT, &value_data.v.i);     

   /*-----------------------------------------------------*\ 
   Populating element PRO_E_RM_SURF_ATTACH_TYPE  
   \*-----------------------------------------------------*/
   value_data.v.i = FM_RM_SURF_ATTACH_SAME; 
   status = ProUtilElemtreeElementAdd( pro_e_feature_tree, PRO_E_RM_SURF_ATTACH_TYPE,
                                 ELEM_VALUE_TYPE_INT, &value_data.v.i); 

   /*
          |
          |-- PRO_E_RM_SURF_SRF_REFS
          |    |
          |    |-- PRO_E_STD_SURF_COLLECTION_APPL
          |    |
          |    |-- PRO_E_STD_EXCL_CNTRS
          |         |
          |         |-- PRO_E_STD_EXCL_CNTRS_ONE_CNTR
          |              |
          |              |-- PRO_E_STD_EXCL_CNTR_SRF_REF      
          |              |
          |              |-- PRO_E_STD_EXCL_CNTR_EDGE_REF      
          |
          |-- PRO_E_RM_SURF_CRV_REFS
          |    |
          |    |-- PRO_E_STD_CURVE_COLLECTION_APPL      
   */


   /*-----------------------------------------------------*\ 
   Populating element PRO_E_RM_SURF_SRF_REFS  
   \*-----------------------------------------------------*/
   status = ProElementAlloc ( PRO_E_RM_SURF_SRF_REFS,
      &pro_e_rm_surf_srf_refs );
   status = ProElemtreeElementAdd ( pro_e_feature_tree,
      NULL, pro_e_rm_surf_srf_refs ); 


   /*-----------------------------------------------------*\ 
   Creating the collection object and setting the instructions
   \*-----------------------------------------------------*/
   status = ProSrfcollectionAlloc ( &collection );
   /* status = ProCrvcollinstrAlloc ( PRO_CURVCOLL_ADD_ONE_INSTR, &instr ); */
   status = ProSrfcollinstrAlloc ( 1, PRO_B_TRUE, &instr );
   status = ProSrfcollinstrIncludeSet ( instr, 1 );
   
   status = ProArraySizeGet ( p_sel, &no_sels);
   for (i=0; i<no_sels; i++)
      {
      status = ProSelectionToReference ( p_sel[i], &reference );
      ERROR_CHECK("ProMdlToModelitem", "UtilCreateRemoveSurfaceFeature", status); 
      status = ProSrfcollrefAlloc ( PRO_SURFCOLL_REF_SINGLE,
         reference, &isntr_ref );
      status = ProSrfcollinstrReferenceAdd ( instr, isntr_ref );
      ERROR_CHECK("ProSrfcollinstrReferenceAdd", "UtilCreateRemoveSurfaceFeature", status);       
      }
   status = ProSrfcollectionInstructionAdd ( collection, instr );
   status = ProSrfcollectionCopy ( collection, &srf_collection ); 
   if ( status != PRO_TK_NO_ERROR )
      {
      return status; 		  
      }
      
   /*-----------------------------------------------------*\   
   Populating element PRO_E_STD_SURF_COLLECTION_APPL  
   \*-----------------------------------------------------*/
   status = ProUtilElemtreeElementAdd( pro_e_rm_surf_srf_refs, PRO_E_STD_SURF_COLLECTION_APPL,
                                 ELEM_VALUE_TYPE_COLLECTION, srf_collection); 
                                 
   /*-----------------------------------------------------*\ 
   Populating element PRO_E_STD_EXCL_CNTRS  
   \*-----------------------------------------------------*/
   status = ProElementAlloc ( PRO_E_STD_EXCL_CNTRS, &pro_e_std_excl_cntrs );
   status = ProElemtreeElementAdd ( pro_e_rm_surf_srf_refs,
      NULL, pro_e_std_excl_cntrs ); 

   /*-----------------------------------------------------*\   
   Creating feature in the model. 
   \*-----------------------------------------------------*/
   rem_surf_status = ProUtilFeatCreate(p_comp_path, 
                     model, pro_e_feature_tree, &feature);  

   /*-----------------------------------------------------*\   
   Free up the allocated memory.
   \*-----------------------------------------------------*/ 
   status = ProElementFree (&pro_e_feature_tree); 
   return rem_surf_status;
}