/*====================================================================*\
FILE    : TestLayer.c
PURPOSE : Layer function testing for Pro/TOOLKIT.

HISTORY..
DATE      BUILD   AUTHOR   MODIFICATIONS
19-Jan-97 H-01-21  Pavel    $$1 Created
04-Feb-97 H-01-25  Pavel    $$2 Use one file for output
06-Mar-97 H-01-28  Pavel    $$3 Added diagram object support
14-Apr-97 H-03-06  CHI      $$4 R18 compatibility
29-Apr-97 H-03-10  CHI      $$5 more R18 compatibility
29-May-97 H-03-13  Pavel    $$6 support for both ProLayer & ProLayerR18
05-Jun-97 H-03-13  Pavel    $$7 Fixed compilation error on SGI
19-Aug-97 H-03-23  Pavel    $$8 Added more includes 
30-Sep-97 H-03-25  Pavel    $$9 Added some ProLayer calls
25-Nov-97 H-03-31  CHI     $$10 ProLayer Xxx R18->R19 (since H-03 is now R20)
15-Jan-98 H-03-37  CHI     $$11 rename ProLayerDisplayStatusSave
04-Nov-98 I-01-26  Alexey  $$12 Replaced some ProMenu functions by ProUtilMenu
15-Nov-98 I-01-26  Alexey  $$13 Fix ProUtilLayerSelect19
16-Nov-98 I-01-26  Alexey  $$14 Fix creating string menu with layer names
18-Nov-98 I-01-26  Alexey  $$15 Use for(i=0;i<num_layer;i++) instead of
				for(i=0;i<=num_layer;i++) after
				ProMdlLayerNamesGetR19().
07-Dec-98 I-01-27  Pavel   $$16 Fixed for testing in Diagram mode
14-Dec-98 I-01-28  agsh    $$17 Correct TEST_CALL_REPORTs
01-Jun-99 I-03-11  mka     $$18 Delete unused variable
08-Jun-99 I-03-12  agsh    $$19 Updated DefLayerTypes
05-Sep-2000 J-01-17  shkulkar $$20 Fix for SPR 839298 in ProTestModelInf
oMenu
\*====================================================================*/

/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProLayerR19.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>

#include <select3d.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"
/*--------------------------------------------------------------------*\
Application macros
\*--------------------------------------------------------------------*/
#define PRO_TEST_LAYER_GET_NAMES  1
#define PRO_TEST_LAYER_ADD_ITEM   2
#define PRO_TEST_LAYER_REM_ITEM   3
#define PRO_TEST_LAYER_DISPLAY_LAYER   4
#define PRO_TEST_LAYER_BLANK_LAYER   5
#define PRO_TEST_LAYER_DISPLAY_ALL  6
#define PRO_TEST_LAYER_BLANK_ALL  7
#define PRO_TEST_LAYER_GET_STATUS 8
#define PRO_TEST_LAYER_CREATE_LAYER 9
#define PRO_TEST_LAYER_DELETE_LAYER 10
#define PRO_TEST_LAYER_GET_ITEMS 11


#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 LAYER_FILE ".lrf"
#define LAYER19_FILE ".lyr"

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

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


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

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

    ProTestQcrName(mod, LAYER19_FILE, string);

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

    /*  Set-up the menu. */
    status = ProMenuFileRegister("TkLayerR19", "tklayer19.mnu", &menu_id);
    TEST_CALL_REPORT("ProMenuFileRegister()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);

    status = ProMenubuttonActionSet("TkLayerR19", "Get Names", 
		    ProTestLayerR19Action, &st, PRO_TEST_LAYER_GET_NAMES);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Add Item", 
		    ProTestLayerR19Action, &st, PRO_TEST_LAYER_ADD_ITEM);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Remove Item", 
		    ProTestLayerR19Action, &st, PRO_TEST_LAYER_REM_ITEM);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Disp Layer", 
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_DISPLAY_LAYER);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Blank Layer", 
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_BLANK_LAYER);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Display All", 
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_DISPLAY_ALL);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Blank All", 
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_BLANK_ALL);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Get Status",
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_GET_STATUS);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Create Layer",
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_CREATE_LAYER);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Delete Layer",
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_DELETE_LAYER);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "Get items",
		    ProTestLayerR19Action,  &st, PRO_TEST_LAYER_GET_ITEMS);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet("TkLayerR19", "TkLayerR19",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenuCreate(PROMENUTYPE_MAIN, "TkLayerR19", &menu_id);
    TEST_CALL_REPORT("ProMenuCreate()", "ProTestLayerR19Menu()",
                      status, status != PRO_TK_NO_ERROR);
    status = ProMenuProcess("TkLayerR19", &action);
    TEST_CALL_REPORT("ProMenuProcess()", "ProTestLayerR19Menu()",
	status, status != PRO_TK_NO_ERROR && status!= PRO_TK_E_FOUND);

    fclose(st.fp);
    return(1);
}

/*==============================================================*\
 Function:  ProTestLayerR19Action()
 Purpose:   Perform the action for layers
\*==============================================================*/
int ProTestLayerR19Action(ProAppData app_data, int option)
{
    ProMdl                model;
    ProMdlType            type;
    ProName              *layer_names;
    int                   num_layer, n_sel, i, n_item;
    ProCharLine	          string;
    ProPath               file_name;
    ProLayerR19           layer;
    ProSelection	  *sel;
    ProModelitem	  model_item;
    ProLayerItemR19	  layer_item, *layer_items;    
    ProLayerDisplay	  action;  
    char		  c_name[PRO_NAME_SIZE];
    FILE *fp;    
    ProError		  status;
    Select3d              *sel3d;    

    model = ((AppStruct*)app_data)->model;
    fp = ((AppStruct*)app_data)->fp;

    switch(option)
    {
    case PRO_TEST_LAYER_GET_NAMES:
	status = ProMdlLayerNamesGetR19(model, &layer_names, &num_layer);
	TEST_CALL_REPORT("ProMdlLayerNamesGetR19()", "ProTestLayerR19Action()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

        sprintf(string, "There are %d layers", num_layer);
	fprintf(fp, "There are %d layers\n", num_layer);
	ProUtilMsgPrint("gen", "TEST %0s", string);
	
        if ( num_layer > 0 )
        {
            fprintf(fp, "\tLayer\tName\n");
            for (i=0; i<num_layer; i++)
                fprintf(fp, "\t%-4d\t%s\n", i, 
		    ProWstringToString(string, layer_names[i]));
        }
        break;

    case PRO_TEST_LAYER_ADD_ITEM:
    case PRO_TEST_LAYER_REM_ITEM:
	status = ProUtilLayerSelect19(model, &layer);
	if (status != PRO_TK_NO_ERROR)
	    break;

        status = ProMdlTypeGet(model, &type);
        TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestLayerR19Action()",
                              status, status != PRO_TK_NO_ERROR);
        if (type == PRO_MDL_DIAGRAM)
        {
            n_sel = pro_select("dgm_obj,dgm_non_cable_wire,dgm_cable",
                                1, &sel3d, NULL, NULL);
            if (n_sel != 1)
                break;
            layer_item.type = PRO_LAYER_DGM_OBJECT;
            layer_item.id = sel3d[0].selected_id;
        }
         else
        {
            status = ProSelect("feature,curve,point,surface",
                                1, NULL, NULL, NULL, NULL, &sel, &n_sel);
            if (status != PRO_TK_NO_ERROR || n_sel != 1)
                break;
            status = ProSelectionModelitemGet(sel[0], &model_item);
            TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestLayerR19Action()",
                              status, status != PRO_TK_NO_ERROR);
            layer_item.type =(ProLayerType) model_item.type;
            layer_item.id = model_item.id;
        }
	if (option == PRO_TEST_LAYER_ADD_ITEM)
	{
	    status = ProLayerItemAddR19(&layer, &layer_item);
	    TEST_CALL_REPORT("ProLayerItemAddR19()", "ProTestLayerR19Action()",
                             status, status != PRO_TK_NO_ERROR);
	}
	else
	{
	    status = ProLayerItemRemoveR19(&layer, &layer_item);
	    TEST_CALL_REPORT("ProLayerItemRemoveR19()", "ProTestLayerR19Action()",
                             status, status != PRO_TK_NO_ERROR);
	}
	fprintf(fp, "Layer %s. Item id %d type %d %s\n", 
	    ProWstringToString(c_name, layer.layer_name), 
	    layer_item.id, layer_item.type,
	    option == PRO_TEST_LAYER_ADD_ITEM ? "added" : "removed");
        break;

    case PRO_TEST_LAYER_DISPLAY_LAYER:
    case PRO_TEST_LAYER_BLANK_LAYER:
	status = ProUtilLayerSelect19(model, &layer);
	if (status != PRO_TK_NO_ERROR)
	    break;

	action = option == PRO_TEST_LAYER_BLANK_LAYER ? PRO_LAYER_TYPE_BLANK :
		 PRO_LAYER_TYPE_DISPLAY;

	status = ProLayerDisplaystatusSetR19(&layer, action);
        TEST_CALL_REPORT("ProLayerDisplaystatusSetR19()", "ProTestLayerR19Action()",
                         status, status != PRO_TK_NO_ERROR);
	fprintf(fp, "Layer %s %s\n", 
	    ProWstringToString(string, layer.layer_name), 
	    option == PRO_TEST_LAYER_DISPLAY_LAYER ? "displayed" : "blanked");
	status = ProWindowRepaint(PRO_VALUE_UNUSED);
	TEST_CALL_REPORT("ProWindowRepaint()", "ProTestLayerR19Action()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);
        break;
    case PRO_TEST_LAYER_DISPLAY_ALL :
    case PRO_TEST_LAYER_BLANK_ALL :
	status = ProMdlLayerNamesGetR19(model, &layer_names, &num_layer);
	TEST_CALL_REPORT("ProMdlLayerNamesGetR19()", "ProTestLayerR19Action()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

	if (status != PRO_TK_NO_ERROR || num_layer<=0)
	    break;
	
	action = option == PRO_TEST_LAYER_BLANK_ALL ? PRO_LAYER_TYPE_BLANK :
		 PRO_LAYER_TYPE_DISPLAY;
	for (i=0; i<num_layer; i++)
        {
	    layer.owner = model;
	    ProUtilWstrcpy(layer.layer_name, layer_names[i]);
	    status = ProLayerDisplaystatusSetR19(&layer, action);
	    TEST_CALL_REPORT("ProLayerDisplaystatusSetR19()", "ProTestLayerR19Action()",
                         status, status != PRO_TK_NO_ERROR);
	    fprintf(fp, "Layer %s %s\n", 
		ProWstringToString(string, layer.layer_name), 
		option == PRO_TEST_LAYER_DISPLAY_ALL ? "displayed" : "blanked");
        }
	status = ProWindowRepaint(PRO_VALUE_UNUSED);
	TEST_CALL_REPORT("ProWindowRepaint()", "ProTestLayerR19Action()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

        break;

    case PRO_TEST_LAYER_GET_STATUS :
	status = ProMdlLayerNamesGetR19(model, &layer_names, &num_layer);
	TEST_CALL_REPORT("ProMdlLayerNamesGetR19()", "ProTestLayerR19Action()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

	if (status != PRO_TK_NO_ERROR || num_layer<=0)
	    break;
    
	for (i=0; i<num_layer; i++)
	{
	    layer.owner = model;
	    ProUtilWstrcpy(layer.layer_name, layer_names[i]);
	    status = ProLayerDisplaystatusGetR19(&layer, &action);
	    TEST_CALL_REPORT("ProLayerDisplaystatusGetR19()", "ProTestLayerR19Action()",
                         status, status != PRO_TK_NO_ERROR);

	    ProWstringToString(string, layer.layer_name);
	    fprintf(fp, "Layer %s - Display_status[%d]: %s\n", string,
		    action, ProUtilLayerStatusString(action));
	    
	}
        break;

    case PRO_TEST_LAYER_CREATE_LAYER:
	ProUtilMsgPrint("gen", "TEST %0s", "Enter name of layer to create:");
	
	status = ProMessageStringRead( PRO_NAME_SIZE, file_name);
        TEST_CALL_REPORT("ProMessageStringRead()", "ProTestLayerR19Action()",
                          status, status != PRO_TK_NO_ERROR);

        layer.owner = model;
        ProUtilWstrcpy(layer.layer_name, file_name);

	status = ProLayerCreateR19(&layer);
        TEST_CALL_REPORT("ProLayerCreateR19()", "ProTestLayerR19Action()",
                          status, status != PRO_TK_NO_ERROR);

        if (status == PRO_TK_NO_ERROR)
        {
            sprintf(string, "Layer <%s> created successfully", 
                    ProWstringToString(c_name, layer.layer_name));
    	    ProUtilMsgPrint("gen", "TEST %0s", string);
	    fprintf(fp, "Layer %s created\n", c_name);
        }
        else
        {
            sprintf(string, "Error - %d", status);
    	    ProUtilMsgPrint("gen", "TEST %0s", string);
        }
        break;

    case PRO_TEST_LAYER_DELETE_LAYER:
	status = ProUtilLayerSelect19(model, &layer);
	if (status != PRO_TK_NO_ERROR)
	    break;

	status = ProLayerDeleteR19(&layer);
        TEST_CALL_REPORT("ProLayerDeleteR19()", "ProTestLayerR19Action()",
                          status, status != PRO_TK_NO_ERROR);
        if (status == PRO_TK_NO_ERROR)
        {
            sprintf(string, "Layer <%s> deleted successfully", 
                    ProWstringToString(c_name, layer.layer_name));
    	    ProUtilMsgPrint("gen", "TEST %0s", string);
	    fprintf(fp, "Layer %s deleted\n", c_name);
        }
        else
        {
            sprintf(string, "Error - %d", status);
       	    ProUtilMsgPrint("gen", "TEST %0s", string);
        }
        break;

    case PRO_TEST_LAYER_GET_ITEMS:
	status = ProUtilLayerSelect19(model, &layer);
	if (status != PRO_TK_NO_ERROR)
	    break;

	status = ProLayerItemsGetR19(&layer, &layer_items, &n_item);
        TEST_CALL_REPORT("ProLayerItemsGetR19()", "ProTestLayerR19Action()",
                          status, status != PRO_TK_NO_ERROR);

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

	fprintf(fp, "%d Items found in Layer %s\n", n_item, c_name);
        for (i=0; i<n_item; i++)
	    fprintf(fp,"\tType %d:\t ID: [%d]\n", layer_items[i].type, 
		    layer_items[i].id);	
        break;

    default:
        break;
    }

    return(1);
}

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

    status = ProMdlLayerNamesGetR19(model, &layer_names, &num_layer);
    TEST_CALL_REPORT("ProMdlLayerNamesGetR19()", "ProTestLayerR19Action()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);
    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++)
    {
            ProUtilMenuStringsStrAdd(&buttons, 
		ProWstringToString( layer_name, layer_names[i] ) );
    }
    ProUtilMsgPrint("gen", "TEST %0s", "Select layer");

    ProStringToWstring(title, "Model Layers");
    status = ProMenuStringsSelect(title, buttons, 1, NULL, &selected, &n_sel);
    TEST_CALL_REPORT("ProMenuStringsSelect()", "ProUtilLayerSelect19()",
                      status, status != PRO_TK_NO_ERROR);
    if (status !=  PRO_TK_NO_ERROR || n_sel != 1)
	return  (PRO_TK_E_NOT_FOUND);

    layer->owner = model;
    ProUtilWstrcpy(layer->layer_name, selected[0]);
    ProUtilMenuStringsFree(&buttons);
    return  (PRO_TK_NO_ERROR);
}

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


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

/*==============================================================*\
 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, LAYER_FILE, string);

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

    /*  Set-up the menu. */
    
    status = ProMenuFileRegister("TkSelLevel", "tksellevel.mnu", &menu_id);
    status = ProMenubuttonActionSet("TkSelLevel", "Sel level", 
		    (ProMenubuttonAction)ProTestSelLevelAction, &st, 0);
    status = ProMenubuttonActionSet("TkSelLevel", "Done/Return", 
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet("TkSelLevel", "TkSelLevel",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
		    
    status = ProMenuCreate(PROMENUTYPE_MAIN, "TkSelLevel", &menu_id);
		   
    status = ProMenuProcess("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_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("TkLayers", "tklayers.mnu", &menu_id);
    status = ProMenubuttonActionSet("TkLayers", "Setup Layer", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SETUP_LAYER);
    status = ProMenubuttonActionSet("TkLayers", "Set Item", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SET_ITEM);
    status = ProMenubuttonActionSet("TkLayers", "Set Display", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SET_DISPLAY);
    status = ProMenubuttonActionSet("TkLayers", "SetDefLayer", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SETDEFLAYER);
    status = ProMenubuttonActionSet("TkLayers", "Save disp stat", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_SAVE_DISP_STAT);
    status = ProMenubuttonActionSet("TkLayers", "Info", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_INFO);
    status = ProMenubuttonActionSet("TkLayers", "Dependency", 
		    (ProMenubuttonAction)ProTestLayerAction, app_data,
		    PRO_TEST_LAYER_DEPENDENCY);
    status = ProMenubuttonActionSet("TkLayers", "Done/Return", 
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet("TkLayers", "TkLayers",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
		    
    status = ProMenuCreate(PROMENUTYPE_MAIN, "TkLayers", &menu_id);
		   
    status = ProMenuProcess("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("TkSetupLayer", "tksetuplayer.mnu", &menu_id);
        status = ProMenubuttonActionSet("TkSetupLayer", "Create", 
	    (ProMenubuttonAction)ProTestSetupLayerAction, app_data,
	    PRO_TEST_LAYER_CREATE);
        status = ProMenubuttonActionSet("TkSetupLayer", "Delete", 
	    (ProMenubuttonAction)ProTestSetupLayerAction, app_data,
	    PRO_TEST_LAYER_DELETE);
        status = ProMenubuttonActionSet("TkSetupLayer", "Done/Return", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        status = ProMenubuttonActionSet("TkSetupLayer", "TkSetupLayer",
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
  		    
        status = ProMenuCreate(PROMENUTYPE_MAIN, "TkSetupLayer", &menu_id);		   
        status = ProMenuProcess("TkSetupLayer", &action);
        break;

    case PRO_TEST_LAYER_SET_ITEM:
        status = ProMenuFileRegister("TkSetItem", "tksetitem.mnu", &menu_id);
        status = ProMenubuttonActionSet("TkSetItem", "Add item", 
	    (ProMenubuttonAction)ProTestSetItemAction, app_data,
	    PRO_TEST_ITEM_ADD);
        status = ProMenubuttonActionSet("TkSetItem", "Remove item", 
	    (ProMenubuttonAction)ProTestSetItemAction, app_data,
	    PRO_TEST_ITEM_REMOVE);
        status = ProMenubuttonActionSet("TkSetItem", "Done/Return", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        status = ProMenubuttonActionSet("TkSetItem", "TkSetItem",
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
  		    
        status = ProMenuCreate(PROMENUTYPE_MAIN, "TkSetItem", &menu_id);		   
        status = ProMenuProcess("TkSetItem", &action);
        break;
        
    case PRO_TEST_LAYER_SET_DISPLAY:
        status = ProMdlTypeGet (model, &type);
        if (type != PRO_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 ("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);
        sprintf (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);
        sprintf (string, "Name of the default %s layer: %s.",
            def_layer_types[i].name, ProWstringToString (c_name, w_name));
        fprintf (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("TkLayerInfo", "tklayerinfo.mnu", &menu_id);
        status = ProMenubuttonActionSet("TkLayerInfo", "Disp Status", 
	    (ProMenubuttonAction)ProTestLayerInfoAction, app_data,
	    PRO_TEST_INFO_DISP_STATUS);
        status = ProMenubuttonActionSet("TkLayerInfo", "Layer Items", 
	    (ProMenubuttonAction)ProTestLayerInfoAction, app_data,
	    PRO_TEST_INFO_LAYER_ITEMS);
        status = ProMenubuttonActionSet("TkLayerInfo", "Done/Return", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        status = ProMenubuttonActionSet("TkLayerInfo", "TkLayerInfo",
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
  		    
        status = ProMenuCreate(PROMENUTYPE_MAIN, "TkLayerInfo", &menu_id);		   
        status = ProMenuProcess("TkLayerInfo", &action);
        break;
    case PRO_TEST_LAYER_DEPENDENCY:
        ProUtilMsgPrint("gen", "TEST %0s", "Select view");
        status = ProSelect ("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);
        sprintf (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);
}

/*==============================================================*\
 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_NAME_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)
        {
            sprintf(c_name, "Layer <%d> created successfully",layer.id); 
    	    ProUtilMsgPrint("gen", "TEST %0s", c_name);
	    fprintf(fp, "Layer %d created\n", layer.id);
        }
        else
        {
            sprintf(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)
        {
            sprintf(c_name, "Layer <%d> deleted successfully", layer.id); 
    	    ProUtilMsgPrint("gen", "TEST %0s", c_name);
	    fprintf(fp, "Layer %d deleted\n", layer.id);
        }
        else
        {
            sprintf(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("TkLayerObj", "tklayerobj.mnu", &menu_id);
    status = ProMenubuttonActionSet("TkLayerObj", "Component", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_COMP);
    status = ProMenubuttonActionSet("TkLayerObj", "Feature", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_FEAT);
    status = ProMenubuttonActionSet("TkLayerObj", "Curve", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_CURVE);
    status = ProMenubuttonActionSet("TkLayerObj", "Quilt", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_QUILT);
    status = ProMenubuttonActionSet("TkLayerObj", "2D items", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_2DITEM);
    status = ProMenubuttonActionSet("TkLayerObj", "Text", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_TEXT);
    status = ProMenubuttonActionSet("TkLayerObj", "Point", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_POINT);
    status = ProMenubuttonActionSet("TkLayerObj", "Datum Plane", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_DTMPLN);
    status = ProMenubuttonActionSet("TkLayerObj", "Layer", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_LAYER);
    status = ProMenubuttonActionSet("TkLayerObj", "Dwg Table", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL,
		    PRO_TEST_OBJ_DWGTABLE);
    status = ProMenubuttonActionSet("TkLayerObj", "Done/Return", 
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet("TkLayerObj", "TkLayerObj",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
		    
    status = ProMenuCreate(PROMENUTYPE_MAIN, "TkLayerObj", &menu_id);

    if (type != PRO_DRAWING)
    {
         status = ProMenubuttonDeactivate ("TkLayerObj", "Component");
         TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestLayerObjSelect",
             status, status != PRO_TK_NO_ERROR);
         status = ProMenubuttonDeactivate ("TkLayerObj", "Dwg Table");
         TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestLayerObjSelect",
             status, status != PRO_TK_NO_ERROR);
    }
		   
    status = ProMenuProcess("TkLayerObj", &action);
    switch (action)
    {
    case PRO_TEST_OBJ_COMP:
        sprintf (sel_option, "prt_or_asm");
        break;
    case PRO_TEST_OBJ_FEAT:
        sprintf (sel_option, "feature");
        break;
    case PRO_TEST_OBJ_CURVE:
        sprintf (sel_option, "curve");
        break;
    case PRO_TEST_OBJ_QUILT:
        sprintf (sel_option, "dtmqlt");
        break;
    case PRO_TEST_OBJ_2DITEM:
        sprintf (sel_option, "note3d");
        break;
    case PRO_TEST_OBJ_POINT:
        sprintf (sel_option, "point");
        break;
    case PRO_TEST_OBJ_DTMPLN:
        sprintf (sel_option, "datum");
        break;
    case PRO_TEST_OBJ_LAYER:
        sprintf (sel_option, "layer");
        break;
    case PRO_TEST_OBJ_DWGTABLE:
    case PRO_TEST_OBJ_TEXT:
    default:
        sprintf (sel_option, "");
        ProUtilMsgPrint("gen", "TEST %0s", "Not implement");
        break;
    }
}

/*==============================================================*\
 Function:  ProTestSetItemAction()
 Purpose:   Action function for set item
\*==============================================================*/
int ProTestSetItemAction(ProAppData app_data, int option)
{
    ProError status;
    ProPath file_name;
    ProMdl model = ((AppStruct*)app_data)->model;
    FILE *fp = ((AppStruct*)app_data)->fp;
    ProLayer layer, layer_add;
    char sel_option[PRO_NAME_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);
    }
    TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestSetItemAction()",
        status, status != PRO_TK_NO_ERROR);
    if (type == PRO_DRAWING &&
        model != model_item.owner &&
        (model_item.type == PRO_ASSEMBLY || 
         model_item.type == PRO_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);
    }
    fprintf(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;
    int num_layer, i, n_item;
    ProLayerDisplay action;
    char string[PRO_NAME_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);

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

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

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

	fprintf(fp, "%d Items found in Layer %d\n", n_item, layer.id);
        for (i=0; i<n_item; i++)
	    fprintf(fp,"\tType %d:\t ID: [%d]\n", layer_items[i].type, 
		    layer_items[i].id);
        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("TkModelInfo", "tkmodelinf.mnu", &dummy);
    status = ProMenubuttonActionSet("TkModelInfo", "Drawing", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_DRAWING);
    status = ProMenubuttonActionSet("TkModelInfo", "Assembly", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_ASSEMBLY);
    status = ProMenubuttonActionSet("TkModelInfo", "Part", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_PART);
    status = ProMenubuttonActionSet("TkModelInfo", "TkModelInfo",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenuCreate(PROMENUTYPE_SUB, "TkModelInfo", &dummy);
    if (type != PRO_DRAWING)
    {
        status = ProMenubuttonDeactivate ("TkModelInfo", "Drawing");
        TEST_CALL_REPORT ("ProMenubuttonDeactivate", "ProTestModelInfoMenu",
            status, status != PRO_TK_NO_ERROR);
    }
    status = ProMenuProcess("TkModelInfo", &info);
    if (info != PRO_DRAWING)
        {
            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)
                {
                    sprintf (c_str, "part");
                }
                else if (info == PRO_ASSEMBLY)
                {
                    sprintf (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) 
                {
                    sprintf (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("TkDisplayStat", "tkdispstat.mnu", &dummy);
    status = ProMenubuttonActionSet("TkDisplayStat", "NORMAL", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_NORMAL);
    status = ProMenubuttonActionSet("TkDisplayStat", "DISPLAY", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_DISPLAY);
    status = ProMenubuttonActionSet("TkDisplayStat", "BLANK", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_BLANK);
    status = ProMenubuttonActionSet("TkDisplayStat", "HIDDEN", 
		    (ProMenubuttonAction)ProTestLayerDeleteWithStatus, NULL, PRO_LAYER_TYPE_HIDDEN);
    status = ProMenubuttonActionSet("TkDisplayStat", "TkDisplayStat",
		    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    switch (old_status)
    {
    case PRO_LAYER_TYPE_NORMAL:
        strcpy (highlight, "NORMAL");
        break;
    case PRO_LAYER_TYPE_DISPLAY:
        strcpy (highlight, "DISPLAY");
        break;
    case PRO_LAYER_TYPE_BLANK:
        strcpy (highlight, "BLANK");
        break;
    case PRO_LAYER_TYPE_HIDDEN:
        strcpy (highlight, "HIDDEN");
        break;
    }
		    
    status = ProMenuCreate(PROMENUTYPE_SUB, "TkDisplayStat", &dummy);
    status = ProMenubuttonHighlight ("TkDisplayStat", highlight);
		   
    status = ProMenuProcess("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("DefLayer", "tkdeflayer.mnu", &dummy);
    for (i = 0; i < type_num; i++)
    {
        status = ProMenubuttonActionSet("DefLayer", 
            def_layer_types[i].name, 
            (ProMenubuttonAction)ProTestLayerDeleteWithStatus, 
            NULL, def_layer_types[i].type);
    }
    status = ProMenuCreate(PROMENUTYPE_MAIN, "DefLayer", &dummy);
    status = ProMenuProcess("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 = ProMdlLayerNamesGetR19(model, &layer_names, &num_layer);
    TEST_CALL_REPORT("ProMdlLayerNamesGetR19()", "ProUtilLayerSelect()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);
    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, "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);
    return  (status);
}

