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


/*--------------------------------------------------------------------*\
Pro/Toolkit includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProSimprep.h>
#include <ProSimprepdata.h>
#include <ProRule.h>
#include <ProFeature.h>
#include <ProSolid.h>
#include <ProMdl.h>
#include <ProSelection.h>
#include <ProModelitem.h>
#include <ProArray.h>
#include <ProMenu.h>
#include <ProUtil.h>
#include <ProAsmcomp.h>
/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestSimpRep.h"
#include "TestError.h"
#include "UtilMessage.h"
#include "UtilString.h"
#include "TestConsts.h"
#include "TestRule.h"
#include "UtilCollect.h"

#include <string.h>
#include "PTApplsUnicodeUtils.h"
/*--------------------------------------------------------------------*\
Application macros
\*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*\
Application data types
\*--------------------------------------------------------------------*/
#define SEL_BY_PICK		1
#define SEL_BY_RULE		2


typedef struct 
	{
	    ProSelection	*p_sel;
	    int			num;
	    char		*p_option; 
	    ProError		status;
	} SelAppData;

static int   def_num;
static SimpRepActions rule_default;

ProError ProTestSelectModelMenu(char*,ProSelection**,int*); 

/*====================================================================*\
FUNCTION : ProTestSimpRep
PURPOSE  : Top level simp rep test menu
\*====================================================================*/
int ProTestSimpRep(ProSolid *p_solid )
{
#ifndef PT_PRODUCTS_BUILD
    ProError		status;
    int			menu_id;    /* The identifier of the created menu */
    int			menu_action;

ProMdlType type;
status = ProMdlTypeGet (*p_solid, &type);
/*--------------------------------------------------------------------*\
    Create menus
\*--------------------------------------------------------------------*/
    status = ProMenuFileRegister( (char *)"SIMPL REPR", (char *)"tksimplrep.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSimpRep()", 
			status, status != PRO_TK_NO_ERROR );

    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Create",
		(ProMenubuttonAction)ProTestSRepDefRule,p_solid,0);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Set Current",
		(ProMenubuttonAction)ProTestSRepList,p_solid, SET_CURR_REP);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Copy",
		(ProMenubuttonAction)ProTestSRepList,p_solid,COPY_REP);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Redefine",
		(ProMenubuttonAction)ProTestSRepList,p_solid, REDEFINE_REP);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Delete",
		(ProMenubuttonAction)ProTestSRepList,p_solid,DELETE_REP);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"List",
		(ProMenubuttonAction)ProTestSRepInfo,p_solid,0);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Info",
		(ProMenubuttonAction)ProTestSRepList,p_solid,REP_INFO);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"Done/Return",
		(ProMenubuttonAction)ProMenuDelete,NULL,0);
    ProMenubuttonActionSet((char *)"SIMPL REPR",(char *)"SIMPL REPR",
		(ProMenubuttonAction)ProMenuDelete,NULL,0);

/*--------------------------------------------------------------------*\
    Make main menu visible
\*--------------------------------------------------------------------*/
    status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"SIMPL REPR", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSimpRep()", 
			status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess( (char *)"SIMPL REPR", &menu_action );
	TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSimpRep()", 
			    status, status != PRO_TK_NO_ERROR );
    }


#endif /* #ifndef PT_PRODUCTS_BUILD */
    return PRO_TK_NO_ERROR;
}

/*====================================================================*\
FUNCTION : ProTestSRepRetrieve
PURPOSE  : Retreive a simp rep from named assembly
\*====================================================================*/
int ProTestSRepRetrieve()
{
#ifndef PT_PRODUCTS_BUILD
    ProSolid  assembly;
    ProError status;
    wchar_t assm_name[PRO_FAMILY_MDLNAME_SIZE], def[PRO_LINE_SIZE], rep_name[PRO_NAME_SIZE];
    char default_asm[] = "block-world";
    char default_rep[] = "Use Default";
    char message[PRO_LINE_SIZE];
    int def_act = 0;
    int range[] = {1,2};
    ProMdlfileType   file_type = PRO_MDLFILE_ASSEMBLY;

    ProStringToWstring(def,default_asm);
    ProTKSprintf(message, "Enter assembly name [%s] : ", default_asm);
    ProUtilMsgPrint("gen", "TEST %0s", message);
    ProUtilStringGet (assm_name, def, PRO_LINE_SIZE);

    ProStringToWstring(def,default_rep);
    ProTKSprintf(message, "Enter simp rep name [%s] : ", default_rep);
    ProUtilMsgPrint("gen", "TEST %0s", message);
    
    if (ProUtilStringGet (rep_name, NULL, PRO_NAME_SIZE))
    {
        status = ProAssemblySimprepMdlnameRetrieve(assm_name, file_type, rep_name, NULL, &assembly);
        TEST_CALL_REPORT("ProAssemblySimprepMdlnameRetrieve()", "ProTestSRepRetrieve()",
                                status, status != PRO_TK_NO_ERROR);

        status = ProSolidDisplay(assembly);
        TEST_CALL_REPORT("ProSolidDisplay()", "ProTestSRepRetrieve()",
                                status, status != PRO_TK_NO_ERROR &&
                                status != PRO_TK_E_FOUND);
        return(0);
    }

    ProTKSprintf(message, 
	"Enter default action type [1=Geom,2=Grfx]: ");
    ProUtilMsgPrint("gen", "TEST %0s", message);
    if (!ProUtilIntGet(range,NULL,&def_act))
	return(0);

    switch(def_act)
    {
	case 1:  
		status = ProSimprepMdlnameRetrieve(assm_name, PRO_MDLFILE_ASSEMBLY, PRO_SIMPREP_GEOM_REP, NULL, &assembly);
                TEST_CALL_REPORT("ProSimprepMdlnameRetrieve()", 
				 "ProTestSRepRetrieve()",
                                 status, status != PRO_TK_NO_ERROR &&
										 status != PRO_TK_BAD_INPUTS);
	break;
	case 2: 
		status = ProSimprepMdlnameRetrieve(assm_name, PRO_MDLFILE_ASSEMBLY, PRO_SIMPREP_GRAPH_REP, NULL, &assembly);
                TEST_CALL_REPORT("ProSimprepMdlnameRetrieve()", 
				 "ProTestSRepRetrieve()",
                                 status, status != PRO_TK_NO_ERROR &&
								         status != PRO_TK_BAD_INPUTS);
        break;
	default:
	        return(0);
    }
	if(status == PRO_TK_NO_ERROR){
		status = ProSolidDisplay(assembly);
		TEST_CALL_REPORT("ProSolidDisplay()", "ProTestSRepRetrieve()",
                            status, status != PRO_TK_NO_ERROR &&
                            status != PRO_TK_E_FOUND &&
							status != PRO_TK_BAD_INPUTS);
	}
#endif /* #ifndef PT_PRODUCTS_BUILD */
    return 0;
}

#ifndef PT_PRODUCTS_BUILD

/*====================================================================*\
FUNCTION : ProTestSRepCreate
PURPOSE  : Create a new simplified rep
\*====================================================================*/
int ProTestSRepCreate(SimpRepData *rep, SimpRepActions action)
{
    ProSimprep simp_rep;
    ProError status;

    ProTestSRepEdit(rep,action);

    status = ProSimprepCreate(*(rep->owner), rep->data, &simp_rep);
    TEST_CALL_REPORT("ProSimprepCreate()", "ProTestSRepCreate()",
                                status, status != PRO_TK_NO_ERROR);
        
    status = ProSimprepActivate(*(rep->owner), &simp_rep);    
    TEST_CALL_REPORT("ProSimprepActivate()", "ProTestSRepCreate()",
                                status, status != PRO_TK_NO_ERROR);
    status = (ProError)ProTestSRepRepaint(rep->owner);

    ProMenuDelete();

    return (0);
}

/*====================================================================*\
FUNCTION : ProTestSRepList
PURPOSE  : List exisiting simplified reps and perform a specified action
\*====================================================================*/
int ProTestSRepList(ProSolid *p_solid, SimpRepActions action)
{
    SimpRepData     simp_rep;
    ProSimprep	    sel_simp_rep;
    ProSimprep      active;
    ProError        status;
    ProSimprepType  type, active_type;
    
    /* Select a simp rep */
    status = ProSimprepSelect (*p_solid, &sel_simp_rep );
    TEST_CALL_REPORT("ProSimprepSelect()", "ProTestSRepList()", status, 
        status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

    /* Use selected simp rep to init the other simp rep */
    status = ProSimprepInit( NULL, sel_simp_rep.id, 
        *p_solid, &(simp_rep.simp_rep) );
    TEST_CALL_REPORT( "ProSimprepInit()", "ProTestSRepList()", status, 
        status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND );
        
    if (status != PRO_TK_NO_ERROR ) 
        return status;

    status = ProSimprepTypeGet (&(simp_rep.simp_rep), &type);
    TEST_CALL_REPORT( "ProSimprepTypeGet()", "ProTestSRepList()", 
        status, status != PRO_TK_NO_ERROR);

    simp_rep.owner = p_solid;

    switch (action)
    {
    case REDEFINE_REP:
/*--------------------------------------------------------------------*\
        Can't redefine master rep
\*--------------------------------------------------------------------*/
        if ( type == PRO_SIMPREP_MASTER_REP)
            return PRO_TK_NO_ERROR;

        status = ProSimprepActivate(*p_solid, &(simp_rep.simp_rep));
        TEST_CALL_REPORT("ProSimprepActivate()", "ProTestSRepList()",
                    status, status != PRO_TK_NO_ERROR);

            status = ProSolidDisplay(*p_solid);
        TEST_CALL_REPORT("ProSolidDisplay()", "ProTestSRepList()",
                    status, status != PRO_TK_NO_ERROR &&
                    status != PRO_TK_E_FOUND);

        status = (ProError)ProTestSRepRedefineMenu(&simp_rep, action);
            break;

    case SET_CURR_REP:
        status = ProSimprepActivate(*p_solid, &(simp_rep.simp_rep));
        TEST_CALL_REPORT("ProSimprepActivate()", "ProTestSRepList()",
                    status, status != PRO_TK_NO_ERROR);
         

        status = ProSimprepActiveGet(*p_solid, &active);
        TEST_CALL_REPORT("ProSimprepActiveGet()", "ProTestSRepList()",
                    status, status != PRO_TK_NO_ERROR);
        status = ProSolidDisplay(*p_solid);
        TEST_CALL_REPORT("ProSolidDisplay()", "ProTestSRepList()",
                    status, status != PRO_TK_NO_ERROR &&
                    status != PRO_TK_E_FOUND);

        if (status != PRO_TK_NO_ERROR)
            return PRO_TK_GENERAL_ERROR;

/*--------------------------------------------------------------------*\
        Selected and active reps should be the same id and type
\*--------------------------------------------------------------------*/
        status = ProSimprepTypeGet (&active, &active_type);
        TEST_CALL_REPORT( "ProSimprepTypeGet()", "ProTestSRepList()", 
            status, status != PRO_TK_NO_ERROR);
        
        if ((active_type != type) || (active.id != simp_rep.simp_rep.id) )
        {
            ProTKFprintf(stderr,"Error setting active simp rep!\n");
            return PRO_TK_GENERAL_ERROR;
        }
        break;
 
    case DELETE_REP:
/*--------------------------------------------------------------------*\
        Can't delete master rep
\*--------------------------------------------------------------------*/
        if ( type == PRO_SIMPREP_MASTER_REP)
            return PRO_TK_NO_ERROR;
        status = ProSimprepDelete(&(simp_rep.simp_rep));
        TEST_CALL_REPORT("ProSimprepDelete()", "ProTestSRepList()",
                    status, status != PRO_TK_NO_ERROR);
            break;

    case COPY_REP:
/*--------------------------------------------------------------------*\
        Can't copy master rep
\*--------------------------------------------------------------------*/
        if ( type == PRO_SIMPREP_MASTER_REP)
           return PRO_TK_NO_ERROR;
        status = ProTestSRepCopy(&(simp_rep.simp_rep));
        break;

    case REP_INFO:
/*--------------------------------------------------------------------*\
        Can't print info about master rep
\*--------------------------------------------------------------------*/
        if ( type == PRO_SIMPREP_MASTER_REP)
            return PRO_TK_NO_ERROR;
        status = ProTestSRepItemInfo(&(simp_rep.simp_rep), NULL);
        break;

    default:
        ProTKFprintf(stderr,"Error, selection error!\n");
            status = PRO_TK_BAD_INPUTS;
    }

    return status;
}

/*====================================================================*\
FUNCTION : ProTestSRepInfo
PURPOSE  : Print out def rule information about models simplified reps
\*====================================================================*/
int ProTestSRepInfo(
    ProSolid *p_solid)
{
    ProError status;
    FILE *simp_rep_fp;
    char filename[] = "simp_rep.inf";
    wchar_t wfilename[PRO_LINE_SIZE];
    ProInfoWindowLocation   win_location = { 0.0, 0.0 };
    ProInfoWindowSize	    win_size = { 25, 80 };

    if ( (simp_rep_fp = PTApplsUnicodeFopen(filename,"w")) == NULL)
    {
    ProTKFprintf(stderr,"Error opening file for writing\n");
        return -1;
    }
    status = ProSolidSimprepVisit(*p_solid, NULL,
             (ProGeomitemAction)ProTestSRepVisitInfo, (ProAppData)simp_rep_fp);
    TEST_CALL_REPORT("ProSolidSimprepVisit()", "ProTestSRepInfo()",
            status, status != PRO_TK_NO_ERROR);

    fclose(simp_rep_fp);

    status = ProInfoWindowDisplay( ProStringToWstring(wfilename, filename),
				    &win_location, &win_size );
    TEST_CALL_REPORT( "ProInfoWindowDisplay()", "ProTestSRepInfo()",
			status, status != PRO_TK_NO_ERROR);


    return 0;
}

/*====================================================================*\
FUNCTION : ProTestSRepVisitInfo
PURPOSE  : Display info window of an assembly's simplified reps
\*====================================================================*/
ProError ProTestSRepVisitInfo(
    ProSimprep *simp_rep,
    ProError err, 
    ProAppData tmp_fp)
{
    ProError status;
    wchar_t  wname[PRO_NAME_SIZE];
    char     name[PRO_PATH_SIZE];
    char     str[30];
    ProSimprepActionType def_action;
    ProSimprepdata *data;
    FILE *fp = (FILE *)tmp_fp;

    if (simp_rep == NULL || fp == NULL)
    {
    status = PRO_TK_GENERAL_ERROR;
    }

    status = ProSimprepdataGet(simp_rep, &data);
    TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRepVisitInfo()",
                status, status != PRO_TK_NO_ERROR);

    if (status == PRO_TK_NO_ERROR) 
    {
    status = ProSimprepdataNameGet(data, wname);
    TEST_CALL_REPORT("ProSimprepdataNameGet()", "ProTestSRepVisitInfo()",
                    status, status != PRO_TK_NO_ERROR);
    }
       
    if (status == PRO_TK_NO_ERROR) 
    {
    status = ProSimprepdataDefltGet(data, &def_action);
    TEST_CALL_REPORT("ProSimprepdataDefltGet()", "ProTestSRepVisitInfo()",
                    status, status != PRO_TK_NO_ERROR);
    }    

    ProWstringToString(name, wname);

    if (status == PRO_TK_NO_ERROR)
    {
    switch (def_action)
    {
    case PRO_SIMPREP_INCLUDE:
        ProTKSprintf (str, "Include");
        break;
    case PRO_SIMPREP_EXCLUDE:
        ProTKSprintf (str, "Exclude");
        break;
    case PRO_SIMPREP_GEOM:
        ProTKSprintf (str, "Geometry");
        break;
    case PRO_SIMPREP_GRAPHICS:
        ProTKSprintf (str, "Graphics");
        break;
    case PRO_SIMPREP_SUBSTITUTE:
 	ProTKSprintf (str, "Substitute");
	break;
    default:
        ProTKSprintf (str, "unknown");
        break;
    }
    ProTKFprintf(fp, "%s - %s components as default rule\n", 
        name, str);
    ProTKFprintf(fp, "Item info:\n");
       fflush(fp);
           
    status = ProTestSRepItemInfo ( simp_rep, fp );
    }    

    return status ;
}


/*====================================================================*\
FUNCTION : ProTestSRepItemInfo 
PURPOSE  : Print out information about each simp rep 
\*====================================================================*/
ProError ProTestSRepItemInfo(
    ProSimprep *simp_rep,
    FILE *fp)
{
    ProSimprepdata *data;
    char name[PRO_PATH_SIZE];
    char filename[] = "srep_info.inf";
    wchar_t wfilename[PRO_LINE_SIZE];
    ProError status;
    SolidFpData sfp_data;
    int num = 0, local_file = 0;
    ProInfoWindowLocation   win_location = { 0.0, 0.0 };
    ProInfoWindowSize	    win_size = { 25, 80 };
    char str[30];
    ProSimprepitem    *simprepitems;
    int simprepitems_num, i;
    
    if (fp == NULL)
    {
        if ( (fp = PTApplsUnicodeFopen(filename,"w")) == NULL)
        {
            ProTKFprintf(stderr,"Error opening file for writing\n");
            return PRO_TK_GENERAL_ERROR;
        }

        local_file = 1;
    }

    status = ProSimprepdataGet(simp_rep, &data);
    TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRepItemInfo()",
        status, status != PRO_TK_NO_ERROR);

    if (status == PRO_TK_NO_ERROR && data != NULL)
    {
        status = ProArraySizeGet((ProArray)(data->items),&num);
        TEST_CALL_REPORT("ProArraySizeGet()", "ProTestSRepItemInfo()",
                    status, status != PRO_TK_NO_ERROR);
        switch (data->deflt)
        {
        case PRO_SIMPREP_INCLUDE:
            ProTKSprintf (str, "Include");
            break;
        case PRO_SIMPREP_EXCLUDE:
            ProTKSprintf (str, "Exclude");
            break;
        case PRO_SIMPREP_GEOM:
            ProTKSprintf (str, "Geometry");
            break;
        case PRO_SIMPREP_GRAPHICS:
            ProTKSprintf (str, "Graphics");
            break;
        case PRO_SIMPREP_SUBSTITUTE:
            ProTKSprintf (str, "Substitute");
            break;
        default:
            ProTKSprintf (str, "unknown");
            break;
        }
        ProTKFprintf(fp, "Name      : %s\nTemp      : %s\nDef rule  : %s\nItem cnt  : %d\n", 
                 ProWstringToString(name, data->name),
                 data->temp == PRO_B_TRUE ? "True" : "False",
                 str, num);


        sfp_data.solid = (ProSolid *)&(simp_rep->owner);
        sfp_data.fp    = fp; 

        status = ProUtilCollectSimprepsdataitems (data, &simprepitems);
        if (status == PRO_TK_NO_ERROR)
        {
            status = ProArraySizeGet ((ProArray)simprepitems, &simprepitems_num);
            TEST_CALL_REPORT( "ProArraySizeGet()", "ProTestSRepItemInfo()", 
            status, status != PRO_TK_NO_ERROR );
            for (i = 0; i < simprepitems_num; i++)
            {
                status = ProTestSRepItemsVisit (simprepitems+i,
     	            PRO_TK_NO_ERROR,( SolidFpData*) &sfp_data);
            }
            status = ProArrayFree ((ProArray*)&simprepitems);
            TEST_CALL_REPORT( "ProArrayFree()", "ProTestSRepItemInfo()", 
                status, status != PRO_TK_NO_ERROR );
        }
    }

    if (local_file == 1)
    {
        fclose(fp);
        status = ProInfoWindowDisplay( ProStringToWstring(wfilename, filename),
            &win_location, &win_size );
        TEST_CALL_REPORT( "ProInfoWindowDisplay()", "ProTestSRepItemInfo()",
			status, status != PRO_TK_NO_ERROR);
    }
    else
    {
        fflush(fp);
    }

    if (data) 
    {
        status = ProSimprepdataFree(&data);
        TEST_CALL_REPORT("ProSimprepdataFree()", "ProTestSRepItemInfo()",
            status, status != PRO_TK_NO_ERROR);
    } 

    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProTestSRepItemsVisit
PURPOSE  : Print out info about each item visited
\*====================================================================*/
ProError ProTestSRepItemsVisit (
    ProSimprepitem *item,
    ProError          err,
    SolidFpData    *fp_data )
{
    wchar_t wname[PRO_MDLNAME_SIZE];
    char     name[PRO_MDLNAME_SIZE];
    ProAsmcomppath comp_path;
    ProMdl    model;
    ProFeature feature;
    ProFeattype type;
    ProBoolean is_visibile;
    ProError status;

    if ( item->item_path.path_size == PRO_VALUE_UNUSED )
    {
/*--------------------------------------------------------------------*\
    Feature simp rep
\*--------------------------------------------------------------------*/
        status = ProFeatureInit(*(fp_data->solid), item->item_path.feat_id, &feature);
    TEST_CALL_REPORT("ProFeatureInit()", "ProTestSRepItemsVisit()",
                status, status != PRO_TK_NO_ERROR);
    status = ProFeatureTypeGet(&feature, &type);
    
    ProTKFprintf(fp_data->fp, "Item type : %d\n", type);    
    }
    else
    {
/*--------------------------------------------------------------------*\
    Assembly simp rep
\*--------------------------------------------------------------------*/
    status = ProAsmcomppathInit(*(fp_data->solid), item->item_path.comp_path,
                item->item_path.path_size, &comp_path);
    TEST_CALL_REPORT("ProAsmcomppathInit()", "ProTestSRepItemsVisit()",
                status, status != PRO_TK_NO_ERROR);
    
    status = ProAsmcomppathMdlGet(&comp_path, &model);
    TEST_CALL_REPORT("ProAsmcomppathMdlGet()", "ProTestSRepItemsVisit()",
                status, status != PRO_TK_NO_ERROR);

    status = ProMdlMdlnameGet(model, wname);

    ProTKFprintf(fp_data->fp,"Item name : %s\n", ProWstringToString(name, wname));    

    is_visibile = PRO_B_TRUE;
    status = ProAsmcompVisibilityGet( &comp_path, NULL, &is_visibile );
    TEST_CALL_REPORT("ProAsmcompVisibilityGet()", "ProTestSRepItemsVisit()",
                status, status != PRO_TK_NO_ERROR &&
                status != PRO_TK_BAD_CONTEXT);
    if( status == PRO_TK_NO_ERROR )
	ProTKFprintf( fp_data->fp,"Item visibility : %s\n", 
		   is_visibile == PRO_B_TRUE ? "Visible" : "Invisible" );
    }
    return PRO_TK_NO_ERROR;
}

/*====================================================================*\
FUNCTION : ProTestSRepDefRule
PURPOSE  : Menu for default create rule
\*====================================================================*/
int ProTestSRepDefRule(ProSolid *p_solid)
{
    ProError		status;
    int			menu_id;    /* The identifier of the created menu */
    int			menu_action;
    ProType		type;
    SimpRepData		rep;
    wchar_t wmessage[PRO_NAME_SIZE];

/*  Get rep name */
    status = ProTestSRepNewNameGet(wmessage);
    ProUtilWstrcpy(rep.name, wmessage);
    rep.owner = p_solid;
    
    status = ProMdlTypeGet (*p_solid, (ProMdlType*)&type);
    ProMenuPush ();
    if (type == PRO_ASSEMBLY)
    {
        status = ProMenuFileRegister((char *) "ASM DFLT RULE", (char *)"tkasrdefr.mnu", &menu_id );
        TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSRepDefRule()", 
			status, status != PRO_TK_NO_ERROR );

	ProMenubuttonActionSet((char *)"ASM DFLT RULE",(char *)"Include Comp",
		(ProMenubuttonAction)ProTestSRepCreate,&rep,CREATE_REP_IN);
        ProMenubuttonActionSet((char *)"ASM DFLT RULE",(char *)"Exclude Comp",
		(ProMenubuttonAction)ProTestSRepCreate,&rep,CREATE_REP_EX);
        ProMenubuttonActionSet((char *)"ASM DFLT RULE",(char *)"Graphics Rep",
		(ProMenubuttonAction)ProTestSRepCreate,&rep,CREATE_REP_GRAPH);
        ProMenubuttonActionSet((char *)"ASM DFLT RULE",(char *)"Geometry Rep",
  		(ProMenubuttonAction)ProTestSRepCreate,&rep,CREATE_REP_GEOM);
/*        ProMenubuttonActionSet((char *)"ASM DFLT RULE",(char *)"Done",
  		(ProMenubuttonAction)ProMenuDelete,NULL,0);*/
        ProMenubuttonActionSet((char *)"ASM DFLT RULE",(char *)"ASM DFLT RULE",
		(ProMenubuttonAction)ProMenuDelete,NULL,0);

        status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"ASM DFLT RULE", &menu_id );
        TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSRepDefRule()", 
			status, status != PRO_TK_NO_ERROR );
        if( status == PRO_TK_NO_ERROR )
        {
	    status = ProMenuProcess( (char *)"DFLT RULE", &menu_action );
            TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSRepDefRule()", 
			    status, status != PRO_TK_NO_ERROR );
        }
    }
    else if (type == PRO_PART)
    {
        status = ProMenuFileRegister( (char *)"PART DFLT RULE", (char *)"tkpsrdefr.mnu", &menu_id );
        TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSRepDefRule()", 
			status, status != PRO_TK_NO_ERROR );
        ProMenubuttonActionSet((char *)"PART DFLT RULE",(char *)"Include Feat",
		(ProMenubuttonAction)ProTestSRepCreate,&rep,CREATE_REP_IN);
        ProMenubuttonActionSet((char *)"PART DFLT RULE",(char *)"Exclude Feat",
		(ProMenubuttonAction)ProTestSRepCreate,&rep,CREATE_REP_EX);
/*        ProMenubuttonActionSet((char *)"PART DFLT RULE",(char *)"Done",
  		(ProMenubuttonAction)ProMenuDelete,NULL,0);*/
        ProMenubuttonActionSet((char *)"PART DFLT RULE",(char *)"PART DFLT RULE",
		(ProMenubuttonAction)ProMenuDelete,NULL,0);

        status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"PART DFLT RULE", &menu_id );
        TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSRepDefRule()", 
			status, status != PRO_TK_NO_ERROR );
        if( status == PRO_TK_NO_ERROR )
        {
	    status = ProMenuProcess( (char *)"PART DFLT RULE", &menu_action );
            TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSRepDefRule()", 
			    status, status != PRO_TK_NO_ERROR );
        }
    }
    ProMenuPop ();
    return 0;
}

/*====================================================================*\
FUNCTION : ProTestSRepEdit
PURPOSE  : Edit rep menu
\*====================================================================*/
int ProTestSRepEdit(SimpRepData *sr_data, SimpRepActions action)
{ 
    ProError status;
    int menu_id;    /* The identifier of the created menu */
    int menu_action;
    ProMdl *owner = (ProMdl*)sr_data->owner;
    ProMdlType type;
    ProSimprepActionType action_type, action_type_for_vis;
    
    ProMdlTypeGet (*owner, &type);
/*--------------------------------------------------------------------*\
    Create menu
\*--------------------------------------------------------------------*/
    ProMenuPush ();
    if (type == PRO_MDL_ASSEMBLY)
    {
        status = ProMenuFileRegister( (char *)"ASM EDIT REPRS",(char *) "tkasreped.mnu", &menu_id );
        TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSRepEdit()", 
			status, status != PRO_TK_NO_ERROR );
	ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Include",
		(ProMenubuttonAction)ProTestSRepAction, sr_data,CREATE_REP_IN);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Exclude",
		(ProMenubuttonAction)ProTestSRepAction, sr_data,CREATE_REP_EX);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Graphics Rep",
		(ProMenubuttonAction)ProTestSRepAction, sr_data,CREATE_REP_GRAPH);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Geometry Rep",
  		(ProMenubuttonAction)ProTestSRepAction, sr_data,CREATE_REP_GEOM);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Substitute",
  		(ProMenubuttonAction)ProTestSRepAction, sr_data,SUBSTITUTE);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Default",
  		(ProMenubuttonAction)ProTestSRepAction, sr_data,DEFAULT);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"Done",
  		(ProMenubuttonAction)ProMenuDelete,NULL,0);
        ProMenubuttonActionSet((char *)"ASM EDIT REPRS",(char *)"ASM EDIT REPRS",
		(ProMenubuttonAction)ProMenuDelete,NULL,0);
    }
    else if (type == PRO_MDL_PART)
    {
        status = ProMenuFileRegister((char *) "PART EDIT REPRS", (char *)"tkpsreped.mnu", &menu_id );
        TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSRepEdit()", 
			status, status != PRO_TK_NO_ERROR );
        ProMenubuttonActionSet((char *)"PART EDIT REPRS",(char *)"Include",
		(ProMenubuttonAction)ProTestSRepAction, sr_data,CREATE_REP_IN);
        ProMenubuttonActionSet((char *)"PART EDIT REPRS",(char *)"Exclude",
		(ProMenubuttonAction)ProTestSRepAction, sr_data,CREATE_REP_EX);
        ProMenubuttonActionSet((char *)"PART EDIT REPRS",(char *)"Default",
		(ProMenubuttonAction)ProTestSRepAction, sr_data,DEFAULT);
        ProMenubuttonActionSet((char *)"PART EDIT REPRS",(char *)"Done",
  		(ProMenubuttonAction)ProMenuDelete,NULL,0);
        ProMenubuttonActionSet((char *)"PART EDIT REPRS",(char *)"PART EDIT REPRS",
		(ProMenubuttonAction)ProMenuDelete,NULL,0);
    }    
    rule_default = action;
/*--------------------------------------------------------------------*\
    Check whether rep is new or exisiting and find default rule
\*--------------------------------------------------------------------*/
    switch (action)
    {
    case CREATE_REP_IN:
        action_type_for_vis = action_type = PRO_SIMPREP_INCLUDE;
        break;
    case CREATE_REP_EX:
        action_type_for_vis = action_type = PRO_SIMPREP_EXCLUDE;
        break;
    case CREATE_REP_GEOM:
        action_type = PRO_SIMPREP_INCLUDE;
        action_type_for_vis = PRO_SIMPREP_GEOM;
        break;
    case CREATE_REP_GRAPH:
        action_type = PRO_SIMPREP_INCLUDE;
        action_type_for_vis = PRO_SIMPREP_GRAPHICS;
        break;
    }
    if (action == CREATE_REP_IN ||
       action == CREATE_REP_EX ||
       action == CREATE_REP_GEOM ||
       action == CREATE_REP_GRAPH)
    {
        status = ProSimprepdataAlloc(sr_data->name, PRO_B_FALSE, 
                    action_type, &(sr_data->data));
        TEST_CALL_REPORT("ProSimprepdataAlloc()", "ProTestSRepEdit()",
                     status, status != PRO_TK_NO_ERROR);
        ProTestSRepVisActionSet(action_type_for_vis); 
    }
    else
    {
        status = ProSimprepdataGet(&(sr_data->simp_rep), &(sr_data->data));
        TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRepEdit()",
                     status, status != PRO_TK_NO_ERROR);
        ProTestSRepVisActionSet(sr_data->data->deflt);
    }
    if (type == PRO_MDL_ASSEMBLY)
    {
        status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"ASM EDIT REPRS", &menu_id );
        TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSRepEdit()", 
			status, status != PRO_TK_NO_ERROR );
        if( status == PRO_TK_NO_ERROR )
        {
            status = ProMenuProcess( (char *)"ASM EDIT REPRS", &menu_action );
            TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSRepEdit()", 
 			    status, status != PRO_TK_NO_ERROR );
        }
    }
    else
    {
        status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"PART EDIT REPRS", &menu_id );
        TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSRepEdit()", 
			status, status != PRO_TK_NO_ERROR );
        if( status == PRO_TK_NO_ERROR )
        {
            status = ProMenuProcess((char *) "PART EDIT REPRS", &menu_action );
            TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSRepEdit()", 
 			    status, status != PRO_TK_NO_ERROR );
        }
    }
    ProMenuPop ();
    return(0);
}

/*====================================================================*\
FUNCTION : ProTestSRepAction
PURPOSE  : General action function
\*====================================================================*/
int ProTestSRepAction(
    SimpRepData *sr_data, 
    SimpRepActions action)
{
    ProError status = PRO_TK_NO_ERROR;

    switch (action)
    {
    case DEFAULT:
        action = rule_default;
        break;
    case CREATE_REP_IN:
    case CREATE_REP_EX:
    case CREATE_REP_GEOM:
    case CREATE_REP_GRAPH:
    case SUBSTITUTE:
        status = ProTestSRepCreateNew(sr_data, action);
        break;
    case REDEFINE_REP: 
        status = (ProError)ProTestSRepRedefineMenu(sr_data, action);
        break;
    }

    return status;
}

/*====================================================================*\
FUNCTION : ProTestSRepCreateNew
PURPOSE  : Create a new simp rep
\*====================================================================*/
ProError ProTestSRepCreateNew(
    SimpRepData *sr_data,
    SimpRepActions action)
{
    ProType type;
    ProSelection *sels;
    int num, i;
    ProError status;
    ProSimprepAction sr_act;
    ProSubstitution subst;
    ProSimprepitem item;
    ProMdlExtension mdl_ext;
    ProAsmcomppath comp_path;
    ProModelitem sel_obj;
    char name[10], option[40];
    ProSimprepActionType act_type;

    ProModelitem sel0_obj;
    ProMdl sel_mdl;

/*--------------------------------------------------------------------*\
    Find current owner type
\*--------------------------------------------------------------------*/
    status = ProMdlExtensionGet(*(sr_data->owner), mdl_ext);
    TEST_CALL_REPORT("ProMdlExtensionGet()", "ProTestSRepCreateNew()",
                    status, status != PRO_TK_NO_ERROR);

    ProWstringToString (name, mdl_ext);

    if(  strcmp ( name, "ASM") == 0 )
    {
        type = PRO_PART;
        ProUtilstrcpy(option, "prt_or_asm");
    }
    else
    {
        type = PRO_FEATURE;
        ProUtilstrcpy(option, "feature");
    }
    switch (action)
    {
    case CREATE_REP_EX:
        act_type = PRO_SIMPREP_EXCLUDE;
        break;
    case CREATE_REP_IN:
        act_type = PRO_SIMPREP_INCLUDE;
        break;
    case CREATE_REP_GEOM:
        act_type = PRO_SIMPREP_GEOM;
        break;
    case CREATE_REP_GRAPH:
        act_type = PRO_SIMPREP_GRAPHICS;
        break;
    case SUBSTITUTE:
        act_type = PRO_SIMPREP_SUBSTITUTE;
        break;
    }
    
    ProUtilMsgPrint("gen","TEST %0s", 
        "Select model(s) (feature) to include");
	
    status = ProTestSelectModelMenu( option, &sels, &num );

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

    status = ProSelectionModelitemGet(sels[0], &sel0_obj);
    TEST_CALL_REPORT("ProSelectionModelitemGet", "ProTestSRepCreateNew()",  
                          status, status != PRO_TK_NO_ERROR);  

    status = ProModelitemMdlGet(&sel0_obj, &sel_mdl);  
    TEST_CALL_REPORT("ProModelitemMdlGet", "ProTestSRepCreateNew()",  
                          status, status != PRO_TK_NO_ERROR);  

    if (act_type == PRO_SIMPREP_SUBSTITUTE)
    {
       status = ProTestSubstitutionInit( (ProSolid*)&sel_mdl, &subst );
        
        if( status == PRO_TK_NO_ERROR )
        {
	    status = ProSimprepActionInit( act_type, &subst, 
		&sr_act );
            TEST_CALL_REPORT("ProSimprepActionInit()", "ProTestSRepCreateNew()",
                          status, status != PRO_TK_NO_ERROR);
        }
    }
    else
    {
        status = ProSimprepActionInit( act_type, NULL, &sr_act);
        TEST_CALL_REPORT("ProSimprepActionInit()", "ProTestSRepCreateNew()",
                          status, status != PRO_TK_NO_ERROR);
    }

    if (status == PRO_TK_NO_ERROR && num >= 1)
    {
        for (i = 0; i < num; i++)
        {
            ProSelectionAsmcomppathGet(sels[i], &comp_path);
            TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", 
                "ProTestSRepCreateNew()",
                status, status != PRO_TK_NO_ERROR);

            ProSelectionModelitemGet(sels[i], &sel_obj);
            TEST_CALL_REPORT("ProSelectionModelitemGet()", 
		"ProTestSRepCreateNew()",
                status, status != PRO_TK_NO_ERROR);

            status = ProSimprepdataitemInit( comp_path.comp_id_table,
		type == PRO_PART ? comp_path.table_num : PRO_VALUE_UNUSED, 
                        sel_obj.id, &sr_act, &item);
            TEST_CALL_REPORT("ProSimprepdataitemInit()", 
		"ProTestSRepCreateNew()",
                status, status != PRO_TK_NO_ERROR);
                        
            status = ProSimprepdataitemAdd(sr_data->data, &item);
            TEST_CALL_REPORT("ProSimprepdataitemAdd()", 
 		"ProTestSRepCreateNew()",
                status, status != PRO_TK_NO_ERROR);

            if (status == PRO_TK_NO_ERROR)
                sr_data->item_count++;
        }
    }
    return(status);
}

/*====================================================================*\
FUNCTION : ProTestSRepRedefineMenu
PURPOSE  : Redefine existing rep
\*====================================================================*/
int ProTestSRepRedefineMenu(
    SimpRepData *sr_data,
    SimpRepActions action )
{
    ProError status = PRO_TK_NO_ERROR;
    ProBoolean is_temp;
    int			menu_id;    /* The identifier of the created menu */
    int			menu_action;


    status = ProTestSRep2ColorDisplay(sr_data);
    status = ProSimprepdataGet(&(sr_data->simp_rep), &(sr_data->data));
    TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRepRedefineMenu()",
                    status, status != PRO_TK_NO_ERROR);
      
    status = ProMenuFileRegister( (char *)"REDEFINE SR", (char *)"tksrredef.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSRepRedefineMenu()", 
			status, status != PRO_TK_NO_ERROR );

    ProMenubuttonActionSet((char *)"REDEFINE SR",(char *)"Rename",
		(ProMenubuttonAction)ProTestSRepRedefine, sr_data,RENAME);
    ProMenubuttonActionSet((char *)"REDEFINE SR",(char *)"Make perm",
		(ProMenubuttonAction)ProTestSRepRedefine, sr_data, MAKE_PERM);
    ProMenubuttonActionSet((char *)"REDEFINE SR",(char *)"Def rule",
		(ProMenubuttonAction)ProTestSRepRedefine, sr_data,DEF_RULE);
    ProMenubuttonActionSet((char *)"REDEFINE SR", (char *)"Add item", 
		(ProMenubuttonAction)ProTestSRepRedefine, sr_data, ADD_ITEM);
    ProMenubuttonActionSet((char *)"REDEFINE SR",(char *)"Del item",
		(ProMenubuttonAction)ProTestSRepRedefine, sr_data, DEL_ITEM);
    ProMenubuttonActionSet((char *)"REDEFINE SR",(char *)"REDEFINE SR", 
		(ProMenubuttonAction)ProMenuDelete,NULL,0);

    status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"REDEFINE SR", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSRepRedefine()", 
			status, status != PRO_TK_NO_ERROR );

    status = ProSimprepdataTmpvalGet(sr_data->data, &is_temp);
    TEST_CALL_REPORT("ProSimprepdataTmpvalGet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);
    if ( is_temp == PRO_B_FALSE )
    {
	status = ProMenubuttonDeactivate( (char *)"REDEFINE SR", (char *)"Make perm" );
	TEST_CALL_REPORT( "ProMenubuttonDeactivate()", "ProTestSRepRedefine()", 
			    status, status != PRO_TK_NO_ERROR );
    }
    else 
    {
	status = ProMenubuttonActivate((char *) "REDEFINE SR", (char *)"Make perm" );
	TEST_CALL_REPORT( "ProMenubuttonDeactivate()", "ProTestSRepRedefine()", 
			    status, status != PRO_TK_NO_ERROR );
    }

    status = ProMenuProcess((char *) "REDEFINE SR", &menu_action );
    TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSRepRedefine()", 
			status, status != PRO_TK_NO_ERROR );


    return 0;
}

/*====================================================================*\
FUNCTION : ProTestSRepRedefine
PURPOSE  : Define all redefine actions
\*====================================================================*/
int ProTestSRepRedefine (
    SimpRepData *sr_data, 
    SimpRepActions action )
{
    ProError status;
    wchar_t wname[PRO_LINE_SIZE];
    char name[10], option[40];
    ProSimprepActionType def_act;
    ProSimprepdata *data;
    ProSimprepitem item;
    ProSimprepAction sr_act ;
    ProSelection *sels;
    ProAsmcomppath comp_path;
    ProModelitem sel_obj;
    ProMdlExtension mdl_ext;
    int     num, i;
    ProType type;
    char str[30];

/*--------------------------------------------------------------------*\
    Find current owner type
\*--------------------------------------------------------------------*/
    status = ProMdlExtensionGet(*(sr_data->owner), mdl_ext);
    TEST_CALL_REPORT("ProMdlExtensionGet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);

    ProWstringToString (name, mdl_ext);

    if(  strcmp ( name, "ASM") == 0 )
    {
        type = PRO_PART;
        ProUtilstrcpy(option, "prt_or_asm");  
    }
    else
    {
        type = PRO_FEATURE;
        ProUtilstrcpy(option, "feature");
    }


/*--------------------------------------------------------------------*\
    Get Simp reps data
\*--------------------------------------------------------------------*/
    status = ProSimprepdataGet(&(sr_data->simp_rep), &data);
    TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);

    status = ProSimprepdataDefltGet(data, &def_act);
    TEST_CALL_REPORT("ProSimprepdataDefltGet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);

    switch (action)
    {
    case RENAME:
        status = ProTestSRepNewNameGet(wname);
        status = ProSimprepdataNameSet(data, wname);
        TEST_CALL_REPORT("ProSimprepdataNameSet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);
        if (status != PRO_TK_NO_ERROR)
            return status;
        status = ProSimprepdataSet(&(sr_data->simp_rep), data); 
        TEST_CALL_REPORT("ProSimprepdataSet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);
        ProMenuDelete();
        break;
        
    case MAKE_PERM:
        status = ProSimprepdataTmpvalSet(data, PRO_B_FALSE);
        TEST_CALL_REPORT("ProSimprepdataTmpvalSet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);
        if (status != PRO_TK_NO_ERROR)
        return status;
        status = ProSimprepdataSet(&(sr_data->simp_rep), data); 
        TEST_CALL_REPORT("ProSimprepdataSet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);
        ProMenuDelete();
        break;
    case DEF_RULE:
        status = ProSimprepdataDefltSet (data, PRO_SIMPREP_REVERSE);
        TEST_CALL_REPORT("ProSimprepdataDefltSet()", 
        "ProTestSRepRedefine()", status, status != PRO_TK_NO_ERROR);
        
        status = ProSimprepdataSet(&(sr_data->simp_rep), data); 
        TEST_CALL_REPORT("ProSimprepdataSet()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);
        ProMenuDelete();
        break;

    case ADD_ITEM:
	status = ProTestSelectModelMenu( option, &sels, &num );
	if( status != PRO_TK_NO_ERROR )
	    break;
        switch (def_act)
        {
        case PRO_SIMPREP_INCLUDE:
            ProTKSprintf (str, "Include");
            break;
        case PRO_SIMPREP_EXCLUDE:
            ProTKSprintf (str, "Exclude");
            break;
        case PRO_SIMPREP_GEOM:
            ProTKSprintf (str, "Geometry");
            break;
        case PRO_SIMPREP_GRAPHICS:
            ProTKSprintf (str, "Graphics");
            break;
        case PRO_SIMPREP_SUBSTITUTE:
            ProTKSprintf (str, "Substitute");
            break;
        default:
            ProTKSprintf (str, "unknown");
            break;
        }
        status = ProSimprepActionInit( def_act , 
                    NULL, &sr_act);
        TEST_CALL_REPORT("ProSimprepActionInit()", "ProTestSRepRedefine()",
                          status, status != PRO_TK_NO_ERROR);

        for (i = 0; i < num; i++)
        {
	    ProSelectionAsmcomppathGet(sels[i], &comp_path);
            TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", 
		"ProTestSRepRedefine()",
                status, status != PRO_TK_NO_ERROR);

            ProSelectionModelitemGet(sels[i], &sel_obj);
            TEST_CALL_REPORT("ProSelectionModelitemGet()", 
		"ProTestSRepRedefine()",
                status, status != PRO_TK_NO_ERROR);

 	    status = ProSimprepdataitemInit(comp_path.comp_id_table,
		type == PRO_PART ? comp_path.table_num : PRO_TK_NOT_USED, 
                sel_obj.id, &sr_act, &item);
	    TEST_CALL_REPORT("ProSimprepdataitemInit()", "ProTestSRepItem()", 
           	status, status != PRO_TK_NO_ERROR);
                        
	    status = ProSimprepdataitemAdd(data, &item);
	    TEST_CALL_REPORT("ProSimprepdataitemAdd()", "ProTestSRepItem()",
       		status, status != PRO_TK_NO_ERROR);
        }
        /* bug in the function ProSimprepdataitemAdd */
        status = ProSimprepdataSet(&(sr_data->simp_rep), data); 
        TEST_CALL_REPORT("ProSimprepdataSet()", "ProTestSRepRedefine()",
                          status, 0);
        ProMenuDelete();

        break;

    case DEL_ITEM:
	status = ProTestSelectModelMenu( option, &sels, &num );
	if( status != PRO_TK_NO_ERROR )
	    break;

        status = ProSimprepActionInit( def_act,
                    NULL, &sr_act);
        TEST_CALL_REPORT("ProSimprepActionInit()", "ProTestSRepRedefine()",
                          status, status != PRO_TK_NO_ERROR);

        for (i = 0; i < num; i++)
        {
            status = ProSelectionAsmcomppathGet(sels[i], &comp_path);
            TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", 
		"ProTestSRepRedefine()",
                status, status != PRO_TK_NO_ERROR);

            status = ProSelectionModelitemGet(sels[i], &sel_obj);
            TEST_CALL_REPORT("ProSelectionModelitemGet()", 
		"ProTestSRepRedefine()",
                status, status != PRO_TK_NO_ERROR);

	    status = ProSimprepdataitemInit(comp_path.comp_id_table,
		type == PRO_PART ? comp_path.table_num : PRO_TK_NOT_USED, 
                sel_obj.id, &sr_act, &item);
	    TEST_CALL_REPORT("ProSimprepdataitemInit()", 
		"ProTestSRepRedefine()", 
                status, status != PRO_TK_NO_ERROR);
		
	    item.action.type = PRO_SIMPREP_NONE;
	    
	    status = ProSimprepdataitemDelete (data, &item);
	    TEST_CALL_REPORT("ProSimprepdataitemDelete()", 
		"ProTestSRepItem()", status,
		( status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND));
        }
        /* bug in function ProSimprepdataitemDelete */
        status = ProSimprepdataSet(&(sr_data->simp_rep), data); 
        TEST_CALL_REPORT("ProSimprepdataSet()", "ProTestSRepRedefine()",
                    status, 0);
        ProMenuDelete();

        break;

    default:
        ProTKFprintf(stderr, "Error - fall through redefine!\n");
    }

    status = ProSimprepdataFree(&data);
    TEST_CALL_REPORT("ProSimprepdataFree()", "ProTestSRepRedefine()",
                    status, status != PRO_TK_NO_ERROR);

    return 0;
}

/*====================================================================*\
FUNCTION : ProTestSRepCopy
PURPOSE  : Copies an exisiting simplified rep
\*====================================================================*/
ProError ProTestSRepCopy(
    ProSimprep* simp_rep)
{
     
    ProSimprepdata *data;
    wchar_t wname[PRO_LINE_SIZE];
    ProError status;
    ProSimprep new_rep;

    status = ProTestSRepNewNameGet(wname);

    status = ProSimprepdataGet(simp_rep, &data);
    TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRepCopy()",
                    status, status != PRO_TK_NO_ERROR);

    if (status != PRO_TK_NO_ERROR)
    return status;
 
    status = ProSimprepdataNameSet(data, wname);
    TEST_CALL_REPORT("ProSimprepdataNameSet()", "ProTestSRepCopy()",
                    status, status != PRO_TK_NO_ERROR);
    if (status != PRO_TK_NO_ERROR)
    return status;

    status = ProSimprepCreate((ProSolid) simp_rep->owner,  data, &new_rep);
    TEST_CALL_REPORT("ProSimprepCreate()", "ProTestSRepCopy()",
                    status, status != PRO_TK_NO_ERROR);

    if (status != PRO_TK_NO_ERROR)
    return status;

    status = ProSimprepdataFree(&data);
    TEST_CALL_REPORT("ProSimprepdataFree()", "ProTestSRepCopy()",
                    status, status != PRO_TK_NO_ERROR);

    status = ProSimprepActivate((ProSolid)simp_rep->owner, &new_rep);
    TEST_CALL_REPORT("ProSimprepActivate()", "ProTestSRepCopy()",
                    status, status != PRO_TK_NO_ERROR);

    ProTestSRepRepaint((ProSolid *)&(simp_rep->owner));

    return status;
}

/*====================================================================*\
FUNCTION : ProTestSRep2ColorDisplay
PURPOSE  : 
\*====================================================================*/
ProError ProTestSRep2ColorDisplay(SimpRepData *sr_data)
{
    ProError status;
    ProModelitem mdl_item;
    ProSelection selection;
    ProAsmcomppath comp_path;
    ProSimprepdata *data;
    ProSimprep simp_rep;
    ItemColorData color_data;
    ProType model_type;
    int model_id = PRO_VALUE_UNUSED ;
    ProSimprepitem    *simprepitems;
    int simprepitems_num, i;


/*--------------------------------------------------------------------*\
    Display generic model/assembly
\*--------------------------------------------------------------------*/
    memcpy ( &simp_rep, &(sr_data->simp_rep), sizeof(ProSimprep));
    simp_rep.id = PRO_TK_NOT_USED;

    status = ProSimprepActivate(*(sr_data->owner), &simp_rep);
    TEST_CALL_REPORT("ProSimprepActivate()", "ProTestSRep2ColorDisplay()",
                    status, status != PRO_TK_NO_ERROR);

    status = ProSolidDisplay(*(sr_data->owner));
    TEST_CALL_REPORT("ProSolidDisplay()", "ProTestSRep2ColorDisplay()",
                    status, status != PRO_TK_NO_ERROR &&
                    status != PRO_TK_E_FOUND);

/*--------------------------------------------------------------------*\
    Set active assembly back to one we are editing
\*--------------------------------------------------------------------*/
    status = ProSimprepActivate(*(sr_data->owner), &(sr_data->simp_rep));
    TEST_CALL_REPORT("ProSimprepActivate()", "ProTestSRep2ColorDisplay()",
                                    status, status != PRO_TK_NO_ERROR);
 
/*--------------------------------------------------------------------*\
    Parts and assemblies need to be handled differently
\*--------------------------------------------------------------------*/
    memset(&comp_path, -1, sizeof(ProAsmcomppath));

    status = ProMdlTypeGet(sr_data->simp_rep.owner, (ProMdlType *)&model_type);
    TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestSRep2ColorDisplay()",
                                    status, status != PRO_TK_NO_ERROR);
    if (model_type == PRO_ASSEMBLY)
    {
		comp_path.table_num = 0;
		ProMdlIdGet(sr_data->simp_rep.owner, &model_id);
		comp_path.owner = (ProSolid)(sr_data->simp_rep.owner);
    }
    
    status = ProModelitemInit(sr_data->simp_rep.owner, model_id, 
				    (ProType)model_type, &mdl_item);
    TEST_CALL_REPORT("ProModelitemInit()", "ProTestSRep2ColorDisplay()",
                      status, status != PRO_TK_NO_ERROR);

    status = ProSelectionAlloc(model_type==PRO_ASSEMBLY?&comp_path:NULL,
        &mdl_item, &selection);
    TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestSRep2ColorDisplay()",
				    status, status != PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Highlight entire model
\*--------------------------------------------------------------------*/
    status = ProSelectionHighlight(selection, PRO_COLOR_ERROR);
    TEST_CALL_REPORT("ProSelectionHighlight()", "ProTestSRep2ColorDisplay()",
                      status, status != PRO_TK_NO_ERROR);

    status = ProSimprepdataGet(&(sr_data->simp_rep), &data);
    TEST_CALL_REPORT("ProSimprepdataGet()", "ProTestSRep2ColorDisplay()",
                      status, status != PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Highlight those data items in simp rep in WARNING color
\*--------------------------------------------------------------------*/
    color_data.owner = &(sr_data->simp_rep);
    color_data.color = PRO_COLOR_WARNING;

    status = ProUtilCollectSimprepsdataitems (data, &simprepitems);
        if (status == PRO_TK_NO_ERROR)
        {
            status = ProArraySizeGet ((ProArray)simprepitems, &simprepitems_num);
            TEST_CALL_REPORT( "ProArraySizeGet()", "ProTestSRep2ColorDisplay()", 
            status, status != PRO_TK_NO_ERROR );
            for (i = 0; i < simprepitems_num; i++)
            {
                status = ProTestSRepItemsColor (simprepitems+i,
     	            PRO_TK_NO_ERROR,( ItemColorData*)&color_data);
            }
            status = ProArrayFree ((ProArray*)&simprepitems);
            TEST_CALL_REPORT( "ProArrayFree()", "ProTestSRep2ColorDisplay()", 
                status, status != PRO_TK_NO_ERROR );
        }
    
    status = ProSimprepdataFree(&data);
    TEST_CALL_REPORT("ProSimprepdataFree()", "ProTestSRep2ColorDisplay()",
                    status, status != PRO_TK_NO_ERROR);

    return status;

}

/*====================================================================*\
FUNCTION : ProTestSRepItemsColor 
PURPOSE  : Highlight a simplified rep item
\*====================================================================*/
ProError ProTestSRepItemsColor (
    ProSimprepitem *p_item, 
    ProError err, 
    ItemColorData *color_data)
{
    ProModelitem mdl_item;
    ProMdl model;
    ProSelection p_sel_init;
    ProError status;
    ProAsmcomppath comp_path;
    ProMdlType model_type;
    int model_id;
    
    status = ProMdlTypeGet(color_data->owner->owner, &model_type);
    TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestSRepItemsColor()",
				status, status != PRO_TK_NO_ERROR);
    if ( model_type == PRO_MDL_ASSEMBLY )
    {
	status = ProAsmcomppathInit((ProSolid)color_data->owner->owner,
				p_item->item_path.comp_path,
				p_item->item_path.path_size,
				&comp_path);
	TEST_CALL_REPORT("ProAsmcomppathInit()", "ProTestSRepItemsColor()",
				status, status != PRO_TK_NO_ERROR);
    
	status = ProAsmcomppathMdlGet(&comp_path, &model);    
        
        if (status == PRO_TK_GENERAL_ERROR)
          return (PRO_TK_E_NOT_FOUND);
          
	TEST_CALL_REPORT("ProAsmcomppathMdlGet()", "ProTestSRepItemsColor()",
				    status, status != PRO_TK_NO_ERROR);

	status = ProMdlIdGet(model, &model_id);
	TEST_CALL_REPORT("ProMdlIdGet()", "ProTestSRepItemsColor()",
				    status, status != PRO_TK_NO_ERROR);

	status = ProModelitemInit (model, model_id, (ProType) model_type, &mdl_item);
	TEST_CALL_REPORT("ProModelitemInit()", "ProTestSRepItemsColor()",
					status, status != PRO_TK_NO_ERROR);
        
    }
    else
    {
	status = ProFeatureInit((ProSolid)color_data->owner->owner, 
			    p_item->item_path.feat_id, &mdl_item);
	TEST_CALL_REPORT("ProFeatureInit()", "ProTestSRepItemsColor()",
				    status, status != PRO_TK_NO_ERROR);

	status = ProAsmcomppathInit((ProSolid)color_data->owner->owner,NULL,0,&comp_path);
	TEST_CALL_REPORT("ProAsmcomppathInit()", "ProTestSRepItemsColor()",
				    status, status != PRO_TK_NO_ERROR);
    }
    
    status = ProSelectionAlloc(&comp_path, &mdl_item, &p_sel_init);
    TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestSRepItemsColor()",
				    status, status != PRO_TK_NO_ERROR);

    status = ProSelectionHighlight(p_sel_init, color_data->color );
    TEST_CALL_REPORT("ProSelectionHighlight()", "ProTestSRepItemsColor()",
                    status, status != PRO_TK_NO_ERROR);

    return PRO_TK_NO_ERROR;
}

/*====================================================================*\
FUNCTION : ProTestSRepRepaint
PURPOSE  : Re-display assembly
\*====================================================================*/
int ProTestSRepRepaint(
    ProSolid *p_solid)
{
    ProError status;

    status = ProSolidDisplay(*p_solid);
    TEST_CALL_REPORT("ProSolidDisplay()", "ProTestSRepRepaint()",
                    status, status != PRO_TK_NO_ERROR &&
                    status != PRO_TK_E_FOUND);
    return 0;
}

/*====================================================================*\
FUNCTION : ProTestSRepNewNameGet
PURPOSE  : 
\*====================================================================*/
ProError ProTestSRepNewNameGet(
    wchar_t *wmessage)
{
    wchar_t wdef[PRO_NAME_SIZE];
    char    def[PRO_NAME_SIZE], message[PRO_LINE_SIZE];    

    ProTKSprintf(def,"REP%03d",++def_num);
    ProTKSprintf(message,"Enter name of new simp rep [%s]: ", def);
    ProUtilMsgPrint("gen", "TEST %0s", message);
    ProStringToWstring(wdef,def);
    ProUtilStringGet(wmessage, wdef, PRO_NAME_SIZE);

    return PRO_TK_NO_ERROR;
}

/*====================================================================*\
FUNCTION : ProTestSRepVisActionSet
PURPOSE  : Sets the visible action button on the EDIT REP menu
\*====================================================================*/
void ProTestSRepVisActionSet (
    ProSimprepActionType action )
{
    ProMdlType type;
    ProMdl model;
    char str_type[30];
    
    ProMdlCurrentGet (&model);
    ProMdlTypeGet (model, &type);
    if (type == PRO_MDL_ASSEMBLY)
        ProTKSprintf (str_type, "ASM EDIT REPRS");
    else
        ProTKSprintf (str_type, "PART EDIT REPRS");
    switch (action)
    {
    case PRO_SIMPREP_EXCLUDE:
        ProMenubuttonVisibilitySet(str_type,(char *)"Exclude",PRO_B_FALSE);
        break;
    case PRO_SIMPREP_INCLUDE:
        ProMenubuttonVisibilitySet(str_type,(char *)"Include",PRO_B_FALSE);
        break;
    case PRO_SIMPREP_GRAPHICS:
        ProMenubuttonVisibilitySet(str_type,(char *)"Graphics Rep",PRO_B_FALSE);
        break;
    case PRO_SIMPREP_GEOM:
        ProMenubuttonVisibilitySet(str_type,(char *)"Geometry Rep",PRO_B_FALSE);
        break;
    }
}



/*====================================================================*\
FUNCTION : ProTestSubstitutionInit
PURPOSE  : Init the structure ProSubstitution.
\*====================================================================*/
ProError ProTestSubstitutionInit( ProSolid* p_solid, ProSubstitution* p_subst )
{
    ProError		status;
    int			menu_id;    /* The identifier of the created menu */
    ProSubstType	subst_type = PRO_SUBST_NONE;
    ProSimprep		simp_rep;

    /* Create menus */
    status = ProMenuFileRegister( (char *)"Subst Type", (char *)"tksubst.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSubstitutionInit()", 
			status, status != PRO_TK_NO_ERROR );

    ProMenubuttonActionSet( (char *)"Subst Type", (char *)"PRO_SUBST_PRT_REP",
	(ProMenubuttonAction)ProTestSubstTypeSet, &subst_type, PRO_SUBST_PRT_REP );
    ProMenubuttonActionSet( (char *)"Subst Type", (char *)"PRO_SUBST_ASM_REP",
	(ProMenubuttonAction)ProTestSubstTypeSet, &subst_type, PRO_SUBST_ASM_REP );
    ProMenubuttonActionSet( (char *)"Subst Type", (char *)"Done/Return", 
	(ProMenubuttonAction)ProMenuDelete, NULL, 0 );
    ProMenubuttonActionSet((char *) "Subst Type",(char *) "Subst Type", 
	(ProMenubuttonAction)ProMenuDelete, NULL, 0 );

    /* Make menu visible */
    status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"Subst Type", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSubstitutionInit()", 
			status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess((char *) "Subst Type", (int*)&subst_type );
	TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSubstitutionInit()", 
			    status, status != PRO_TK_NO_ERROR );
    }
    switch( subst_type )
    {
      case PRO_SUBST_PRT_REP:
      case PRO_SUBST_ASM_REP:
	/* Select a simp rep */
        ProUtilMsgPrint( "gen","TEST %0s",  "Select simp rep to substitute with" );

                 status = ProSimprepSelect(*p_solid, &simp_rep );
 	 TEST_CALL_REPORT( "ProSimprepSelect()", "ProTestSubstitutionInit()",
		 	    status, status != PRO_TK_NO_ERROR 
			 	    && status != PRO_TK_E_NOT_FOUND);

         if( status == PRO_TK_NO_ERROR )
         {
	     status = ProSubstitutionInit( subst_type, PRO_VALUE_UNUSED, NULL, 
	  				    &simp_rep, p_subst );
 	     TEST_CALL_REPORT( "ProSubstitutionInit()", 	"ProTestSubstitutionInit()",
			 	status, status != PRO_TK_NO_ERROR );
         }
      

        break;
    }


    return status;
}


/*====================================================================*\
FUNCTION : ProTestSubstTypeSet
PURPOSE  : On-button func. Set variable p_type to the value type.
\*====================================================================*/
int ProTestSubstTypeSet( ProSubstType* p_subst_type, ProSubstType subst_type )
{
    *p_subst_type = subst_type;
    ProMenuDeleteWithStatus (subst_type);
    return 0;
}



/*====================================================================*\
FUNCTION : ProTestSelectModel
PURPOSE  : On-button func. Select by mouse pick or by rules
\*====================================================================*/
ProError ProTestSelectModel(
    SelAppData		*p_sel_data,
    int                 mode
)
{
    switch( mode )
    {
      case SEL_BY_RULE:
	p_sel_data->status = ProSelectWithRules( p_sel_data->p_option, -1, 
		NULL, NULL, NULL, NULL, 
		&(p_sel_data->p_sel), &(p_sel_data->num) );
	break;

      default:
	p_sel_data->status = ProSelect( p_sel_data->p_option, -1, 
		NULL, NULL, NULL, NULL,
        	 &(p_sel_data->p_sel), &(p_sel_data->num) );
    }

    ProMenuDelete();


    return PRO_TK_NO_ERROR;
}



/*====================================================================*\
FUNCTION : ProTestSelectModelMenu
PURPOSE  : On-button func. SELECT MDL menu
\*====================================================================*/
ProError ProTestSelectModelMenu( 
    char		*p_option,	/* In */
    ProSelection	**p_sel,	/* Out */
    int			*p_num		/* Out */
)
{
    ProError		status;
    SelAppData		sel_data;
    int			menu_id;
    int			menu_action;


    sel_data.p_option = p_option;
    sel_data.p_sel = NULL;
    sel_data.num = 0;
    sel_data.status = PRO_TK_GENERAL_ERROR;

/*--------------------------------------------------------------------*\
    Create menus
\*--------------------------------------------------------------------*/
    status = ProMenuFileRegister( (char *)"SELECT MDL BY", (char *)"tksrsel.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestSelectModelMenu()", 
			status, status != PRO_TK_NO_ERROR );

    ProMenubuttonActionSet((char *) "SELECT MDL BY", (char *)"By Pick",
	(ProMenubuttonAction)ProTestSelectModel, &sel_data, SEL_BY_PICK );
    ProMenubuttonActionSet( (char *)"SELECT MDL BY",(char *) "By Rule",
	(ProMenubuttonAction)ProTestSelectModel, &sel_data, SEL_BY_RULE );

    ProMenubuttonActionSet((char *) "SELECT MDL BY", (char *)"SELECT MDL BY",
	(ProMenubuttonAction)ProMenuDelete, NULL, 0 );

/*--------------------------------------------------------------------*\
    Make  menu visible
\*--------------------------------------------------------------------*/
    status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"SELECT MDL BY", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestSelectModelMenu()", 
			status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess( (char *)"SELECT MDL BY", &menu_action );
	TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSelectModelMenu()", 
			    status, status != PRO_TK_NO_ERROR );
    }

    *p_sel = sel_data.p_sel;
    *p_num = sel_data.num;


    return sel_data.status;
}


#endif /* #ifndef PT_PRODUCTS_BUILD */