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


/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProLayer.h>
#include <ProMdl.h>
#include <ProMenu.h>
#include <ProMessage.h>
#include <ProModelitem.h>
#include <ProWindows.h>
#include <ProUtil.h>
#include <ProFeatType.h>

/*--------------------------------------------------------------------*\
C System includes
\*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "UtilFiles.h"
#include "UtilMatrix.h"
#include "TestMenu.h"
#include "UtilMessage.h"
#include "UtilString.h"
#include "UtilCollect.h"
#include <ProTKRunTime.h>
#include <PTApplsUnicodeUtils.h>
#include <UtilMenu.h>

/*--------------------------------------------------------------------*\
Application macros
\*--------------------------------------------------------------------*/


#define PRO_TEST_LAYER_SETUP_LAYER	1
#define PRO_TEST_LAYER_SET_ITEM		2
#define PRO_TEST_LAYER_SET_DISPLAY	3
#define PRO_TEST_LAYER_SETDEFLAYER	4
#define PRO_TEST_LAYER_INFO		5
#define PRO_TEST_LAYER_SAVE_DISP_STAT	6
#define PRO_TEST_LAYER_DEPENDENCY       7

#define PRO_TEST_LAYER_CREATE		10
#define PRO_TEST_LAYER_DELETE		11

#define PRO_TEST_ITEM_ADD		20
#define PRO_TEST_ITEM_REMOVE		21
#define PRO_TEST_ITEM_COPY		22

#define PRO_TEST_INFO_LAYER_ITEMS	30
#define PRO_TEST_INFO_DISP_STATUS	31

#define PRO_TEST_OBJ_COMP	40
#define PRO_TEST_OBJ_FEAT	41
#define PRO_TEST_OBJ_CURVE	42
#define PRO_TEST_OBJ_QUILT	43
#define PRO_TEST_OBJ_2DITEM	44
#define PRO_TEST_OBJ_TEXT	45
#define PRO_TEST_OBJ_POINT	46
#define PRO_TEST_OBJ_DTMPLN	47
#define PRO_TEST_OBJ_LAYER	48
#define PRO_TEST_OBJ_DWGTABLE	49
#define PRO_TEST_DIAGRAM 50

#define LAYER_FILE ".lrf"

#define PRO_NO_TYPE 0

typedef struct {
    ProMdl  model;
    FILE *fp;
} AppStruct;

typedef struct {
    ProDefLayerType type;
    char *name;
    } DefLayerTypes;    


static char *ProUtilLayerStatusString(ProLayerDisplay  display_status);
ProError ProUtilLayerSelect(ProMdl   model, ProLayer *layer);
void ProTestDefLayerMenu (int *type);
void ProTestDispStatusMenu (ProLayerDisplay old_status, 
    ProLayerDisplay *new_status);
ProError ProTestModelInfoMenu (ProMdlType type, ProMdl *model);

/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/
DefLayerTypes def_layer_types[] = {
    {PRO_DEFLAYER_ASSEM_MEMBER,		(char*)"ASSMMEMBER"},
    {PRO_DEFLAYER_COMP_DESIGN_MODEL,	(char*)"DESIGNMODEL"},
    {PRO_DEFLAYER_COMP_WORKPIECE,	(char*)"WORKPIECE"},
    {PRO_DEFLAYER_COMP_FIXTURE,		(char*)"FIXTURE"},
    {PRO_DEFLAYER_GEOM_FEAT,		(char*)"GEOMFEAT"},
    {PRO_DEFLAYER_NOGEOM_FEAT,		(char*)"NOGEOMFEAT"},
    {PRO_DEFLAYER_COSM_SKETCH,		(char*)"COSMSKETCH"},
    {PRO_DEFLAYER_AXIS,			(char*)"AXIS"},
    {PRO_DEFLAYER_SURFACE,		(char*)"SURFACE"},
    {PRO_DEFLAYER_DATUM,		(char*)"DATUM"},
    {PRO_DEFLAYER_POINT,		(char*)"POINT"},
    {PRO_DEFLAYER_CURVE,		(char*)"CURVE"},
    {PRO_DEFLAYER_CSYS,			(char*)"CSYS"},
    {PRO_DEFLAYER_FEATURE,		(char*)"FEATURE"},
    {PRO_DEFLAYER_HOLE_FEAT,		(char*)"HOLEFEAT"},
    {PRO_DEFLAYER_ROUND_FEAT,		(char*)"ROUNDFEAT"},
    {PRO_DEFLAYER_CHAMFER_FEAT,		(char*)"CHAMFERFEAT"},
    {PRO_DEFLAYER_SLOT_FEAT,		(char*)"SLOTFEAT"},
    {PRO_DEFLAYER_CUT_FEAT,		(char*)"CUTFEAT"},
    {PRO_DEFLAYER_PROTRUSION_FEAT,	(char*)"PROTRUSION"},
    {PRO_DEFLAYER_RIB_FEAT,		(char*)"RIBFEAT"},
    {PRO_DEFLAYER_DRAFT_FEAT,		(char*)"DRAFTFEAT"},
    {PRO_DEFLAYER_SHELL_FEAT,		(char*)"SHELLFEAT"},
    {PRO_DEFLAYER_CORN_CHAMF_FEAT,	(char*)"CORNCHAMF"},
    {PRO_DEFLAYER_ASSY_CUT_FEAT,	(char*)"ASSYCUTFEAT"},
    {PRO_DEFLAYER_TRIM_LINE_FEAT,	(char*)"TRIMLINE"},
    {PRO_DEFLAYER_COSM_ROUND_FEAT,	(char*)"COSMROUND"},
    {PRO_DEFLAYER_DIM,			(char*)"DIM"},
    {PRO_DEFLAYER_PARAMETER_DIM,	(char*)"PEREMETERDIM"},
    {PRO_DEFLAYER_DRIVEN_DIM,		(char*)"DRIVENDIM"},
    {PRO_DEFLAYER_DRAFT_DIM,		(char*)"DRAFTDIM"},
    {PRO_DEFLAYER_REFDIM,		(char*)"REFDIM"},
    {PRO_DEFLAYER_PART_REFDIM,		(char*)"PARTREFDIM"},
    {PRO_DEFLAYER_DRAFT_REFDIM,		(char*)"DRAFTREFDIM"},
    {PRO_DEFLAYER_CURVE_ENT,		(char*)"CURVEENT"},
    {PRO_DEFLAYER_NOTE,			(char*)"NOTE"},
    {PRO_DEFLAYER_GTOL,			(char*)"GTOL"},
    {PRO_DEFLAYER_SYMBOL,		(char*)"SYMBOL"},
    {PRO_DEFLAYER_SFIN,			(char*)"SFIN"},
    {PRO_DEFLAYER_DRAFT_ENTITY,		(char*)"DREFTENTITY"},
    {PRO_DEFLAYER_DRAFT_CONSTR,		(char*)"DRAFTCONSRT"},
    {PRO_DEFLAYER_DRAFT_GEOM,		(char*)"DREFTGEOM"},
    {PRO_DEFLAYER_DRAFT_HIDDEN,		(char*)"DRAFTHIDDEN"},
    {PRO_DEFLAYER_DRAFT_OTHERS,		(char*)"DRAFTOTHERS"},
    {PRO_DEFLAYER_DRAFT_GRP,		(char*)"DRAFTGPR"},
    {PRO_DEFLAYER_DRAFT_DTM,		(char*)"DRAFTDTM"},
    {PRO_DEFLAYER_QUILT,		(char*)"QUILT"},
    {PRO_DEFLAYER_DGM_WIRE,		(char*)"DGMWIRE"},
    {PRO_DEFLAYER_DGM_CONN_COMP,	(char*)"DGMCONNCOMP"},
    {PRO_DEFLAYER_DGM_RAIL,		(char*)"DGMRAIL"},
    {PRO_DEFLAYER_DGM_HIGHWAY,		(char*)"DGMHIGHWAY"},
    {PRO_DEFLAYER_DETAIL_ITEM,		(char*)"DETAILITEM"},
    {PRO_DEFLAYER_DATUM_POINT,		(char*)"DATUMPOINT"},
    {PRO_DEFLAYER_DATUM_PLANE,		(char*)"DATUMPLANE"},
    {PRO_DEFLAYER_SNAP_LINE,		(char*)"SNAPLINE"},
    {PRO_DEFLAYER_DWG_TABLE,		(char*)"DWGTABLE"},
    {PRO_DEFLAYER_THREAD_FEAT,          (char*)"THREADFEAT"},
    {PRO_DEFLAYER_SOLID_GEOM,           (char*)"SOLIDGEOM"},
    {PRO_DEFLAYER_EXT_GCPY_FEAT,        (char*)"EXTGCPYFEAT"},
    {PRO_DEFLAYER_SKELETON,             (char*)"SKELETON"},
    {PRO_DEFLAYER_ANNOT_ELEM,           (char*)"ANNOTATIONELEMENT"},
    };
    
static int type_num = sizeof (def_layer_types) / sizeof (DefLayerTypes);





/*==============================================================*\
 Function:  ProUtilLayerStatusString()
 Purpose:   Return sting status by int
\*==============================================================*/
static char *ProUtilLayerStatusString(
    ProLayerDisplay  display_status)
{
    switch (display_status)
    {
	case PRO_LAYER_TYPE_NORMAL:
	    return ((char*)"PRO_LAYER_TYPE_NORMAL");
	case PRO_LAYER_TYPE_DISPLAY:
	    return ((char*)"PRO_LAYER_TYPE_DISPLAY");
	case PRO_LAYER_TYPE_BLANK:
	    return ((char*)"PRO_LAYER_TYPE_BLANK");
	case PRO_LAYER_TYPE_HIDDEN:
	    return ((char*)"PRO_LAYER_TYPE_HIDDEN");
	
    }
    return ((char*)"Invalid status");
}


/*==============================================================*\
 Function:  ProTestLayerDeleteWithStatus()
 Purpose:   Action function for def layer types menu
\*==============================================================*/
int ProTestLayerDeleteWithStatus(ProAppData app_data, int option)
{
    ProMenuDeleteWithStatus (option);
    return (1);
}

// Action function for ProMdlLayerVisit
ProError PTUtilLayerNameAction(ProLayer* layer, ProAppData app_data)
{
	ProError status;
	ProName** layer_name_array = (ProName **) app_data;
	ProName layer_name;

	status = ProModelitemNameGet((ProModelitem*) layer, layer_name);
	TEST_CALL_REPORT("ProModelitemNameGet()", "PTUtilLayerNameAction()",
                status, status != PRO_TK_NO_ERROR);

	if(status == PRO_TK_NO_ERROR)
	{
		status = ProArrayObjectAdd( (ProArray *)layer_name_array, PRO_VALUE_UNUSED, 1, &layer_name);
		TEST_CALL_REPORT("ProArrayObjectAdd()", "PTUtilLayerNameAction()",
                status, status != PRO_TK_NO_ERROR);
	}

	return (PRO_TK_NO_ERROR);
}

// Returns ProArray of layer names in the model
ProError PTUtilMdlLayerNamesGet(ProMdl mdl, ProName** layer_name_array)
{
	ProError status;

	status = ProArrayAlloc( 0, sizeof( ProName ), 1,
		(ProArray *)layer_name_array );
	TEST_CALL_REPORT("ProArrayAlloc()", "PTUtilMdlLayerNamesGet()",
                status, status != PRO_TK_NO_ERROR);

	if( status == PRO_TK_NO_ERROR )
	{
		status = ProMdlLayerVisit(mdl, PTUtilLayerNameAction, NULL, layer_name_array);
		TEST_CALL_REPORT("ProMdlLayerVisit()", "PTUtilMdlLayerNamesGet()",
                status, status != PRO_TK_NO_ERROR);
	}

	return (PRO_TK_NO_ERROR);
}

/*==============================================================*\
 Function:  ProTestLayerMenu()
 Purpose:   The user's layer menu
\*==============================================================*/
int ProTestLayerMenu(ProMdl *mod)
{
    int ProTestSelLevelAction(ProAppData app_data, int option), action, menu_id;
    ProError status;
    AppStruct st;
    ProCharLine string;

    ProTestQcrName(mod, (char*)LAYER_FILE, (char*)string);

    st.model = *mod;
    st.fp = PTApplsUnicodeFopen(string,"w");

    /*  Set-up the menu. */
    
    status = ProMenuFileRegister((char*)"TkSelLevel",(char*) "tksellevel.mnu", &menu_id);
    status = ProMenubuttonActionSet((char*)"TkSelLevel",(char*) "Sel level", 
		    (ProMenubuttonAction)ProTestSelLevelAction, &st, 0);
    status = ProMenubuttonActionSet((char*)"TkSelLevel",(char*) "Done/Return", 
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet((char*)"TkSelLevel",(char*) "TkSelLevel",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
		    
    status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkSelLevel", &menu_id);
		   
    status = ProMenuProcess((char*)"TkSelLevel", &action);
    
    fclose(st.fp);
    return(1);
}

/*==============================================================*\
 Function:  ProTestSelLevelAction()
 Purpose:   Perform the action for layers menu
\*==============================================================*/
int ProTestSelLevelAction(ProAppData app_data, int option)
{
    int ProTestLayerAction(ProAppData app_data, int option), action, menu_id;
    ProError status;
    ProMdl model = ((AppStruct*)app_data)->model;
    ProMdlType type;
    
    status = ProMdlTypeGet (model, &type);
    if (type != PRO_MDL_PART)
    {
        status = ProTestModelInfoMenu (type, &model);     
        if (status == PRO_TK_NO_ERROR)
            ((AppStruct*)app_data)->model = model;
        else if (status == PRO_TK_GENERAL_ERROR)
            return (1);
    }
    
    status = ProMenuFileRegister((char*)"TkLayers",(char*) "tklayers.mnu", &menu_id);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Setup Layer", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SETUP_LAYER);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Set Item", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SET_ITEM);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Set Display", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SET_DISPLAY);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "SetDefLayer", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SETDEFLAYER);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Save disp stat", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SAVE_DISP_STAT);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Info", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_INFO);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Dependency", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_DEPENDENCY);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "Done/Return", 
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet((char*)"TkLayers",(char*) "TkLayers",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
		    
    status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkLayers", &menu_id);
		   
    status = ProMenuProcess((char*)"TkLayers", &action);
    return (PRO_TK_NO_ERROR);
}

/*==============================================================*\
 Function:  ProTestLayerAction()
 Purpose:   Perform the action for layers
\*==============================================================*/
int ProTestLayerAction(ProAppData app_data, int option)
{
    ProError status;
    int menu_id, action;
    ProMdl model = ((AppStruct*)app_data)->model;
    FILE *fp = ((AppStruct*)app_data)->fp;
    ProMdlType type;
    ProLayerDisplay display_status, new_display_status;
    ProLayer layer;
    ProSelection *sel;
    int n_sel;
    ProView view;
    ProDefLayerType layer_type;
    ProName w_name;
    int i;
    ProCharLine	string;
    ProBoolean dep;
    char c_name[PRO_NAME_SIZE];
    int ProTestSetupLayerAction(ProAppData app_data, int option);
    int ProTestSetItemAction(ProAppData app_data, int option);
    int ProTestLayerInfoAction(ProAppData app_data, int option);

    switch(option)
    {
    case PRO_TEST_LAYER_SETUP_LAYER:
        status = ProMenuFileRegister((char*)"TkSetupLayer",(char*) "tksetuplayer.mnu", &menu_id);
        status = ProMenubuttonActionSet((char*)"TkSetupLayer",(char*) "Create", 
	    (ProMenubuttonAction)ProTestSetupLayerAction, app_data,
	    PRO_TEST_LAYER_CREATE);
        status = ProMenubuttonActionSet((char*)"TkSetupLayer",(char*) "Delete", 
	    (ProMenubuttonAction)ProTestSetupLayerAction, app_data,
	    PRO_TEST_LAYER_DELETE);
        status = ProMenubuttonActionSet((char*)"TkSetupLayer",(char*) "Done/Return", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        status = ProMenubuttonActionSet((char*)"TkSetupLayer",(char*) "TkSetupLayer",
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
  		    
        status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkSetupLayer", &menu_id);		   
        status = ProMenuProcess((char*)"TkSetupLayer", &action);
        break;

    case PRO_TEST_LAYER_SET_ITEM:
        status = ProMenuFileRegister((char*)"TkSetItem",(char*) "tksetitem.mnu", &menu_id);
        status = ProMenubuttonActionSet((char*)"TkSetItem",(char*) "Add item", 
	    (ProMenubuttonAction)ProTestSetItemAction, app_data,
	    PRO_TEST_ITEM_ADD);
        status = ProMenubuttonActionSet((char*)"TkSetItem",(char*) "Remove item", 
	    (ProMenubuttonAction)ProTestSetItemAction, app_data,
	    PRO_TEST_ITEM_REMOVE);
        status = ProMenubuttonActionSet((char*)"TkSetItem",(char*) "Done/Return", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        status = ProMenubuttonActionSet((char*)"TkSetItem",(char*) "TkSetItem",
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
  		    
        status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkSetItem", &menu_id);		   
        status = ProMenuProcess((char*)"TkSetItem", &action);
        break;
        
    case PRO_TEST_LAYER_SET_DISPLAY:
        status = ProMdlTypeGet (model, &type);
        if (type != PRO_MDL_DRAWING)
        {
            status = ProUtilLayerSelect(model, &layer);
            if (status != PRO_TK_NO_ERROR)
	        break;
	    status = ProLayerDisplaystatusGet (&layer, &display_status);
	    TEST_CALL_REPORT("ProLayerDisplaystatusGet()", "ProTestLayerAction()",
                status, status != PRO_TK_NO_ERROR);
            ProTestDispStatusMenu (display_status, &new_display_status);
            
	    status = ProLayerDisplaystatusSet(&layer, new_display_status);
            TEST_CALL_REPORT("ProLayerDisplaystatusSet()", "ProTestLayerAction()",
                status, status != PRO_TK_NO_ERROR);
            status = ProWindowRepaint(PRO_VALUE_UNUSED);
            TEST_CALL_REPORT("ProWindowRepaint()", "ProTestLayerAction()",
	        status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);
	}
        else
        {
            ProUtilMsgPrint("gen", "TEST %0s", "Select view");
            status = ProSelect ((char*)"prt_or_asm", 1, NULL, NULL, NULL, NULL,
                &sel, &n_sel);
            if (status != PRO_TK_NO_ERROR || n_sel != 1)
                break;
            status = ProSelectionViewGet (sel[0], &view);
            TEST_CALL_REPORT("ProSelectionViewGet()", "ProTestLayerAction()",
                status, status != PRO_TK_NO_ERROR);
            status = ProUtilLayerSelect(model, &layer);
            if (status != PRO_TK_NO_ERROR)
                break;
            status = ProDwgLayerDisplaystatusGet (&layer, view, &display_status);
            TEST_CALL_REPORT("ProDwgLayerDisplaystatusGet()", "ProTestLayerAction()",
                status, status != PRO_TK_NO_ERROR);
            ProTestDispStatusMenu (display_status, &new_display_status);
            status = ProDwgLayerDisplaystatusSet (&layer, view, new_display_status);
            TEST_CALL_REPORT("ProDwgLayerDisplaystatusSet()", "ProTestLayerAction()",
                status, status != PRO_TK_NO_ERROR);
            status = ProWindowRepaint(PRO_VALUE_UNUSED);
            TEST_CALL_REPORT("ProWindowRepaint()", "ProTestLayerAction()",
                status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);
        }
        break;
    case PRO_TEST_LAYER_SETDEFLAYER:
        ProTestDefLayerMenu ((int*)&layer_type);
        for (i = 0; i < type_num; i++)
        {
            if (def_layer_types[i].type == layer_type)
            	break;
        }
        status = ProLayerDefLayerGet (layer_type, w_name);
        TEST_CALL_REPORT("ProLayerDefLayerGet()", "ProTestLayerAction()",
                          status, status != PRO_TK_NO_ERROR);
        ProTKSprintf (string, "Set the name of the default %s layer[%s]:",
            def_layer_types[i].name, ProWstringToString (c_name, w_name));
        ProUtilMsgPrint ("gen", "TEST %0s", string);
        status = ProMessageStringRead (PRO_NAME_SIZE, w_name);
        if (status != PRO_TK_NO_ERROR)
            break;
        status = ProLayerDefLayerSet (layer_type, w_name);
        TEST_CALL_REPORT("ProLayerDefLayerSet()", "ProTestLayerAction()",
                          status, status != PRO_TK_NO_ERROR);
        status = ProLayerDefLayerGet (layer_type, w_name);
        TEST_CALL_REPORT("ProLayerDefLayerGet()", "ProTestLayerAction()",
                          status, status != PRO_TK_NO_ERROR);
        ProTKSprintf (string, "Name of the default %s layer: %s.",
            def_layer_types[i].name, ProWstringToString (c_name, w_name));
        ProTKFprintf (fp, "%s\n", string);
        
        break;
    case PRO_TEST_LAYER_SAVE_DISP_STAT:
        status = ProMdlCurrentGet (&model);
        TEST_CALL_REPORT("ProMdlCurrentGet()", "ProTestLayerAction()",
                          status, status != PRO_TK_NO_ERROR);
        status = ProLayerDisplaystatusSave (model);
        TEST_CALL_REPORT("ProLayerDisplaystatusSave()", "ProTestLayerAction()",
                          status, status != PRO_TK_NO_ERROR &&
                          status != PRO_TK_NO_CHANGE); 
        if (status != PRO_TK_NO_ERROR)
        {
            if (status != PRO_TK_NO_CHANGE)
            {
                ProUtilMsgPrint("gen", "TEST %0s", 
                    "A model cannot have layers.");
                break;
            }
            ProUtilMsgPrint("gen", "TEST %0s", 
                "No layers have been changed since the last save.");
        }
        break;
    case PRO_TEST_LAYER_INFO:
        status = ProMenuFileRegister((char*)"TkLayerInfo",(char*) "tklayerinfo.mnu", &menu_id);
        status = ProMenubuttonActionSet((char*)"TkLayerInfo",(char*) "Disp Status", 
	    (ProMenubuttonAction)ProTestLayerInfoAction, app_data,
	    PRO_TEST_INFO_DISP_STATUS);
        status = ProMenubuttonActionSet((char*)"TkLayerInfo",(char*) "Layer Items", 
	    (ProMenubuttonAction)ProTestLayerInfoAction, app_data,
	    PRO_TEST_INFO_LAYER_ITEMS);
        status = ProMenubuttonActionSet((char*)"TkLayerInfo",(char*) "Done/Return", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        status = ProMenubuttonActionSet((char*)"TkLayerInfo",(char*) "TkLayerInfo",
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
  		    
        status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkLayerInfo", &menu_id);		   
        status = ProMenuProcess((char*)"TkLayerInfo", &action);
        break;
    case PRO_TEST_LAYER_DEPENDENCY:
        ProUtilMsgPrint("gen", "TEST %0s", "Select view");
        status = ProSelect ((char*)"prt_or_asm", 1, NULL, NULL, NULL, NULL,
            &sel, &n_sel);
        if (status != PRO_TK_NO_ERROR || n_sel != 1)
            break;
        status = ProSelectionViewGet (sel[0], &view);
        TEST_CALL_REPORT("ProSelectionViewGet()", "ProTestLayerAction()",
            status, status != PRO_TK_NO_ERROR);
        status = ProLayerViewDependencyGet (view, &dep);
        TEST_CALL_REPORT("ProLayerViewDependencyGet()", "ProTestLayerAction()",
            status, status != PRO_TK_NO_ERROR);
        ProTKSprintf (c_name, "Dependency YES/NO[%s]:\n",
            dep ? "YES" : "NO");
        ProUtilMsgPrint("gen", "TEST %0s", c_name);
        status = ProMessageStringRead (3, w_name);
        if (status != PRO_TK_NO_ERROR)
            break;
        ProWstringToString (c_name, w_name);
        if (strncmp ("y", c_name, 1) == 0 ||
            strncmp ("Y", c_name, 1) == 0)
            dep = PRO_B_TRUE;
        else
            dep = PRO_B_FALSE;
        status = ProLayerViewDependencySet (view, dep);
        TEST_CALL_REPORT("ProLayerViewDependencySet()", "ProTestLayerAction()",
            status, status != PRO_TK_NO_ERROR);
        break;
    default:
        break;
    }

    return(1);
}

#define PRO_TEXT_SEL_OPTION "point,axis,csys,datum"

/*==============================================================*\
 Function:  ProTestSetupLayerAction()
 Purpose:   Action function for setup layers
\*==============================================================*/
int ProTestSetupLayerAction(ProAppData app_data, int option)
{
    ProError status;
    ProPath file_name;
    ProMdl model = ((AppStruct*)app_data)->model;
    FILE *fp = ((AppStruct*)app_data)->fp;
    ProLayer layer;
    char c_name[PRO_COMMENT_SIZE];
    
    switch (option)
    {
    case PRO_TEST_LAYER_CREATE:
        ProUtilMsgPrint("gen", "TEST %0s", "Enter name of layer to create:");
	
	status = ProMessageStringRead( PRO_NAME_SIZE, file_name);
        TEST_CALL_REPORT("ProMessageStringRead()", "ProTestSetupLayerAction()",
                          status, status != PRO_TK_NO_ERROR);

	status = ProLayerCreate(model, file_name, &layer);
        TEST_CALL_REPORT("ProLayerCreate()", "ProTestSetupLayerAction()",
                          status, status != PRO_TK_NO_ERROR);

        if (status == PRO_TK_NO_ERROR)
        {
            ProTKSprintf(c_name, "Layer <%d> created successfully",layer.id); 
    	    ProUtilMsgPrint("gen", "TEST %0s", c_name);
	    ProTKFprintf(fp, "Layer %d created\n", layer.id);
        }
        else
        {
            ProTKSprintf(c_name, "Error - %d", status);
    	    ProUtilMsgPrint("gen", "TEST %0s", c_name);
        }
        break;
    case PRO_TEST_LAYER_DELETE:
        status = ProUtilLayerSelect(model, &layer);
	if (status != PRO_TK_NO_ERROR)
	    break;

	status = ProLayerDelete(&layer);
        TEST_CALL_REPORT("ProLayerDelete()", "ProTestSetupLayerAction()",
                          status, status != PRO_TK_NO_ERROR);
        if (status == PRO_TK_NO_ERROR)
        {
            ProTKSprintf(c_name, "Layer <%d> deleted successfully", layer.id); 
    	    ProUtilMsgPrint("gen", "TEST %0s", c_name);
	    ProTKFprintf(fp, "Layer %d deleted\n", layer.id);
        }
        else
        {
            ProTKSprintf(c_name, "Error - %d", status);
       	    ProUtilMsgPrint("gen", "TEST %0s", c_name);
        }
        break;
    }
    return (1);
}

/*==============================================================*\
 Function:  ProTestLayerObjSelect()
 Purpose:   Function for select layer object
\*==============================================================*/
void ProTestLayerObjSelect (ProMdlType type, char *sel_option)
{
    ProError status;
    int menu_id, action;
    
    status = ProMenuFileRegister((char*)"TkLayerObj",(char*) "tklayerobj.mnu", &menu_id);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Component", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_COMP);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Feature", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_FEAT);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Curve", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_CURVE);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Quilt", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_QUILT);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "2D items", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_2DITEM);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Text", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_TEXT);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Point", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_POINT);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Datum Plane", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_DTMPLN);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Layer", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_LAYER);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Dwg Table", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_DWGTABLE);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Diagramsel", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_DIAGRAM);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "Done/Return", 
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet((char*)"TkLayerObj",(char*) "TkLayerObj",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
		    
    status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkLayerObj", &menu_id);

    if (type != PRO_MDL_DRAWING && type != PRO_MDL_DIAGRAM)
    {
         status = ProMenubuttonDeactivate ((char*)"TkLayerObj",(char*) "Component");
         TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestLayerObjSelect",
             status, status != PRO_TK_NO_ERROR);
         status = ProMenubuttonDeactivate ((char*)"TkLayerObj",(char*) "Dwg Table");
         TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestLayerObjSelect",
             status, status != PRO_TK_NO_ERROR);
    }
		   
    status = ProMenuProcess((char*)"TkLayerObj", &action);
    switch (action)
    {
    case PRO_TEST_OBJ_COMP:
        ProTKSprintf (sel_option, "prt_or_asm");
        break;
    case PRO_TEST_OBJ_FEAT:
        ProTKSprintf (sel_option, "feature");
        break;
    case PRO_TEST_OBJ_CURVE:
        ProTKSprintf (sel_option, "curve");
        break;
    case PRO_TEST_OBJ_QUILT:
        ProTKSprintf (sel_option, "dtmqlt");
        break;
    case PRO_TEST_OBJ_2DITEM:
        ProTKSprintf (sel_option, "any_note,draft_ent");
        break;
    case PRO_TEST_OBJ_POINT:
        ProTKSprintf (sel_option, "point");
        break;
    case PRO_TEST_OBJ_DTMPLN:
        ProTKSprintf (sel_option, "datum");
        break;
    case PRO_TEST_OBJ_LAYER:
        ProTKSprintf (sel_option, "layer");
        break;
    case PRO_TEST_OBJ_TEXT:
        ProTKSprintf (sel_option, PRO_TEXT_SEL_OPTION);
        break;
	case PRO_TEST_DIAGRAM:
        ProTKSprintf (sel_option, "dgm_obj,dgm_non_cable_wire,dgm_cable");
        break;
    case PRO_TEST_OBJ_DWGTABLE:
    default:
        ProTKSprintf (sel_option, "");
        ProUtilMsgPrint("gen", "TEST %0s", "Not implemented");
        break;
    }
}



/*==============================================================*\
 Function:  ProTestSetItemAction()
 Purpose:   Action function for set item
\*==============================================================*/
int ProTestSetItemAction(ProAppData app_data, int option)
{
    ProError status;
    ProMdl model = ((AppStruct*)app_data)->model;
    FILE *fp = ((AppStruct*)app_data)->fp;
    ProLayer layer, layer_add;
    char sel_option[PRO_PATH_SIZE];
    ProMdlType type;
    void ProTestLayerObjSelect (ProMdlType type, char *sel_option);
    ProSelection *sel;
    int n_sel;
    ProModelitem model_item;
    ProAsmcomppath comp_path;
    ProLayerItem layer_item;

    status = ProMdlTypeGet (model, &type);
    status = ProUtilLayerSelect(model, &layer);
    if (status != PRO_TK_NO_ERROR)
        return (1);
    ProTestLayerObjSelect (type, sel_option);
    if (sel_option[0] == '\0')
        return (1);
    if (strcmp (sel_option, "layer") == 0)
    {
        status = ProUtilLayerSelect (model, &layer_add);
        if (layer_add.id == layer.id)
        {
            ProUtilMsgPrint("gen", "TEST %0s", "Can't add layer in itself");
            return (1);
        }
        status = ProModelitemInit (layer.owner, layer.id, layer.type, &model_item);
    }
    else
    {
        status = ProSelect(sel_option, 1, NULL, NULL, NULL, NULL, &sel, &n_sel);
        if (status != PRO_TK_NO_ERROR || n_sel != 1)
            return (1);
        status = ProSelectionModelitemGet(sel[0], &model_item);

	if (strcmp (sel_option, PRO_TEXT_SEL_OPTION) == 0)
	  {
	    switch (model_item.type)
	      {
	      case PRO_CSYS:
	      case PRO_AXIS:
	      case PRO_POINT:
		model_item.type = PRO_ENTITY_TEXT;
		break;
	      case PRO_SURFACE:
		{
		  ProFeature feat;
		  
		  status = ProGeomitemFeatureGet (&model_item, &feat);
		  model_item.id = feat.id;
		  model_item.type = PRO_DATUM_TEXT;
		  break;
		}
	      default:
		model_item.type = (ProType)PRO_NO_TYPE;
		ProUtilMsgPrint("gen", "TEST %0s", "Not implemented");
		return PRO_TK_GENERAL_ERROR;
		break;
	      }
	  }	
	if (strcmp (sel_option, "datum") == 0)
	  {
	    if (model_item.type == PRO_SURFACE)
	      model_item.type = PRO_DATUM_PLANE;
	  }
    }
    TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestSetItemAction()",
        status, status != PRO_TK_NO_ERROR);
    if (type == PRO_MDL_DRAWING &&
        model != model_item.owner &&
        (model_item.type == PRO_MDL_ASSEMBLY || 
         model_item.type == PRO_MDL_PART ||
         model_item.type == PRO_FEATURE))
    {
        status = ProSelectionAsmcomppathGet(sel[0], &comp_path);
        TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", 
            "ProTestSetItemAction()", status, status != PRO_TK_NO_ERROR);
        if (model_item.type == PRO_ASSEMBLY || model_item.type == PRO_PART)
        {
            model_item.type = PRO_FEATURE;
            model_item.id = comp_path.comp_id_table[0];
            model_item.owner =  comp_path.owner;
        }
        status = ProDwgLayerItemInit ((ProLayerType)model_item.type, model_item.id,
            &comp_path, &layer_item);
        TEST_CALL_REPORT("ProDwgLayerItemInit()", "ProTestSetItemAction()",
            status, status != PRO_TK_NO_ERROR);
    }  
    else
    {
        status = ProLayerItemInit((ProLayerType)model_item.type, model_item.id,
        model, &layer_item);
        TEST_CALL_REPORT("ProLayerItemInit()", "ProTestSetItemAction()",
            status, status != PRO_TK_NO_ERROR);
    }
    if (option == PRO_TEST_ITEM_ADD)
    {
        status = ProLayerItemAdd(&layer, &layer_item);
        TEST_CALL_REPORT("ProLayerItemAdd()", "ProTestSetItemAction()",
            status, status != PRO_TK_NO_ERROR);
    }
    else
    {
        status = ProLayerItemRemove(&layer, &layer_item);
        TEST_CALL_REPORT("ProLayerItemRemove()", "ProTestSetItemAction()",
            status, status != PRO_TK_NO_ERROR);
    }
    ProTKFprintf(fp, "Layer %d. Item id %d type %d %s\n", layer.id,
        layer_item.id, layer_item.type,
        option == PRO_TEST_ITEM_ADD ? "added" : "removed");

    return (1);
}

/*==============================================================*\
 Function:  ProTestLayerInfoAction()
 Purpose:   Action function for layer info
\*==============================================================*/
int ProTestLayerInfoAction(ProAppData app_data, int option)
{
    ProError status;
    ProMdl model = ((AppStruct*)app_data)->model;
    FILE *fp = ((AppStruct*)app_data)->fp;
    ProLayer *p_layer, layer;
    ProLayerItem *layer_items = NULL;
    int num_layer, i, n_item;
    ProLayerDisplay action;
    char string[PRO_COMMENT_SIZE];
    
    switch (option)
    {
    case PRO_TEST_INFO_DISP_STATUS:
       	status = ProUtilCollectMdlLayers(model, &p_layer);
	if (status == PRO_TK_NO_ERROR)
	{
	    status = ProArraySizeGet((ProArray*)p_layer, &num_layer);
	    TEST_CALL_REPORT("ProArraySizeGet()", "ProTestLayerInfoActionn()",
	        			    status, status != PRO_TK_NO_ERROR);
	}
	if (status != PRO_TK_NO_ERROR || num_layer<=0)
	    break;
    
	for (i=0; i<num_layer; i++)
	{
	    status = ProLayerDisplaystatusGet(p_layer+i, &action);
	    TEST_CALL_REPORT("ProLayerDisplaystatusGet()", 
		"ProTestLayerInfoAction()", status, status != PRO_TK_NO_ERROR);

	    ProTKFprintf(fp, "Layer %d - Display_status[%d]: %s\n", p_layer[i].id,
		    action, ProUtilLayerStatusString(action));
		fflush (fp);
	    
	}
        break;
    case PRO_TEST_INFO_LAYER_ITEMS:
        status = ProUtilLayerSelect(model, &layer);
	if (status != PRO_TK_NO_ERROR)
	    break;

	status = ProLayerItemsPopulate(&layer, &layer_items, &n_item);
        TEST_CALL_REPORT("ProLayerItemsPopulate()", "ProTestLayerInfoAction()",
                          status, status != PRO_TK_NO_ERROR);

        if (status != PRO_TK_NO_ERROR)
        {
            ProTKSprintf(string, "Error - %d", status);
       	    ProUtilMsgPrint("gen", "TEST %0s", string);
	    break;
	}
        ProTKSprintf(string, "There are %d items in layer <%d>", n_item, layer.id); 
	ProUtilMsgPrint("gen", "TEST %0s", string);

	ProTKFprintf(fp, "%d Items found in Layer %d\n", n_item, layer.id);
	for (i=0; i<n_item; i++)
	  ProTKFprintf(fp,"\tType %d:\t ID: [%d]\n", layer_items[i].type, 
			  layer_items[i].id);
	fflush (fp);
        status = ProLayeritemarrayFree(&layer_items);
 
	break;
    }
    return (PRO_TK_NO_ERROR);
}

/*==============================================================*\
 Function:  ProTestModelInfoMenu()
 Purpose:   Select model type and sets model
\*==============================================================*/
ProError ProTestModelInfoMenu (ProMdlType type, ProMdl *model)
{
    ProError status;
    int dummy, info, n_sel, i;
    ProSelection *sel;
    char c_str[PRO_NAME_SIZE];
    char c_msg[PRO_NAME_SIZE];
    ProModelitem model_item;
    
    ProUtilMsgPrint("gen", "TEST %0s", "Select level");

    status = ProMenuFileRegister((char*)"TkModelInfo",(char*) "tkmodelinf.mnu", &dummy);
    status = ProMenubuttonActionSet((char*)"TkModelInfo",(char*) "Drawing", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_DRAWING);
    status = ProMenubuttonActionSet((char*)"TkModelInfo",(char*) "Assembly", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_ASSEMBLY);
    status = ProMenubuttonActionSet((char*)"TkModelInfo",(char*) "Part", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_PART);
    status = ProMenubuttonActionSet((char*)"TkModelInfo",(char*) "Diagram", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_DIAGRAM);
    status = ProMenubuttonActionSet((char*)"TkModelInfo",(char*) "TkModelInfo",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenuCreate(PROMENUTYPE_SUB,(char*) "TkModelInfo", &dummy);
    if (type != PRO_MDL_DRAWING)
    {
        status = ProMenubuttonDeactivate ((char*)"TkModelInfo",(char*) "Drawing");
        TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestModelInfoMenu",
            status, status != PRO_TK_NO_ERROR);
    }
    if (type != PRO_MDL_DIAGRAM)
    {
        status = ProMenubuttonDeactivate ((char*)"TkModelInfo",(char*) "Diagram");
        TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestModelInfoMenu",
            status, status != PRO_TK_NO_ERROR);
    }
    status = ProMenuProcess((char*)"TkModelInfo", &info);
    if (info != PRO_DRAWING && info != PRO_DIAGRAM)
        {
            if (info == PRO_PART)
            {
                ProUtilMsgPrint("gen", "TEST %0s", "Select a part");
            }
            else if (info == PRO_ASSEMBLY)
            {
                ProUtilMsgPrint("gen", "TEST %0s", "Select an assembly");
            }
            else 
                return (PRO_TK_GENERAL_ERROR);
            for(i = 0; ; i++)
            {
                if (info == PRO_PART)
                {
                    ProTKSprintf (c_str, "part");
                }
                else if (info == PRO_ASSEMBLY)
                {
                    ProTKSprintf (c_str, "prt_or_asm");
                }
                else 
                    return (PRO_TK_GENERAL_ERROR);
                status = ProSelect (c_str, 1, NULL, NULL, NULL, NULL,
                    &sel, &n_sel);
                if (status != PRO_TK_NO_ERROR)
                    return (PRO_TK_GENERAL_ERROR);
                if ( n_sel <= 0 )
                    return (PRO_TK_GENERAL_ERROR);
                status = ProSelectionModelitemGet(sel[0], &model_item);
                if (info != model_item.type) 
                {
                    ProTKSprintf (c_msg, "It isn't %s. Select again %d", info == PRO_PART ? "a part" : "an assembly", i);
                    ProUtilMsgPrint("gen", "TEST %0s", c_msg);
                }
                else
                {
                    *model = model_item.owner;
                    return (PRO_TK_NO_ERROR);
                }
            }
        }
    return (PRO_TK_USER_ABORT);    
}

/*==============================================================*\
 Function:  ProTestDispStatusMenu()
 Purpose:   Select display status 
\*==============================================================*/
void ProTestDispStatusMenu (ProLayerDisplay old_status, 
    ProLayerDisplay *new_status)
{
    ProError status;
    int dummy, action;
    char highlight[PRO_NAME_SIZE];
    
    ProUtilMsgPrint("gen", "TEST %0s", "Select display status");

    status = ProMenuFileRegister((char*)"TkDisplayStat",(char*) "tkdispstat.mnu", &dummy);
    status = ProMenubuttonActionSet((char*)"TkDisplayStat",(char*) "NORMAL", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_NORMAL);
    status = ProMenubuttonActionSet((char*)"TkDisplayStat",(char*) "DISPLAY", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_DISPLAY);
    status = ProMenubuttonActionSet((char*)"TkDisplayStat",(char*) "BLANK", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_BLANK);
    status = ProMenubuttonActionSet((char*)"TkDisplayStat",(char*) "HIDDEN", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_HIDDEN);
    status = ProMenubuttonActionSet((char*)"TkDisplayStat",(char*) "TkDisplayStat",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    switch (old_status)
    {
    case PRO_LAYER_TYPE_NORMAL:
        ProUtilstrcpy (highlight, "NORMAL");
        break;
    case PRO_LAYER_TYPE_DISPLAY:
        ProUtilstrcpy (highlight, "DISPLAY");
        break;
    case PRO_LAYER_TYPE_BLANK:
        ProUtilstrcpy (highlight, "BLANK");
        break;
    case PRO_LAYER_TYPE_HIDDEN:
        ProUtilstrcpy (highlight, "HIDDEN");
        break;
    }
		    
    status = ProMenuCreate(PROMENUTYPE_SUB,(char*) "TkDisplayStat", &dummy);
    status = ProMenubuttonHighlight ((char*)"TkDisplayStat", highlight);
		   
    status = ProMenuProcess((char*)"TkDisplayStat", &action);
    *new_status = (ProLayerDisplay)action;
}

/*==============================================================*\
 Function:  ProTestDefLayerMenu()
 Purpose:   Process menu and return layer type
\*==============================================================*/
void ProTestDefLayerMenu(int *type)
{
    ProError status;
    int dummy, i;
    
    status = ProMenuFileRegister((char*)"DefLayer",(char*) "tkdeflayer.mnu", &dummy);
    for (i = 0; i < type_num; i++)
    {
        status = ProMenubuttonActionSet((char*)"DefLayer",(char*) 
            def_layer_types[i].name, 
            (ProMenubuttonAction)ProTestLayerDeleteWithStatus, 
            NULL, def_layer_types[i].type);
    }
    status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "DefLayer", &dummy);
    status = ProMenuProcess((char*)"DefLayer", type);
}

/*==============================================================*\
 Function:  ProUtilLayerSelect()
 Purpose:   Select one layer from menu and fill ProLayer struct
 Return:    PRO_TK_NO_ERROR if successfull, PRO_TK_E_NOT_FOUND otherwise
\*==============================================================*/
ProError ProUtilLayerSelect(
    ProMdl   model,	/* In : the Model */
    ProLayer *layer)	/* Out: selected layer, user's memory */  
{
    int num_layer, i, n_sel;
    ProName *layer_names, title;
    ProError status;
    wchar_t **buttons, **selected;

	status = PTUtilMdlLayerNamesGet(model, &layer_names);
	TEST_CALL_REPORT("PTUtilMdlLayerNamesGet()", "ProUtilLayerSelect()",
                      status, status != PRO_TK_NO_ERROR);

	status = ProArraySizeGet((ProArray) layer_names,&num_layer);
	TEST_CALL_REPORT("ProArraySizeGet()", "ProUtilLayerSelect()",
                      status, status != PRO_TK_NO_ERROR);

    if (status != PRO_TK_NO_ERROR) 
    {
  	ProUtilMsgPrint("gen", "TEST %0s", "Unable select layer");
	return (PRO_TK_E_NOT_FOUND);
    }
    
    ProUtilMenuStringsAlloc(&buttons);
    for (i=0; i<num_layer; i++)
            ProUtilMenuStringsWstrAdd( &buttons, layer_names[i]);

    ProUtilMsgPrint("gen", "TEST %0s", "Select layer");

    ProStringToWstring(title, (char*)"Model Layers");
    status = ProMenuStringsSelect(title, buttons, 1, NULL, &selected, &n_sel);
    TEST_CALL_REPORT("ProMenuStringsSelect()", "ProUtilLayerSelect()",
                      status, status != PRO_TK_NO_ERROR);
    if (status !=  PRO_TK_NO_ERROR || n_sel != 1)
	return  (PRO_TK_E_NOT_FOUND);
    
    status = ProMdlLayerGet(model, selected[0], layer);
    TEST_CALL_REPORT("ProMdlLayerGet()", "ProUtilLayerSelect()",
                      status, status != PRO_TK_NO_ERROR);
    ProUtilMenuStringsFree(&buttons);

	status = ProArrayFree((ProArray *)&layer_names);
	TEST_CALL_REPORT("ProArrayFree()", "ProUtilLayerSelect()",
                      status, status != PRO_TK_NO_ERROR);

    return  (status);
}