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

#include <ProToolkit.h>
#include <ProFeature.h>
#include <ProSelbuffer.h>
#include <ProReference.h>
#include <ProUtil.h>
#include <ProSmtFlatWall.h>
#include <ProSheetmetal.h>
#include <ProMenuBar.h>
#include <ProPopupmenu.h>
#include <ProMdl.h>
#include <PTApplsUnicodeUtils.h>
#include <ProEdge.h>
#include <ProFeatType.h>


  
/*=====================================================================*\
FUNCTION: UserSmtFlatWallCreate
PURPOSE:  Create sheetmetal flat wall features.
\*=====================================================================*/
int UserSmtFlatWallCreate (ProReference edge_ref,
			    double bend_radius,
			    ProSection section) 
{ 
  ProError status;
  ProElement pro_e_feature_tree;
  ProElement pro_e_feature_type;
  ProElement pro_e_smt_wall_type;
  ProElement pro_e_std_feature_name;
  ProElement pro_e_smt_flat_wall_att_edge;
  ProElement pro_e_smt_flat_wall_angle;
  ProElement pro_e_smt_flat_wall_angle_type;
  ProElement pro_e_smt_flat_wall_angle_val;
  ProElement pro_e_smt_flat_wall_angle_flip;
  ProElement pro_e_std_section;
  ProElement pro_e_sketcher;
  ProElement pro_e_smt_fillets;
  ProElement pro_e_smt_fillets_use_rad;
  ProElement pro_e_smt_fillets_side;
  ProElement pro_e_smt_fillets_value;
  ProElement pro_e_smt_wall_height;
  ProElement pro_e_smt_wall_height_type;
  ProElement pro_e_smt_wall_height_value;
  ProElement pro_e_smt_bend_relief;
  ProElement pro_e_smt_bend_relief_side1;
  ProElement pro_e_bend_relief_type;
  ProElement pro_e_bend_relief_width;
  ProElement pro_e_bend_relief_depth;
  ProElement pro_e_bend_relief_angle;
  ProElement pro_e_smt_bend_relief_side2;
  ProElement pro_e_smt_wall_thickness_flip;
  ProElement pro_e_smt_dev_len_calculation;
  ProElement pro_e_smt_dev_len_source;
  ProElement pro_e_smt_dev_len_y_factor;
  ProElement pro_e_smt_dev_len_y_factor_value;
  ProElement pro_e_smt_dev_len_y_factor_type;
  ProElement pro_e_smt_dev_len_bend_table;
  ProMdl model;
  ProModelitem model_item;
  ProFeatureCreateOptions *opts = 0;
  ProSelection model_sel;
  ProFeature feature;
  ProErrorlist errors;
  ProSelection feat_sel;


/*-----------------------------------------------------------------*\
Processing Element PRO_E_FEATURE_TREE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_FEATURE_TREE, &pro_e_feature_tree ); 

/*-----------------------------------------------------------------*\
Processing Element PRO_E_FEATURE_TYPE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_FEATURE_TYPE, &pro_e_feature_type );
  status = ProElementIntegerSet ( pro_e_feature_type, PRO_FEAT_WALL );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				   pro_e_feature_type );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_WALL_TYPE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_WALL_TYPE, &pro_e_smt_wall_type );
  status = ProElementIntegerSet ( pro_e_smt_wall_type, 
				  PRO_SMT_WALL_TYPE_FLAT );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				   pro_e_smt_wall_type );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FLAT_WALL_ATT_EDGE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ATT_EDGE, 
			     &pro_e_smt_flat_wall_att_edge );
  status = ProElementReferenceSet( pro_e_smt_flat_wall_att_edge, edge_ref );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				   pro_e_smt_flat_wall_att_edge );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FLAT_WALL_ANGLE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE, 
			     &pro_e_smt_flat_wall_angle );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				   pro_e_smt_flat_wall_angle  );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FLAT_WALL_ANGLE_TYPE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE_TYPE, 
			     &pro_e_smt_flat_wall_angle_type );
  status = ProElementIntegerSet ( pro_e_smt_flat_wall_angle_type,
				  PRO_BND_ANGLE_VALUE);
  status = ProElemtreeElementAdd ( pro_e_smt_flat_wall_angle, NULL, 
				   pro_e_smt_flat_wall_angle_type );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FLAT_WALL_ANGLE_VAL
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE_VAL, 
			     &pro_e_smt_flat_wall_angle_val );
  status = ProElementDoubleSet (  pro_e_smt_flat_wall_angle_val, 90.000000 );
  status = ProElemtreeElementAdd ( pro_e_smt_flat_wall_angle, NULL, 
				   pro_e_smt_flat_wall_angle_val );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FLAT_WALL_ANGLE_FLIP
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FLAT_WALL_ANGLE_FLIP, 
			     &pro_e_smt_flat_wall_angle_flip );
  status = ProElementIntegerSet ( pro_e_smt_flat_wall_angle_flip, PRO_B_FALSE);
  status = ProElemtreeElementAdd ( pro_e_smt_flat_wall_angle, NULL, 
				   pro_e_smt_flat_wall_angle_flip );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_STD_SECTION
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_STD_SECTION, &pro_e_std_section );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, pro_e_std_section  );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SKETCHER
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SKETCHER, &pro_e_sketcher );
  status = ProElementSpecialvalueSet ( pro_e_sketcher, section );
  status = ProElemtreeElementAdd ( pro_e_std_section, NULL, 
				   pro_e_sketcher );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FILLETS
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FILLETS, &pro_e_smt_fillets );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				   pro_e_smt_fillets  );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FILLETS_USE_RAD
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FILLETS_USE_RAD, 
			     &pro_e_smt_fillets_use_rad );
  status = ProElementIntegerSet ( pro_e_smt_fillets_use_rad,  PRO_B_TRUE);
  status = ProElemtreeElementAdd ( pro_e_smt_fillets, NULL, 
				   pro_e_smt_fillets_use_rad );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FILLETS_SIDE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FILLETS_SIDE, &pro_e_smt_fillets_side );
  status = ProElementIntegerSet ( pro_e_smt_fillets_side, 
				  PRO_BEND_RAD_INSIDE );
  status = ProElemtreeElementAdd ( pro_e_smt_fillets, NULL, 
				   pro_e_smt_fillets_side );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_FILLETS_VALUE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_FILLETS_VALUE, 
			     &pro_e_smt_fillets_value );
  status = ProElementDoubleSet (  pro_e_smt_fillets_value, bend_radius );
  status = ProElemtreeElementAdd ( pro_e_smt_fillets, NULL, 
				   pro_e_smt_fillets_value );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_WALL_HEIGHT
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_WALL_HEIGHT, &pro_e_smt_wall_height );
  status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				   pro_e_smt_wall_height  );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_WALL_HEIGHT_TYPE
\*-----------------------------------------------------------------*/
  status = ProElementAlloc ( PRO_E_SMT_WALL_HEIGHT_TYPE, 
			     &pro_e_smt_wall_height_type );
  status = ProElementIntegerSet ( pro_e_smt_wall_height_type, 
				  PRO_SMT_WALL_HEIGHT_NONE );
  status = ProElemtreeElementAdd ( pro_e_smt_wall_height, NULL, 
				   pro_e_smt_wall_height_type );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_BEND_RELIEF
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_BEND_RELIEF, &pro_e_smt_bend_relief );
 status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				  pro_e_smt_bend_relief  );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_BEND_RELIEF_SIDE1
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_BEND_RELIEF_SIDE1, 
			    &pro_e_smt_bend_relief_side1 );
 status = ProElemtreeElementAdd ( pro_e_smt_bend_relief, NULL, 
				  pro_e_smt_bend_relief_side1  );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_BEND_RELIEF_TYPE
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_BEND_RELIEF_TYPE, &pro_e_bend_relief_type );
 status = ProElementIntegerSet ( pro_e_bend_relief_type, PRO_BEND_RLF_RIP );
 status = ProElemtreeElementAdd ( pro_e_smt_bend_relief_side1, NULL, 
				  pro_e_bend_relief_type );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_BEND_RELIEF_SIDE2
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_BEND_RELIEF_SIDE2, 
			    &pro_e_smt_bend_relief_side2 );
 status = ProElemtreeElementAdd ( pro_e_smt_bend_relief, NULL, 
				  pro_e_smt_bend_relief_side2  );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_BEND_RELIEF_TYPE
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_BEND_RELIEF_TYPE, 
			    &pro_e_bend_relief_type );
 status = ProElementIntegerSet ( pro_e_bend_relief_type, PRO_BEND_RLF_RIP );
 status = ProElemtreeElementAdd ( pro_e_smt_bend_relief_side2, NULL, 
				  pro_e_bend_relief_type );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_WALL_THICKNESS_FLIP
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_WALL_THICKNESS_FLIP, 
			    &pro_e_smt_wall_thickness_flip );
 status = ProElementIntegerSet ( pro_e_smt_wall_thickness_flip, 
				 PRO_B_FALSE );
 status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				  pro_e_smt_wall_thickness_flip );

/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_DEV_LEN_CALCULATION
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_CALCULATION, 
			    &pro_e_smt_dev_len_calculation );
 status = ProElemtreeElementAdd ( pro_e_feature_tree, NULL, 
				  pro_e_smt_dev_len_calculation  );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_DEV_LEN_SOURCE
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_SOURCE, 
			    &pro_e_smt_dev_len_source );
 status = ProElementIntegerSet ( pro_e_smt_dev_len_source, 
				 PRO_DVL_SRC_FEAT_YF_ONLY );
 status = ProElemtreeElementAdd ( pro_e_smt_dev_len_calculation, NULL, 
				  pro_e_smt_dev_len_source );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_DEV_LEN_Y_FACTOR
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_Y_FACTOR, 
			    &pro_e_smt_dev_len_y_factor );
 status = ProElemtreeElementAdd ( pro_e_smt_dev_len_calculation, NULL, 
				  pro_e_smt_dev_len_y_factor  );
 
/*-----------------------------------------------------------------*\
Processing Element PRO_E_SMT_DEV_LEN_Y_FACTOR_VALUE
\*-----------------------------------------------------------------*/
 status = ProElementAlloc ( PRO_E_SMT_DEV_LEN_Y_FACTOR_VALUE, 
			    &pro_e_smt_dev_len_y_factor_value );
 status = ProElementDoubleSet (  pro_e_smt_dev_len_y_factor_value, 
				 0.320000 );
 status = ProElemtreeElementAdd ( pro_e_smt_dev_len_y_factor, NULL, 
				  pro_e_smt_dev_len_y_factor_value );

/*-----------------------------------------------------------------*\
Create the feature using the element tree
\*-----------------------------------------------------------------*/
 status = ProMdlCurrentGet (&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_NO_OPTS;

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

  status = ProArrayFree((ProArray*)&opts);
 if (status == PRO_TK_NO_ERROR)
 {
	 ProSelectionAlloc (NULL, &feature, &feat_sel);
	 ProSelbufferClear ();
	 ProSelbufferSelectionAdd (feat_sel);
	 ProSelectionFree (&feat_sel);
 }

 return (PRO_TK_NO_ERROR);
}


/*=====================================================================*\
FUNCTION: UserSmtFlatWallCreate_OA_CreateISec
PURPOSE:  Create sheetmetal flat wall features using Object/Action 
          selection and Pro/E's predefined rectangular section.
\*=====================================================================*/
int UserSmtFlatWallCreate_OA_CreateRectSec ()
{
  ProError status;
  ProSelection* sel;
  ProReference reference;
  ProPart part;
  ProDimension thickness_dim;
  double thickness;
  ProSection rect_wall_sec;
  ProPath w_mdlpath;
  ProCharPath mdlpath, secpath;
  char* prodir;
  
/*-----------------------------------------------------------------*\
Extract the current selected edge or edge chain as the wall attachment
\*-----------------------------------------------------------------*/
  status = ProSelbufferSelectionsGet (&sel);

  status = ProSelectionToReference ( sel[0], &reference );
  
/*-----------------------------------------------------------------*\
Extract the wall thickness to use for the bend radius
\*-----------------------------------------------------------------*/ 
  status = ProMdlCurrentGet ((ProMdl*)&part);
  status = ProSmtPartThicknessGet(part, &thickness_dim);
  status = ProDimensionValueGet (&thickness_dim, &thickness);

/*-----------------------------------------------------------------*\
Retrieve the Pro/ENGINEER default section for rectangular flat walls
\*-----------------------------------------------------------------*/ 
  prodir = getenv ("PRO_DIRECTORY");
  if (prodir == NULL)
	return PRO_TK_INVALID_DIR;

  ProTKSprintf (secpath, "%s/text/smt/", prodir);
  ProTKSprintf (mdlpath, "%srect_flat_wall.sec", secpath);
  ProStringToWstring (w_mdlpath, mdlpath);
  status = ProMdlFiletypeLoad  (w_mdlpath,  PRO_MDLFILE_UNUSED, PRO_B_FALSE, 
					   (ProMdl*)&rect_wall_sec);

/*-----------------------------------------------------------------*\
Create the feature with the extracted information
\*-----------------------------------------------------------------*/
  UserSmtFlatWallCreate (reference, thickness, rect_wall_sec);

  ProReferenceFree (reference);

  return (PRO_TK_NO_ERROR);
}

/*=====================================================================*\
FUNCTION: UserSectionOpen
PURPOSE:  Retrieve a section using a File Open dialog.
\*=====================================================================*/
ProError UserSectionOpen (ProSection* sec)
{
  ProError status;
  ProName label;
  ProLine filter;
  ProPath* shortcut_path_arr;
  ProName* shortcut_name;
  ProPath path;

/*-----------------------------------------------------------------*\
Prompt to select a section using the Open dialog box
\*-----------------------------------------------------------------*/
  ProStringToWstring (label, "Select section");
  ProStringToWstring (filter, "*.sec");
  ProArrayAlloc (0, sizeof (ProPath), 1, (ProArray*) &shortcut_path_arr);
  ProArrayAlloc (0, sizeof (ProName), 1, (ProArray*) &shortcut_name);

  status = ProFileMdlnameOpen (label, filter, shortcut_path_arr, shortcut_name,
			NULL, NULL, path);
    
  if (status == PRO_TK_NO_ERROR)
  {
/*-----------------------------------------------------------------*\
Retrieve the selected section
\*-----------------------------------------------------------------*/
    status = ProMdlFiletypeLoad (path,  PRO_MDLFILE_UNUSED, PRO_B_FALSE, 
			 (ProMdl*)sec);
  }
  
  ProArrayFree ((ProArray*)&shortcut_path_arr);
  ProArrayFree ((ProArray*)&shortcut_name);
  
  return (status);
}

/*=====================================================================*\
FUNCTION: UserSmtFlatWallCreate_OA_CreateUserDefSec
PURPOSE:  Create sheetmetal flat wall features using Object/Action 
          selection and a user-selected 2D section.
\*=====================================================================*/
int UserSmtFlatWallCreate_OA_CreateUserDefSec ()
{
  ProError status;
  ProSelection* sel;
  ProReference reference;
  ProPart part;
  ProDimension thickness_dim;
  double thickness;
  ProSection userdef_sec;
  ProPath w_mdlpath;
  ProCharPath mdlpath, secpath;
  char* prodir;
  
/*-----------------------------------------------------------------*\
Prompt the user to select a section for the flange wall
\*-----------------------------------------------------------------*/
  status = UserSectionOpen (&userdef_sec);
  
  if (status != PRO_TK_NO_ERROR)
    return (status);

/*-----------------------------------------------------------------*\
Extract the current selected edge or edge chain as the wall attachment
\*-----------------------------------------------------------------*/
  status = ProSelbufferSelectionsGet (&sel);

  status = ProSelectionToReference ( sel[0], &reference );
  
/*-----------------------------------------------------------------*\
Extract the wall thickness to use for the bend radius
\*-----------------------------------------------------------------*/ 
  status = ProMdlCurrentGet ((ProMdl*)&part);
  status = ProSmtPartThicknessGet(part, &thickness_dim);
  status = ProDimensionValueGet (&thickness_dim, &thickness);

/*-----------------------------------------------------------------*\
Create the feature with the extracted information
\*-----------------------------------------------------------------*/
  UserSmtFlatWallCreate (reference, thickness, userdef_sec);
 
  ProReferenceFree (reference);
  ProMdlErase (userdef_sec);

  return (PRO_TK_NO_ERROR);
}

/*=====================================================================*\
FUNCTION: UserEdgeIsSmtFaceEdge
PURPOSE:  Returns TRUE if the edge borders a sheetmetal face.
\*=====================================================================*/
ProBoolean UserEdgeIsSmtFaceEdge (ProGeomitem* edge)
{
  ProEdge edge_ptr;
  ProEdge edges [2];
  ProSurface surfs [2];
  ProSmtSurfType srf_type, srf_type2;
  
/*-----------------------------------------------------------------*\
Obtain the neighboring surfaces for the given edge
\*-----------------------------------------------------------------*/
  ProGeomitemToEdge (edge, &edge_ptr);
  
  ProEdgeNeighborsGet (edge_ptr, &edges[0], &edges[1],
		       &surfs [0], &surfs[1]);
  
/*-----------------------------------------------------------------*\
Test the surfaces
\*-----------------------------------------------------------------*/
  ProSmtSurfaceTypeGet (edge->owner, surfs [0], &srf_type);
  ProSmtSurfaceTypeGet (edge->owner, surfs [1], &srf_type2);
  
  if (srf_type == PRO_SMT_SURF_FACE || 
      srf_type2 == PRO_SMT_SURF_FACE ||
      srf_type == PRO_SMT_SURF_OFFSET || 
      srf_type2 == PRO_SMT_SURF_OFFSET)
    return PRO_B_TRUE;
  else
    return PRO_B_FALSE;
}

#define OA 1  /* Standard OA in the menu system, typically gray out 
		 the button when not usable*/
#define PM 2 /* OA in a popup menu, typically remove the button when 
	         not usable */

/*=====================================================================*\
FUNCTION: UserSmtFlatWallCreate_TestLow
PURPOSE:  Access function for the button for smt flat wall feature creation
\*=====================================================================*/
static uiCmdAccessState UserSmtFlatWallCreate_TestLow (ProSelection* sels, 
						       int mode)
{
  uiCmdAccessState access_result;
  ProBoolean should_free = PRO_B_FALSE;
  ProError status;
  ProMdl mdl;
  ProMdlType type;
  ProMdlsubtype subtype;
  ProReference reference;
  ProModelitem item;
  ProEdge edge;
  ProEnttype ent_type;
  int size;

/*-----------------------------------------------------------------*\
  Set the default return if the button is unusable.
\*-----------------------------------------------------------------*/  
  if (mode == OA)
    access_result = ACCESS_UNAVAILABLE;
  else 
    access_result = ACCESS_REMOVE;

  status = ProMdlCurrentGet (&mdl);

  if (status != PRO_TK_NO_ERROR)
    return (access_result);

  status = ProMdlTypeGet (mdl, &type);

  status = ProMdlSubtypeGet (mdl, &subtype);
  
  if (type != PRO_MDL_PART || subtype != PROMDLSTYPE_PART_SHEETMETAL)
    return (access_result);

/*-----------------------------------------------------------------*\
  If called without selections, extract the current selections from
  the buffer.
\*-----------------------------------------------------------------*/ 
  if (sels == NULL)
    {   
      status = ProSelbufferSelectionsGet (&sels);
      
      if (status != PRO_TK_NO_ERROR)
	return access_result;

      if (sels == NULL)
	return access_result;

      should_free = PRO_B_TRUE;
    }

/*-----------------------------------------------------------------*\
  This command allows only one selection.
\*-----------------------------------------------------------------*/   
  status = ProArraySizeGet (sels, &size);
  
  if (status != PRO_TK_NO_ERROR)
    return access_result;

  if (size == 1)
    {
/*-----------------------------------------------------------------*\
Extract the reference edge selected by the user
\*-----------------------------------------------------------------*/    
      status = ProSelectionToReference (sels [0], &reference);
      ProTKPrintf ("Status of ProSelectionCollectionGet: %d\n\n", status);

      if (status == PRO_TK_NO_ERROR)
	{
/*-----------------------------------------------------------------*\
Check the reference to ensure that the reference is an edge 
which borders a sheetmetal face.
\*-----------------------------------------------------------------*/
	  ProReferenceTypeGet (reference, &item.type);
	  
	  if (item.type == PRO_EDGE)
	    {
	      
	      ProReferenceOwnerGet (reference, &item.owner);
	      ProReferenceIdGet (reference, &item.id);
	      
	      ProReferenceFree (reference);
	      
	      if (UserEdgeIsSmtFaceEdge (&item))
		{

/*-----------------------------------------------------------------*\
Flat wall attachment edge must be straight
\*-----------------------------------------------------------------*/
		  ProGeomitemToEdge (&item, &edge);
		  
		  ProEdgeTypeGet (edge, &ent_type);
		  
		  if (ent_type == PRO_ENT_LINE)
		    {
/*-----------------------------------------------------------------*\
If reference is OK, the button should be active.
\*-----------------------------------------------------------------*/
		      access_result = ACCESS_AVAILABLE;
		    }
		}
	    }
	}
    }
  
  if (should_free)
    ProSelectionarrayFree (sels);
      
  return access_result;
}

/*=====================================================================*\
FUNCTION: UserSmtFlatWallCreate_TestMdlTree
PURPOSE:  Access function for the model tree popup menu button.	
\*=====================================================================*/
uiCmdAccessState UserSmtFlatWallCreate_TestMdlTree (uiCmdAccessMode mode)
{ 
  return UserSmtFlatWallCreate_TestLow (NULL, PM);
}


/*=====================================================================*\
FUNCTION: UserSmtFlatWallCreate_TestPM
PURPOSE:  Access function for the graphics window popup menu button.	
\*=====================================================================*/
uiCmdAccessState UserSmtFlatWallCreate_TestPM (uiCmdCmdId id,
				      ProAppData data,
				      ProSelection* sels)
{ 
  return UserSmtFlatWallCreate_TestLow (sels, PM);
}