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



/*---------------------- Pro/Toolkit Includes ------------------------*/
#include <ProToolkit.h>
#include <ProFeature.h>
#include <ProFeatType.h>
#include <ProGeomitem.h>
#include <ProUtil.h>

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

/*---------------------- Function Prototypes -------------------------*/
ProError UserHoleSrfDisp();
ProError UserEdgeNeighborsEval(ProGeomitem *p_handle,
                               ProError    status,
                               ProAppData  app_data);
 
typedef struct uappdata
{
    int feature_id;
    ProMdl solid;
} UappData;


/*============================================================================*\
    Function: UserHoleSrfDisp()
    Purpose: Display surfaces adjacent to selected hole
\*============================================================================*/
ProError UserHoleSrfDisp()
{
    int n, sel_count, feat_id;
    ProFeattype feat_type;
    ProError status;
    ProFeature feat;
    ProFileName msgfile;
    ProSelection *psels=NULL;
    ProMdl p_solid;
    ProModelitem p_surf, p_edge, p_mdl_item;
    UappData appdata;

/*----------------------------------------------------------------------------*\
	Prompt user for hole selection
\*----------------------------------------------------------------------------*/
    ProStringToWstring(msgfile,"msg_uggeom.txt");
    ProMessageDisplay(msgfile,"USER Select Hole Feature:");
    if((ProSelect("feature",1,NULL,NULL,NULL,NULL,&psels, &sel_count) != 
       PRO_TK_NO_ERROR) || (sel_count < 1))
       return((int) PRO_TK_GENERAL_ERROR);

    status = ProSelectionModelitemGet(psels[0],&p_mdl_item);
    ERROR_CHECK( "UserHoleSrfDisp", "ProSelectionModelitemGet", status );
    
/*----------------------------------------------------------------------------*\
	Verify selection of hole feature
\*----------------------------------------------------------------------------*/
    status = ProFeatureTypeGet(&p_mdl_item,&feat_type);
    ERROR_CHECK( "UserHoleSrfDisp", "ProFeatureTypeGet", status );

    if(feat_type != PRO_FEAT_HOLE)
    {
       ProMessageDisplay(msgfile,"USER Feature is not a hole");
       ERROR_CHECK( "UserHoleSrfDisp", "ProMessageDisplay(Feature is not)",status);
       return((int) PRO_TK_GENERAL_ERROR);
    }

/*----------------------------------------------------------------------------*\
	Use UappData structure (cast to ProAppData type)
        to pass data between visit function and here
\*----------------------------------------------------------------------------*/

    appdata.feature_id = p_mdl_item.id;
    status = ProMdlCurrentGet(&(appdata.solid));
    ERROR_CHECK( "UserHoleSrfDisp", "ProMdlCurrentGet",status);
    status = ProFeatureGeomitemVisit(&p_mdl_item, PRO_EDGE,UserEdgeNeighborsEval,NULL,
                                    (ProAppData) &appdata);
    ERROR_CHECK( "UserHoleSrfDisp", "ProFeatureGeomitemVisit",status);
    return((int)PRO_TK_NO_ERROR);
}

/*============================================================================*\
    Function : UserEdgeNeighborsEval()
    Purpose  : Evaluate surfaces adjacent to edges by comparing feature id 
	       to feature id of hole
\*============================================================================*/
ProError UserEdgeNeighborsEval(
  ProGeomitem *p_edge,   /* input from visit function */
  ProError status,       /* output from filter function */
  ProAppData p_inp       /* user application data - input in this case */
)
{
    int n;
    UappData *ud = (UappData *)p_inp;
    ProEdge this_edge, next1, next2;
    ProSurface surf[2];
    ProGeomitem geom_item;
    ProSelection selection;
    ProFeature feat;

/*----------------------------------------------------------------------------*\
    Look at both surfaces attached to this edge and  highlight whichever
    doesn't belong to this feature.
\*----------------------------------------------------------------------------*/
    status = ProGeomitemToEdge(p_edge,&this_edge);
    ERROR_CHECK("UserEdgeNeighborsEval","ProGeomitemToEdge",status);
    status = ProEdgeNeighborsGet(this_edge,&next1,&next2,&surf[0],&surf[1]);
    ERROR_CHECK("UserEdgeNeighborsEval","ProEdgeNeighborsGet",status);
    for(n=0; n < 2; n++)
    {
        status = ProSurfaceToGeomitem(ud->solid,surf[n],&geom_item);
        ERROR_CHECK("UserEdgeNeighborsEval","ProSurfaceToGeomitem",status);
        status = ProGeomitemFeatureGet(&geom_item,&feat);
        ERROR_CHECK("UserEdgeNeighborsEval","ProGeomitemFeatureGet",status);
        if(feat.id != ud->feature_id)
        {
	    status = ProSelectionAlloc(NULL,&geom_item,&selection);
	    ERROR_CHECK("UserEdgeNeighborsEval","ProSelectionAlloc",status);
	    status = ProSelectionHighlight(selection, PRO_COLOR_HIGHLITE);
	    ERROR_CHECK("UserEdgeNeighborsEval","ProSelectionHighlight",status);
	    status = ProSelectionFree(&selection);
	    ERROR_CHECK("UserEdgeNeighborsEval","ProSelectionFree",status);
        }
    }
      
    return((int)PRO_TK_NO_ERROR);
}