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


/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProArray.h>
#include <ProEdge.h>
#include <ProFeature.h>
#include <ProMdl.h>
#include <ProMenu.h>
#include <ProModelitem.h>
#include <ProParameter.h>
#include <ProParamval.h>
#include <ProSelection.h>
#include <ProSurface.h>
#include <ProUtil.h>
#include <ProTKRunTime.h>
#include <PTApplsUnicodeUtils.h>

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "TestParams.h"
#include "TestFiletypes.h"
#include "UtilFiles.h"
#include "UtilMessage.h"
#include "UtilString.h"
#include "UtilCollect.h"
#include "UtilMenu.h"

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

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define USER_DELETE 0
#define USER_RESET  1

#define USER_DES_ADD	10
#define USER_DES_REMOVE 11

/*--------------------------------------------------------------------*\
Application data types
\*--------------------------------------------------------------------*/

typedef struct
{
    int num_params;
    ProParameter *param_list;
} ParamList;

/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/

static int ProTestListParams(ProMdl  model);
static int ProTestSetParam(ProMdl  model);
static int ProTestAddParam(ProMdl  model);
static int ProTestParamDeleteAction(ProMdl  model, int action);
static int ProTestParamDesAction(ProMdl  model, int action);
int ProTestShowList(ProMdl model, ProModelitem *);
int ProTestShowParamsList (ProMdl model, ProParameter* pars);

static FILE *fp;
/*====================================================================*\
  Function : ProTestParams
  Purpose  : Display the parameters menu
\*====================================================================*/
int ProTestParams(char *a, int b)
{
    ProError status;
    ProMdl   model;
    char fname[PRO_FILE_NAME_SIZE];
    int id;

    status = ProMdlCurrentGet(&model);
    TEST_CALL_REPORT("ProMdlCurrentGet()", "ProTestParams()", status,
                                                status != PRO_TK_NO_ERROR);
    ProTestQcrName(&model, (char*)PARAMETERS, fname);
    fp = PTApplsUnicodeFopen(fname, "w");

    status = ProMenuFileRegister((char*)"TkParams", (char*)"tkparams.mnu", &id);
    TEST_CALL_REPORT ("ProMenuFileRegister", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-ListParams", 
	(ProMenubuttonAction)ProTestListParams, model, 0);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-SetParam", 
	(ProMenubuttonAction)ProTestSetParam, model, 0);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-AddParam", 
	(ProMenubuttonAction)ProTestAddParam, model, 0);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-DeleteParam", 
	(ProMenubuttonAction)ProTestParamDeleteAction, model, USER_DELETE);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-ResetParam", 
	(ProMenubuttonAction)ProTestParamDeleteAction, model, USER_RESET);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-DesignationAdd", 
	(ProMenubuttonAction)ProTestParamDesAction, model, USER_DES_ADD);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"-DesignationDel", 
	(ProMenubuttonAction)ProTestParamDesAction, model, USER_DES_REMOVE);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"Done TkParams", 
	(ProMenubuttonAction)ProMenuDelete, NULL, 0);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkParams", (char*)"TkParams", 
	(ProMenubuttonAction)ProMenuDelete, NULL, 0);
    TEST_CALL_REPORT ("ProMenubuttonActionSet", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);

    status = ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkParams", &id);
    TEST_CALL_REPORT ("ProMenuCreate", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    status = ProMenuProcess ((char*)"TkParams", &id);
    TEST_CALL_REPORT ("ProMenuProcess", "ProTestParams",
         status, status != PRO_TK_NO_ERROR);
    fclose(fp);
    return(0);
}

/*====================================================================*\
  Function : ProTestGetElemType
  Purpose  : Allow the user to select an element type
\*====================================================================*/
static ProType ProTestGetElemType(ProBoolean allow_multi)
{
    ProError status;
    int	opt;
    static ProUtilMenuButtons elem_type[] = {
	{"ElementMenu", 0, TEST_CALL_PRO_MENU_DELETE},
	{"Object", PRO_EXTOBJ, 0},
	{"Feature", PRO_FEATURE, 0},
        {"Surface", PRO_SURFACE, 0},
        {"Edge", PRO_EDGE, 0},
	{"Annotation Element", PRO_ANNOTATION_ELEM, 0},
	{"Any", PRO_TYPE_UNUSED, 0},
	{"", 0, 0}
    };

    static ProUtilMenuButtons elem_type_allow_multi[] = {
	{"ElementMenu", 0, TEST_CALL_PRO_MENU_DELETE},
	{"Object", PRO_EXTOBJ, 0},
	{"Feature", PRO_FEATURE, 0},
        {"Surface", PRO_SURFACE, 0},
        {"Edge", PRO_EDGE, 0},
	{"Annotation Element", PRO_ANNOTATION_ELEM, 0},
	{"Any", PRO_TYPE_UNUSED, 0},
	{"Selected", PRO_TYPE_INVALID, 0},
	{"", 0, 0}
    };
    if (allow_multi)
      {
	status = ProUtilMenuIntValueSelect(elem_type_allow_multi, &opt);
	if (status!=PRO_TK_NO_ERROR) opt=PRO_TYPE_INVALID;
      }
    else
      {
	status = ProUtilMenuIntValueSelect(elem_type, &opt);
	if (status!=PRO_TK_NO_ERROR) opt=PRO_TYPE_INVALID;
      }

   return ((ProType)opt);
}

/*====================================================================*\
  Function : ProTestGetContext
  Purpose  : Allow the user to select the types of items from which you can
             select parameters.
\*====================================================================*/
static int ProTestGetContext()
{
  int opt;
  ProError status;

  static ProUtilMenuButtons context_type[] = {
    {"ContextMenu", 0, TEST_CALL_PRO_MENU_DELETE},
    {"Any/All", PRO_PARAMSELECT_ANY, 0},
    {"Model", PRO_PARAMSELECT_MODEL, 0},
    {"Part", PRO_PARAMSELECT_PART, 0},
    {"Assembly", PRO_PARAMSELECT_ASM, 0},
    {"Feature", PRO_PARAMSELECT_FEATURE, 0},
    {"Component", PRO_PARAMSELECT_COMPONENT, 0},
    {"Surface/Edge", PRO_PARAMSELECT_SURFACE | PRO_PARAMSELECT_EDGE, 0},
    {"Quilt", PRO_PARAMSELECT_QUILT, 0},
    {"Curve/Composite", PRO_PARAMSELECT_CURVE | PRO_PARAMSELECT_COMPOSITE_CURVE, 0},
    {"Inherited", PRO_PARAMSELECT_INHERITED, 0},
    {"Skeleton", PRO_PARAMSELECT_SKELETON, 0},
    {"", 0, 0}
    };
  
  status = ProUtilMenuIntValueSelect(context_type, &opt);
  if (status!=PRO_TK_NO_ERROR) opt=PRO_PARAMSELECT_ANY;

  return opt;
}

/*====================================================================*\
  Function : ProTestGetParamType
  Purpose  : Allow the user to select a parameter type
\*====================================================================*/
static ProParamvalueType ProTestGetParamType()
{
    ProError status;
    int	opt;
    static ProUtilMenuButtons param_type[] = {
	{"ParamTypeMenu", 0, TEST_CALL_PRO_MENU_DELETE},
	{"Double", PRO_PARAM_DOUBLE, 0},
	{"String", PRO_PARAM_STRING, 0},
        {"Integer", PRO_PARAM_INTEGER, 0},
        {"Boolean", PRO_PARAM_BOOLEAN, 0},
	{"", 0, 0}
    };
    status = ProUtilMenuIntValueSelect(param_type, &opt);
    TEST_CALL_REPORT ("ProUtilMenuIntValueSelect", "ProTestGetParamType",
         status, status != PRO_TK_NO_ERROR);
    return ((ProParamvalueType)opt);
}

/*====================================================================*\
  Function : ProTestPickItem
  Purpose  : Allow the user to choose an item from which to generate
             a list of parameters
\*====================================================================*/
static int ProTestPickItem(
    ProMdl model,		/* In : current model */
    ProType type,		/* In : item type */
    ProModelitem *p_modelitem)	/* Out: selected feature, User's memory */
{
    int p_sel_num;
    ProError status = PRO_TK_BAD_INPUTS;
    char option[80];
    ProMdlType mdltype;
    ProSelection *sel;
    
    if(type==PRO_TYPE_INVALID) return(FALSE);
    switch( type )
    {
        case PRO_EXTOBJ:
            ProTKPrintf((char*)"Getting a Model\n");

	    status = ProMdlTypeGet(model, &mdltype);
	    TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestPickItem()",
				    status, status != PRO_TK_NO_ERROR);
	    if (mdltype == PRO_MDL_ASSEMBLY)
	    {
		ProUtilstrcpy(option, "prt_or_asm");
	    }
	    else
	    {
		status = ProMdlToModelitem(model, p_modelitem);
		TEST_CALL_REPORT("ProMdlToModelitem()", "ProTestPickItem()",
				status, status != PRO_TK_NO_ERROR);
		return (TRUE);
	    }
            break;

        case PRO_FEATURE:
	    ProUtilstrcpy(option, "feature");
            break;

        case PRO_EDGE:
	case PRO_SURFACE:

	    ProUtilstrcpy(option, "edge,surface");
        break;
	case PRO_ANNOTATION_ELEM:
	  ProUtilstrcpy (option, "annot_elem");
	  break;
        case PRO_VALUE_UNUSED:
          ProUtilstrcpy (option, "prt_or_asm,feature,edge,surface,annot_elem,curve,comp_crv,dtmqlt");
          break;
    }

    status = ProSelect(option, 1, NULL, NULL, NULL, NULL, &sel, &p_sel_num);
    TEST_CALL_REPORT("ProSelect()", "ProTestPickItem()",
					status, status == PRO_TK_COMM_ERROR);
    if( status != PRO_TK_NO_ERROR )
        return( FALSE );
    else
    {
	status = ProSelectionModelitemGet(sel[0], p_modelitem);
	TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestPickItem()",
					status, status != PRO_TK_NO_ERROR);
	return( TRUE );
    }
}

/*====================================================================*\
  Function : ProTestListParams
  Purpose  : Generate a list of parameters for a user-selected item
\*====================================================================*/
static int ProTestListParams(ProMdl model)
{
    ProType type;
    ProModelitem modelitem;

    type = ProTestGetElemType(PRO_B_TRUE);

    if (type == PRO_TYPE_INVALID)
      {
	int context;
	ProError status;
	ProParameter* pars;

	context = ProTestGetContext ();

	status = ProParameterSelect (NULL, model, context,
				     PRO_B_TRUE,
				     (wchar_t *)L"Include params",
				     NULL,
				     &pars);
	TEST_CALL_REPORT ("ProParameterSelect()", "ProTestListParams()",
			  status, status != PRO_TK_NO_ERROR);

	if (status == PRO_TK_NO_ERROR)
	  {
	    ProTKFprintf(fp, (char*)"Listing selected params:\n");

	    ProTestShowParamsList (model, pars);
	    
	    ProArrayFree((ProArray*)&pars);
	    TEST_CALL_REPORT("ProArrayFree()", "ProTestShowList()",
			     status, status != PRO_TK_NO_ERROR);
	  }
	
      }
    else
      {
	if( ProTestPickItem(model, type, &modelitem) )
	ProTestShowList(model, &modelitem);
      }

    return( 0 );
}

/*====================================================================*\
  Function : ProTestShowList
  Purpose  : Generate and display a list of parameters for a chosen
             item
\*====================================================================*/
int ProTestShowList(ProMdl model, ProModelitem *p_modelitem)
{
    ProError status;
    ProParameter *pars;
   

    status = ProUtilCollectParameters(p_modelitem, &pars);
    if (status!=PRO_TK_NO_ERROR)
	return (-1);

    ProTestShowParamsList (model, pars);
    
    ProArrayFree((ProArray*)&pars);
    TEST_CALL_REPORT("ProArrayFree()", "ProTestShowList()",
		     status, status != PRO_TK_NO_ERROR);
    
    return (0);
}

/*====================================================================*\
  Function : ProTestShowList
  Purpose  : Display a list of parameters 
\*====================================================================*/
int ProTestShowParamsList (ProMdl model, ProParameter* pars)
{
    int i, n;
    
    ProError status;
    ProParamvalue value;
    char name[PRO_NAME_SIZE];
    char astr[PRO_LINE_SIZE];
    char fname[PRO_FILE_NAME_SIZE];
    ProPath path;
    FILE *fv;
    ProBoolean modif = PRO_B_FALSE;
    ProBoolean desig;
    
    status = ProArraySizeGet((ProArray)pars, &n);
    TEST_CALL_REPORT("ProArraySizeGet()", "ProTestShowList()",
		     status, status != PRO_TK_NO_ERROR);
    
    ProTestQcrName(&model, (char*)".inf", fname);
    fv = PTApplsUnicodeFopen(fname, "w");


    ProTKFprintf(fp, (char*)"Name\t\tMod\tValType\t\tValue\t\tDesignated\n");
    ProTKFprintf(fv, (char*)"Name\t\tMod\tValType\t\tValue\t\tDesignated\n");

    for( i = 0; i < n; i++ )
    {
      value.type = PRO_PARAM_VOID;
        status = ProParameterValueWithUnitsGet(&pars[i], &value, NULL);
        TEST_CALL_REPORT("ProParameterValueWithUnitsGet()", "ProTestShowList()",
                                        status, status != PRO_TK_NO_ERROR);

	status = ProParameterIsModified(&pars[i], &modif);
        TEST_CALL_REPORT("ProParameterIsModified()", "ProTestShowList()",
                                        status, status != PRO_TK_NO_ERROR);

        ProWstringToString(name, pars[i].id);
        ProTKFprintf(fp, (char*)"%s\t%s", name, modif ? "Yes" : "No");
        ProTKFprintf(fv, (char*)"%s\t%s", name, modif ? "Yes" : "No");
        switch( value.type )
        {
            case PRO_PARAM_DOUBLE:
                ProTKFprintf(fp, (char*)"\tdouble\t\t%f\t", value.value.d_val);
                ProTKFprintf(fv, (char*)"\tdouble\t\t%f\t", value.value.d_val);
                break;
            case PRO_PARAM_STRING:
                ProWstringToString(astr, value.value.s_val);
                ProTKFprintf(fp, (char*)"\tstring\t\t%s\t", astr);
                ProTKFprintf(fv, (char*)"\tstring\t\t%s\t", astr);
                break;
            case PRO_PARAM_INTEGER:
                ProTKFprintf(fp, (char*)"\tinteger\t\t%d\t", value.value.i_val);
                ProTKFprintf(fv, (char*)"\tinteger\t\t%d\t", value.value.i_val);
                break;
            case PRO_PARAM_BOOLEAN:
                ProTKFprintf(fp, (char*)"\tboolean\t\t%d\t", value.value.l_val);
                ProTKFprintf(fv, (char*)"\tboolean\t\t%d\t", value.value.l_val);
                break;
            default:
                ProTKFprintf(fp, (char*)"\tvoid\t\tNULL\t");
                ProTKFprintf(fv, (char*)"\tvoid\t\tNULL\t");
        }

	status = ProParameterDesignationVerify(&pars[i], &desig);
        TEST_CALL_REPORT("ProParameterIsModified()", "ProTestShowList()",
                                        status, status != PRO_TK_NO_ERROR);

	ProTKFprintf(fp, (char*)"%s\n", desig ? "Yes" : "No");
        ProTKFprintf(fv, (char*)"%s\n", desig ? "Yes" : "No");

    }

    fclose(fv);
    ProStringToWstring(path, fname);
    ProInfoWindowDisplay(path, NULL, NULL);
    return( 0 );
}

/*====================================================================*\
  Function : ProTestNewParam
  Purpose  : Create a new parameter for a selected item
\*====================================================================*/
static int ProTestNewParam(ProMdl model, ProModelitem *p_modelitem )
{
    ProParamvalue new_value;
    ProParamvalueType new_value_type;
    ProParamvalueValue user_value;
    void* p_value;
    ProParameter new_param;
    ProName name;
    ProError status;
    char def_bool;
    char astr[PRO_NAME_SIZE*sizeof(wchar_t)];
    char aname[PRO_NAME_SIZE*sizeof(wchar_t)];

    new_value_type = ProTestGetParamType();

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please enter a name: ");
    ProUtilStringGet(name, NULL, PRO_NAME_SIZE);

    ProTKFprintf(fp, (char*)"Name:\t%s\n", ProWstringToString(aname, name));
    switch( new_value_type )
    {
        case PRO_PARAM_DOUBLE:
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please enter a double value: ");
            ProUtilDoubleGet(NULL, NULL, &user_value.d_val);
            ProTKSprintf(astr, (char*)"Value:\t%f\n", user_value.d_val);
            ProTKFprintf(fp, astr);
            p_value = (void*)&user_value.d_val;
            break;
        case PRO_PARAM_STRING:
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a string value: ");
            ProUtilStringGet(user_value.s_val, NULL, PRO_LINE_SIZE);
            ProTKSprintf(astr, (char*)"Value:\t%s\n",
                                ProWstringToString(aname, user_value.s_val));
            ProTKFprintf(fp, astr);
            p_value = (void*)&user_value.s_val;
            break;
        case PRO_PARAM_INTEGER:
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a integer value: ");
            ProUtilIntGet(NULL, NULL, &user_value.i_val);
            ProTKSprintf(astr, (char*)"Value:\t%d\n", user_value.i_val);
            ProTKFprintf(fp, astr);
            p_value = (void*)&user_value.i_val;
            break;
        case PRO_PARAM_BOOLEAN:
            def_bool = 0;
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a Yes/No value[NO]: ");
            user_value.l_val = ProUtilYesnoGet(&def_bool);
            ProTKSprintf(astr, (char*)"Value:\t%d\n", user_value.l_val);
            ProTKFprintf(fp, astr);
            p_value = (void*)&user_value.l_val;
            break;
        default:
            return( -1 );
    }

    status = ProParamvalueSet( &new_value, p_value, new_value_type );
    TEST_CALL_REPORT( "ProParamvalueSet()", "ProTestNewParam()",
				status, status != PRO_TK_NO_ERROR );

    status = ProParameterWithUnitsCreate(p_modelitem, name, &new_value, NULL, &new_param);
    TEST_CALL_REPORT("ProParameterWithUnitsCreate()", "ProTestNewParam()", status,
                                                status != PRO_TK_NO_ERROR);
    return( 0 );
}

/*====================================================================*\
  Function : ProTestSetParam
  Purpose  : Allow the user to set the value of a parameter
\*====================================================================*/
static int ProTestSetParam(ProMdl model)
{
    ProName name;
    ProType type;
    ProParameter param;
    ProParamvalue value;
    ProParamvalueType value_type;
    ProParamvalueValue dummy_value;
    ProError status;
    char def_bool;
    char astr[PRO_LINE_SIZE];
    char aname[PRO_NAME_SIZE*sizeof(wchar_t)];
    ProModelitem sel_obj;


    type = ProTestGetElemType(PRO_B_FALSE);

    if( ProTestPickItem(model, type, &sel_obj) )
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Enter the name of the parameter: ");
        ProUtilStringGet(name, NULL, PRO_NAME_SIZE);

        status = ProParameterInit(&sel_obj, name, &param);
        TEST_CALL_REPORT("ProParameterInit()", "ProTestSetParam()", status,
                                                status == PRO_TK_COMM_ERROR);

	if( status == PRO_TK_NO_ERROR )
	  {
	    status = ProParameterValueWithUnitsGet(&param, &value, NULL);
	    TEST_CALL_REPORT("ProParameterValueWithUnitsGet()", "ProTestSetParam()",
			     status, status == PRO_TK_COMM_ERROR);
	    
	    status = ProParamvalueTypeGet( &value, &value_type );
	    TEST_CALL_REPORT("ProParamvalueTypeGet()", "ProTestSetParam()",
                                        status, status == PRO_TK_COMM_ERROR);
	    
	    /* Only test call */
	    status = ProParamvalueValueGet( &value, value_type, &dummy_value);
	    TEST_CALL_REPORT( "ProParamvalueValueGet()", "ProTestSetParam()",
			      status, status == PRO_TK_COMM_ERROR);
	  }

        if( status == PRO_TK_NO_ERROR )
        {
            ProTKSprintf(astr, (char*)"Name:\t%s\n", ProWstringToString(aname, name));
            ProTKFprintf(fp, astr);
            switch( value_type )
            {
                case PRO_PARAM_DOUBLE:
                    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a double value: ");
                    ProUtilDoubleGet(NULL, NULL, &value.value.d_val);
                    ProTKSprintf(astr, (char*)"Value:\t%f\n", value.value.d_val);
                    ProTKFprintf(fp, astr);
                    break;
                case PRO_PARAM_STRING:
                    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a string value: ");
                    ProUtilStringGet(value.value.s_val, NULL,
                                                                PRO_LINE_SIZE);
                    ProTKSprintf(astr,(char*)"Value:\t%s\n",
                                ProWstringToString(aname, value.value.s_val));
                    ProTKFprintf(fp, astr);
                    break;
                case PRO_PARAM_INTEGER:
                    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a integer value: ");
                    ProUtilIntGet(NULL, NULL, &value.value.i_val);
                    ProTKSprintf(astr, (char*)"Value:\t%d\n", value.value.i_val);
                    ProTKFprintf(fp, astr);
                    break;
                case PRO_PARAM_BOOLEAN:
                    def_bool = 0;
                    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
                                        "Please enter a Yes/No value[NO]: ");
                    value.value.l_val = ProUtilYesnoGet(&def_bool);
                    ProTKSprintf(astr, (char*)"Value:\t%d\n", value.value.l_val);
                    ProTKFprintf(fp, astr);
                    break;
                default:
                    return( -1 );
            }

            status = ProParameterValueWithUnitsSet(&param, &value, NULL);
            TEST_CALL_REPORT("ProParameterValueWithUnitsSet()", "ProTestSetParams()",
                                        status, status == PRO_TK_COMM_ERROR);
        }
        else
        {
            ProTKSprintf(astr, (char*)"Parameter '%s' does not exist\n",
                                                ProWstringToString(aname, name));
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", astr);

        }
    }

    return( 0 );
}

/*====================================================================*\
  Function : ProTestAddParam
  Purpose  : Add a parameter to a model item
\*====================================================================*/
static int ProTestAddParam(ProMdl model)
{
    ProType type;
    ProModelitem modelitem;

    type = ProTestGetElemType(PRO_B_FALSE);
    ProTKPrintf((char*)"type = %d\n", type);

    if( ProTestPickItem(model, type, &modelitem) )
        ProTestNewParam(model, &modelitem);

    return( 0 );
}


/*====================================================================*\
  Function : ProTestParamDeleteAction
  Purpose  : Allow the user to delete, reset or rename a parameter
\*====================================================================*/
static int ProTestParamDeleteAction(ProMdl model, int action)
{
    ProType type;
    ProParameter param;
    ProError status;
    char aname[PRO_NAME_SIZE];
    char astr[PRO_LINE_SIZE];
    ProModelitem sel_obj;

    type = ProTestGetElemType(PRO_B_FALSE);

    if( ProTestPickItem(model, type, &sel_obj))
    {
	  status = ProParameterSelect(&sel_obj, NULL, PRO_PARAMSELECT_ANY,
								  PRO_B_FALSE, NULL, &param, NULL);
        TEST_CALL_REPORT("ProParameterSelect()", "ProTestParamDeleteAction()",
                                status, status != PRO_TK_NO_ERROR && status != PRO_TK_USER_ABORT);
        if( status == PRO_TK_NO_ERROR )
        {
	    ProWstringToString(aname, param.id);
	    switch (action)
	    {
		case USER_RESET:
	            ProTKSprintf(astr, (char*)"Parameter '%s' reset...\n", aname);
		    ProTKFprintf(fp, astr);
		    status = ProParameterValueReset(&param);
		    TEST_CALL_REPORT("ProParameterValueReset()", 
					    "ProTestParamDeleteAction()",
					    status, status != PRO_TK_NO_ERROR);
		    break;
		case USER_DELETE:
                    ProTKSprintf(astr, (char*)"Parameter '%s' deleted...\n", aname);
		    ProTKFprintf(fp, astr);
		    status = ProParameterDelete(&param);
		    TEST_CALL_REPORT("ProParameterDelete()",
					    "ProTestParamDeleteAction()",
					    status, status != PRO_TK_NO_ERROR);
		    break;
		default:
		    ProTKFprintf(fp, (char*)"Error!\n");
		    break;
	    }
        }
    }

    return(0);
}



/*====================================================================*\
  Function : ProTestParamDesAction
  Purpose  : Allow the user to add/remove designation of param
\*====================================================================*/
static int ProTestParamDesAction(ProMdl model, int action)
{
    ProType type;
    ProParameter param;
    ProError status;
    char aname[PRO_NAME_SIZE];
    char astr[PRO_LINE_SIZE];
    ProModelitem sel_obj;
    ProBoolean des;

    type = ProTestGetElemType(PRO_B_FALSE);

    if( ProTestPickItem(model, type, &sel_obj))
    {
        status = ProParameterSelect(&sel_obj, NULL, PRO_PARAMSELECT_ANY,
									PRO_B_FALSE, NULL, &param, NULL);
        TEST_CALL_REPORT("ProParameterSelect()", "ProTestParamDeleteAction()",
                                status, status != PRO_TK_NO_ERROR && status != PRO_TK_USER_ABORT);
        if( status == PRO_TK_NO_ERROR )
        {
	    ProWstringToString(aname, param.id);
	    status = ProParameterDesignationVerify(&param, &des);
            TEST_CALL_REPORT("ProParameterDesignationVerify()",
					    "ProTestParamDeleteAction()", 
					    status, status != PRO_TK_NO_ERROR);

	    switch (action)
	    {
		case USER_DES_ADD:
		    if (des)
		    {
			ProTKSprintf(astr, (char*)"Parameter %s already designated", 
			    aname); 
			break;
		    }

		    status = ProParameterDesignationAdd(&param);
		    TEST_CALL_REPORT("ProParameterDesignationAdd()", 
					    "ProTestParamDeleteAction()", 
					    status, status != PRO_TK_NO_ERROR);
		    if (status == PRO_TK_NO_ERROR)
		    {
			ProTKSprintf(astr, (char*)"Parameter %s designated", aname);
		    }

		    break;
		case USER_DES_REMOVE:
		    if (!des)
		    {
			ProTKSprintf(astr, (char*)"Parameter %s not designated", aname);
			break;
		    }

		    status = ProParameterDesignationRemove(&param);
		    TEST_CALL_REPORT("ProParameterDesignationRemove()", 
					    "ProTestParamDeleteAction()", 
					    status, status != PRO_TK_NO_ERROR);
		    if (status == PRO_TK_NO_ERROR)
		    {
			ProTKSprintf(astr, (char*)"Removed designation from parameter %s",
			    aname);
		    }

		    break;
		default:
		    ProUtilstrcpy(astr, "Error!");
		    break;
	    }

	    ProTKFprintf(fp, (char*)"%s\n", astr);
    	    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", astr);
        }
    }

    return(0);
}