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



/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProArray.h>
#include <ProFeature.h>
#include <ProMdl.h>
#include <ProMenu.h>
#include <ProProcstep.h>
#include <ProUtil.h>
#include <ProSolid.h>

/*--------------------------------------------------------------------*\
C System includes
\*--------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "TestFiletypes.h"
#include "UtilFiles.h"
#include "UtilMessage.h"
#include "UtilCollect.h"
#include "UtilTree.h"
#include "UtilMenu.h"
#include "UtilString.h"
#include <ProTKRunTime.h>
#include <ProMessage.h>
#include <PTApplsUnicodeUtils.h>
#include <ProTKRunTime.h>
#include <ProExpldstate.h>
/*--------------------------------------------------------------------*\
Application macros
\*--------------------------------------------------------------------*/

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

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

/*====================================================================*\
  Function : ProUtilProcstepDataGet
  Purpose  : Get value data 
\*====================================================================*/

ProError ProUtilProcstepDataGet (
    ProProcstep *procstep,      /* Pointer on  ProProcstep type element */
    int element_id,             /* id_elem                              */
    ProValueData **valuedata)   /* ProArray                             */
{
    ProValue *p_values;
    ProElement elem_tree, p_element;
    ProElempathItem elempathitem;
    int path_size = 1, multi_size, i;
    ProError err;
    ProValueData pval_data;
    ProValueDataType elem_type;
    ProBoolean is_multival;
    ProValueData value_data;
    
/*-------------------------------------------------------------------------*\
    Get  tree element
\*-------------------------------------------------------------------------*/

    elempathitem.type = PRO_ELEM_PATH_ITEM_TYPE_ID;
    elempathitem.path_item.elem_id = element_id;
    
    err = ProFeatureElemtreeExtract ((ProFeature*)procstep, NULL, PRO_FEAT_EXTRACT_NO_OPTS, &elem_tree);
    TEST_CALL_REPORT("ProFeatureElemtreeExtract()",
		     "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR); 

    err = ProUtilElemtreeElementGet (elem_tree, &elempathitem,
				     path_size, &p_element);
   
    if (err != PRO_TK_NO_ERROR)
	return (err);

/*-------------------------------------------------------------------------*\
    Get  element values
\*-------------------------------------------------------------------------*/
    err = ProElementIsMultival(p_element, NULL, &is_multival);
    if (is_multival == PRO_B_TRUE)
    {
        err = ProArrayAlloc(0, sizeof(ProValue),
            1, (ProArray*)&p_values);
        TEST_CALL_REPORT("ProArrayAlloc()",
            "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR);

        err = ProElementValuesGet(p_element, &p_values);
        TEST_CALL_REPORT("ProElementValuesGet()",
            "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR);
        err = ProArraySizeGet((ProArray)p_values, &multi_size);
        TEST_CALL_REPORT("ProArraySizeGet()",
            "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR);

        for (i = 0; i < multi_size; i++)
        {
            err = ProValueDataGet(p_values[i], &pval_data);
            TEST_CALL_REPORT("ProValueDataGet()",
                "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR);

            err = ProArrayObjectAdd((ProArray*)valuedata,
                0, 1, (void*)&pval_data);
            TEST_CALL_REPORT("ProArrayObjectAdd()",
                "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR);
        }

        err = ProArrayFree((ProArray*)&p_values);
        TEST_CALL_REPORT("ProArrayFree()",
            "ProUtilProcstepDataGet", err, err != PRO_TK_NO_ERROR);
    }
    else
    {
        err = ProElementValuetypeGet(p_element, &elem_type);
        if (err == PRO_TK_NO_ERROR)
        {
            switch (elem_type)
            {
                case PRO_VALUE_TYPE_TRANSFORM:
                {
                    ProMatrix elem_value;
                    err = ProElementTransformGet(p_element,(ProElementTransformOptions)NULL, elem_value);
                    if (err == PRO_TK_NO_ERROR)
                    {
                        value_data.type = PRO_VALUE_TYPE_TRANSFORM;
                        err = ProValuedataTransformSet(&value_data, elem_value);
                        err = ProArrayObjectAdd((ProArray*)valuedata, 0, 1, (void*)&value_data);
                    }
                    break;
                }
                case PRO_VALUE_TYPE_INT:
                {
                    int elem_value;
                    err = ProElementIntegerGet(p_element, (ProElementIntegerOptions)NULL, &elem_value);
                    if (err == PRO_TK_NO_ERROR)
                    {
                        value_data.type = PRO_VALUE_TYPE_INT;
                        value_data.v.i = elem_value;
                        err = ProArrayObjectAdd((ProArray*)valuedata, 0, 1, (void*)&value_data);
                    }
                    break;
                }
                case PRO_VALUE_TYPE_DOUBLE:
                {
                    double dbl_val;
                    err = ProElementDoubleGet(p_element, (ProElementDoubleOptions)NULL, &dbl_val);
                    if (err == PRO_TK_NO_ERROR)
                    {
                        value_data.type = PRO_VALUE_TYPE_DOUBLE;
                        value_data.v.d = dbl_val;
                        err = ProArrayObjectAdd((ProArray*)valuedata, 0, 1, (void*)&value_data);
                    }
                    break;
                }
                case PRO_VALUE_TYPE_STRING:
                {
                    char* str_value;
                    err = ProElementStringGet(p_element, (ProElementStringOptions)NULL, &str_value);
                    if (err == PRO_TK_NO_ERROR)
                    {
                        value_data.type = PRO_VALUE_TYPE_STRING;
                        err = ProValuedataStringSet(&value_data, (char*)str_value);
                        err = ProArrayObjectAdd((ProArray*)valuedata, 0, 1, (void*)&value_data);
                    }
                    break;
                }
                case PRO_VALUE_TYPE_WSTRING:
                {
                    wchar_t* str_value;
                    err = ProElementWstringGet(p_element, (ProElementWstringOptions)NULL, &str_value);
                    if (err == PRO_TK_NO_ERROR)
                    {
                        value_data.type = PRO_VALUE_TYPE_WSTRING;
                        err = ProValuedataWstringSet(&value_data, str_value);
                        err = ProArrayObjectAdd((ProArray*)valuedata, 0, 1, (void*)&value_data);
                    }
                    break;
                }
                case PRO_VALUE_TYPE_BOOLEAN:
                {
                    ProBoolean elem_value;
                    err = ProElementBooleanGet(p_element, (ProElementBooleanOptions)NULL, &elem_value);
                    if (err == PRO_TK_NO_ERROR)
                    {
                        value_data.type = PRO_VALUE_TYPE_BOOLEAN;
                        value_data.v.b = elem_value;
                        err = ProArrayObjectAdd((ProArray*)valuedata, 0, 1, (void*)&value_data);
                    }
                    break;
                }
            }
        }
    }     
    return (err);
}
 
/*====================================================================*\
  Function : ProUtilProcstepTypeGet
  Purpose  : Get process step type 
\*====================================================================*/

ProError ProUtilProcstepTypeGet (int n_type,
				 ProProcstep *procstep,
				 char (*step_type)[2][13])
{
    ProError err= PRO_TK_NO_ERROR, status;
    ProValueData *valuedata;
    int n_array;
    
    switch (n_type)
    {
	case PRO_PROCSTEP_ASSEMBLE :
	    ProUtilstrcpy((*step_type)[0], "Assemble");
	    ProUtilstrcpy((*step_type)[1], "ASSEMBLED");
	    break;
	case PRO_PROCSTEP_DISASSEMBLE :
	    ProUtilstrcpy((*step_type)[0], "Disassemble");
	    ProUtilstrcpy((*step_type)[1], "DISASSEMBLED");
	    break;
	case PRO_PROCSTEP_REASSEMBLE :
	    ProUtilstrcpy((*step_type)[0], "Reassemble");
	    ProUtilstrcpy((*step_type)[1], "REASSEMBLED");
	    break;
	case PRO_PROCSTEP_REPOSITION :
	    ProUtilstrcpy((*step_type)[0], "Reposition");
	    ProUtilstrcpy((*step_type)[1], "REPOSITIONED");
	    break;
	case PRO_PROCSTEP_SURFACE :
	    ProUtilstrcpy((*step_type)[0], "Surface");
	    ProUtilstrcpy((*step_type)[1], "Surface");
	    break;
	case PRO_PROCSTEP_VOLUME :
	    ProUtilstrcpy((*step_type)[0], "Volume");
	    ProUtilstrcpy((*step_type)[1], "Volume");
	    break;
	case PRO_PROCSTEP_MFG_MODEL : 
	    ProUtilstrcpy((*step_type)[0], "Mfg_model");
	    ProUtilstrcpy((*step_type)[1], "Mfg_model");
	    break;
	case PRO_PROCSTEP_GENERAL :
	    ProUtilstrcpy((*step_type)[0], "General");

	    err = ProArrayAlloc (0, sizeof(ProValueData),
				 1, (ProArray*)&valuedata);
	    TEST_CALL_REPORT("ProArrayAlloc()", 
			     "ProUtilProcstepTypeGet",
			     err, err != PRO_TK_NO_ERROR);
	    
	    err = ProUtilProcstepDataGet (procstep,
					  PRO_E_GEN_STEP_TYPE,
					  &valuedata);
	    status = ProArraySizeGet ((ProArray)valuedata, &n_array);
	    TEST_CALL_REPORT("ProArraySizeGet()",
			     "ProUtilProcstepTypeGet", status,
			     status != PRO_TK_NO_ERROR);

	    if (err == PRO_TK_NO_ERROR && n_array != 0)
		ProWstringToString ((*step_type)[1], valuedata[0].v.w);

	    err = ProArrayFree ((ProArray*)&valuedata);
	    TEST_CALL_REPORT("ProArrayFree()", 
			     "ProUtilProcstepTypeGet",
			     err, err != PRO_TK_NO_ERROR);
	    
	    break;
	default:
	    ProUtilstrcpy((*step_type)[0], "unknow");
	}
    return err;
}

/*====================================================================*\
  Function : ProTestSetStep
  Purpose  : Select and set active process step 
\*====================================================================*/
ProError ProTestSetStep (
    ProAppData model,
    int var2)
{
    ProSolid solid = *((ProSolid*)model);
    ProError err;
    ProCharLine str;
    wchar_t **w_strings, **p_sel;
    ProName w_title;
    ProProcstep *p_steps, procstep, active;
    int n_steps, i, sel, n_sel, id;

/*-------------------------------------------------------------------------*\
    Find all process steps in the model
\*-------------------------------------------------------------------------*/

    err = ProUtilCollectProcstep(solid, &p_steps);
    if (err != PRO_TK_NO_ERROR)
	return (PRO_TK_NO_ERROR);

    err = ProArraySizeGet((ProArray)p_steps, &n_steps);
    TEST_CALL_REPORT("ProArraySizeGet()", 
			    "ProTestProcstep", err, err != PRO_TK_NO_ERROR);
    if (n_steps <= 0)
	return (PRO_TK_NO_ERROR);

/*-------------------------------------------------------------------------*\
   Create a menu for select active step 
\*-------------------------------------------------------------------------*/
    w_strings = (wchar_t**)calloc(n_steps+1, sizeof(wchar_t*));
    for (i=0; i<n_steps; i++)
    {
	w_strings[i] = (wchar_t*)calloc(1, sizeof(ProName));
	ProTKSprintf(str, "Step %d", i+1);
	ProStringToWstring(w_strings[i], str);
    } 
    w_strings[n_steps] = (wchar_t*)calloc(1, sizeof(ProName));


    ProStringToWstring(w_title, (char *)"Steps"); 
    ProUtilMsgPrint("gen", "TEST %0s", "Select a step");

    err = ProMenuStringsSelect(w_title, w_strings, 1, NULL, &p_sel, &n_sel);
    TEST_CALL_REPORT("ProMenuStringsSelect()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);

    if (err == PRO_TK_NO_ERROR)
    {
	for (i=0; i<=n_steps; i++)
	    if (ProUtilWstrCmp(w_strings[i], p_sel[0])==0)
		break;
	sel = i;
    }
    
/*-------------------------------------------------------------------------*\
   Free allocated memory 
\*-------------------------------------------------------------------------*/
    for (i=0; i<n_steps+1; i++)
	free(w_strings[i]);
    free(w_strings);

    if (err != PRO_TK_NO_ERROR || sel>n_steps)
	return (PRO_TK_NO_ERROR);
   
/*-------------------------------------------------------------------------*\
   Init procstep 
\*-------------------------------------------------------------------------*/
    if (sel<n_steps)
    {
	err = ProProcstepInit(solid, sel+1, PRO_VALUE_UNUSED, &procstep);
	TEST_CALL_REPORT("ProProcstepInit()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);
	ProTKSprintf(str, "Selected step has Id = %d", procstep.id);
	ProUtilMsgPrint("gen", "TEST %0s", str);
    }
    else
    {
	ProUtilMsgPrint("gen", "TEST %0s", "Enter proc step Id [QUIT]:");
	err = ProMessageIntegerRead(NULL, &id);
	TEST_CALL_REPORT("ProMessageIntegerRead()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);
	if (err != PRO_TK_NO_ERROR)
	    return (PRO_TK_NO_ERROR);

	err = ProProcstepInit(solid, PRO_VALUE_UNUSED, id, &procstep);
	TEST_CALL_REPORT("ProProcstepInit()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);

    }

/*-------------------------------------------------------------------------*\
   Compare with current active step 
\*-------------------------------------------------------------------------*/
    err = ProProcstepActiveGet(solid, &active);
    TEST_CALL_REPORT("ProProcstepActiveGet()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);
    if (active.id == procstep.id && err == PRO_TK_NO_ERROR)
	ProUtilMsgPrint("gen", "TEST %0s", "Selected step already active");
    else 
    {
/*-------------------------------------------------------------------------*\
  Set new set 
\*-------------------------------------------------------------------------*/
	err = ProProcstepActiveSet(solid, &procstep);
	TEST_CALL_REPORT("ProProcstepActiveSet()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);
	if (err == PRO_TK_NO_ERROR)
	    ProUtilMsgPrint("gen", "TEST %0s", "Active step set successfully");
			    
	err = ProSolidRegenerate(solid, (int)PRO_REGEN_ALLOW_CONFIRM);

    	TEST_CALL_REPORT("ProSolidRegenerate()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);
#ifndef PT_PRODUCTS_BUILD
	err = ProSolidDisplay(solid);
    	TEST_CALL_REPORT("ProSolidDisplay()", 
			    "ProtestSetStep", err, err != PRO_TK_NO_ERROR);
#endif
    }
    
/*-------------------------------------------------------------------------*\
   Activate or Unactivate Next#step and Previous#step buttons
\*-------------------------------------------------------------------------*/
    err = ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Previous step",
			       p_steps[0].id != procstep.id);
    err = ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Next step", 
			       p_steps[n_steps-1].id != procstep.id);
    err = ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Info", 1);
    
    err = ProArrayFree((ProArray*)&p_steps);
    TEST_CALL_REPORT("ProArrayFree()", 
		     "ProtestSetStep", err, err != PRO_TK_NO_ERROR);

    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : ProTestStep
  Purpose  : Set next process step to be active 
\*====================================================================*/
ProError ProTestStep (
    ProAppData model,
    int flag)
{
    ProProcstep active, *p_steps;
    ProError err;
    ProSolid solid = *((ProSolid*)model);
    int n_steps, des = 1, i;
    
    if (!flag)
	des = -1;
/*-------------------------------------------------------------------------*\
    Find all process steps in the model
\*-------------------------------------------------------------------------*/
    
    err = ProUtilCollectProcstep(solid, &p_steps);
    if (err != PRO_TK_NO_ERROR)
	return (PRO_TK_NO_ERROR);

    err = ProArraySizeGet((ProArray)p_steps, &n_steps);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestStep", err, err != PRO_TK_NO_ERROR);
         
    err = ProProcstepActiveGet (solid, &active);
    TEST_CALL_REPORT("ProProcstepActiveGet()",
		     "ProTestStep", err, err != PRO_TK_NO_ERROR);
		     
    if (err != PRO_TK_NO_ERROR)
    {
	active = p_steps[0];
	des = 0;
    }
    err = ProProcstepNumberGet(solid, &active, &i);
    TEST_CALL_REPORT("ProProcstepNumberGet()",
		     "ProTestStep", err, err != PRO_TK_NO_ERROR);
    i+=des - 1;
    err = ProProcstepActiveSet(solid, &p_steps[i]);
    TEST_CALL_REPORT("ProProcstepActiveSet()",
		     "ProTestStep", err, err != PRO_TK_NO_ERROR);
    
    err = ProSolidRegenerate(solid, (int)PRO_REGEN_ALLOW_CONFIRM);

    TEST_CALL_REPORT("ProSolidRegenerate()", 
		     "ProTestStep", err, err != PRO_TK_NO_ERROR);
#ifndef PT_PRODUCTS_BUILD
    err = ProSolidDisplay(solid);
    TEST_CALL_REPORT("ProSolidDisplay()", 
		     "ProTestStep", err, err != PRO_TK_NO_ERROR);
#endif
    
/*-------------------------------------------------------------------------*\
   Activate or Unactivate Next#step and Previous#step buttons
\*-------------------------------------------------------------------------*/
    ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Previous step", i>0);
    ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Next step", i+1<n_steps);
    ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Info", 1);
    
    err = ProArrayFree((ProArray*)&p_steps);
    
    return(PRO_TK_NO_ERROR);    
}

/*====================================================================*\
  Function : ProTestInfo
  Purpose  : Get info for current process step 
\*====================================================================*/
ProError ProTestInfo (ProAppData model, int var2)
{
    char messagefile[] = "teststeps.inf", sname[PRO_MDLNAME_SIZE],
	stype[2][13], msg_str[PRO_LINE_SIZE], strout[PRO_PATH_SIZE],
	*sign_eq = (char *)"======================================================",
	*sign_ln = (char *)"------------------------------------------------------",
	s_description[1000];
    FILE *pfile;
    ProProcstep procstep;
    ProError err, status;
    ProSolid solid = (*(ProSolid*)model);
    ProValueData *valuedata;
    ProModelitem model_item;
    wchar_t msgfile[PRO_NAME_SIZE], mdl_wname[PRO_MDLNAME_SIZE];
    int n_step, str_len, i, size_array, n_gen, element_id;
    ProExpldstate expld_state;
    ProSimprep simp_rep;
        
    pfile = (FILE *)PTApplsUnicodeFopen (messagefile, "w");
    err = ProArrayAlloc (0, sizeof(ProValueData),
			 1, (ProArray*)&valuedata);
    TEST_CALL_REPORT("ProArrayAlloc()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
    
/*-------------------------------------------------------------------------*\
    Get model name 
\*-------------------------------------------------------------------------*/
    err = ProMdlMdlnameGet ((ProMdl)solid, mdl_wname);
    ProWstringToString (sname, mdl_wname);
    ProTKSprintf(strout, "PROCESS NAME = %s\n", sname);
    strncat(strout, sign_eq, strlen(strout)-1);
    ProTKFprintf(pfile,"\n%s\n\n", strout);
    
/*-------------------------------------------------------------------------*\
    Get active process it step type and step number
\*-------------------------------------------------------------------------*/
    
    err = ProProcstepActiveGet (solid, &procstep); 
    TEST_CALL_REPORT("ProProcstepActiveGet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);

    err = ProProcstepNumberGet (solid, &procstep, &n_step);
    TEST_CALL_REPORT("ProProcstepNumberGet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
  
    err = ProUtilProcstepDataGet (&procstep, PRO_E_PROCESS_STEP_TYPE,
				  &valuedata);

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

    if (err == PRO_TK_NO_ERROR && size_array != 0)
	err = ProUtilProcstepTypeGet (valuedata[0].v.i, &procstep, &stype);
   
    n_gen = valuedata[0].v.i == PRO_PROCSTEP_GENERAL ? 1:0;
    
    ProTKSprintf(strout, "STEP %d: %s", n_step, stype[n_gen]);
    str_len = strlen(strout);
    ProUtilstrncpy(msg_str, sign_ln, str_len);
    msg_str[str_len]='\0';
    ProTKFprintf(pfile," %s\n %s\n %s", msg_str, strout, msg_str);

    err = ProArraySizeSet ((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArraySizeSet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
		     
/*-------------------------------------------------------------------------*\
    Get components
\*-------------------------------------------------------------------------*/

    if (n_gen)
    {	
	element_id = PRO_E_GEN_STEP_REFS;
	ProTKFprintf(pfile, "\n\n ITEM REFERENCED\n");
    }
    else
    {
	ProTKFprintf(pfile, "\n\n COMPONENTS %s\n", stype[1]);
	element_id = PRO_E_COMPONENTS;
    }
    
    err = ProUtilProcstepDataGet (&procstep, element_id, &valuedata); 

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

    if (err == PRO_TK_NO_ERROR && size_array != 0)
    {
	for (i=size_array-1; i>=0; i--)
	{
	    err = ProSelectionModelitemGet (valuedata[i].v.r, &model_item);
	    TEST_CALL_REPORT("ProSelectionModelitemGet()", 
	    	"ProTestInfo", err, err != PRO_TK_NO_ERROR &&
		err != PRO_TK_BAD_INPUTS);

	    ProUtilstrcpy(sname, "*");	    
	    if (err == PRO_TK_NO_ERROR)
	    {	    
		err = ProMdlMdlnameGet (model_item.owner, mdl_wname);
		TEST_CALL_REPORT("ProMdlMdlnameGet()", 
			     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
		ProWstringToString (sname, mdl_wname);
	    }	    
	    ProTKFprintf (pfile, "    %s\n", sname);
	}
    }
    else
	ProTKFprintf(pfile, "    None\n"); 

    err = ProArraySizeSet((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArraySizeSet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
		    	    
/*-------------------------------------------------------------------------*\
    Get Abreviated Description
\*-------------------------------------------------------------------------*/
    err = ProUtilProcstepDataGet (&procstep, PRO_E_DESCRIPTION, &valuedata);

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);
 
    if (err == PRO_TK_NO_ERROR && size_array != 0)
    {
	ProWstringToString (s_description, valuedata[size_array-1].v.w);
	if (size_array > 1)
	    ProUtilstrcat (s_description, "...");
    }
    else
	ProUtilstrcpy (s_description, "No description");

    ProTKFprintf (pfile, "\n ABREVIATED DESCRIPTION\n    %s\n", s_description);

    err = ProArraySizeSet ((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArrayObjectRemove()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	
/*-------------------------------------------------------------------------*\
     Get Time Estimate
\*-------------------------------------------------------------------------*/

    err = ProUtilProcstepDataGet (&procstep, PRO_E_TIME_ESTIMATE, &valuedata);

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

    if ((err == PRO_TK_NO_ERROR) && (valuedata[0].v.d > 0.0) && size_array != 0)
	ProTKFprintf (pfile, "\n TIME ESTIMATE\n    %f HOURS\n", valuedata[0].v.d); 
    else
	ProTKFprintf (pfile, "\n TIME ESTIMATE\n    No assigned\n");

    err = ProArraySizeSet ((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArraySizeSet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	
/*-------------------------------------------------------------------------*\
    Get Cost Estimate
\*-------------------------------------------------------------------------*/

    err = ProUtilProcstepDataGet (&procstep, PRO_E_COST_ESTIMATE, &valuedata);
    
    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

    if ((err == PRO_TK_NO_ERROR) && (valuedata[0].v.d != 0.0) && size_array != 0)
	ProTKFprintf (pfile, "\n COST ESTIMATE\n    %f\n", valuedata[0].v.d); 
    else
	ProTKFprintf (pfile, "\n COST ESTIMATE\n    Not Assigned\n");

    err = ProArraySizeSet ((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArraySizeSet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	
/*-------------------------------------------------------------------------*\
    Get Simplfd Rep
\*-------------------------------------------------------------------------*/

    err = ProUtilProcstepDataGet (&procstep, PRO_E_SIMPLFD_REP,&valuedata);

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

#ifndef PT_PRODUCTS_BUILD
    if (err == PRO_TK_NO_ERROR && size_array != 0 && valuedata[0].v.i != -1)
    {
	err = ProSimprepInit (NULL, valuedata[0].v.i, solid, &simp_rep);
	TEST_CALL_REPORT("ProSimprepInit()", 
			 "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	err = ProModelitemNameGet ((ProModelitem*)&simp_rep, mdl_wname);
	TEST_CALL_REPORT("ProModelitemNameGet()", 
			 "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	ProWstringToString (strout, mdl_wname);
    }
    else
#endif
	ProUtilstrcpy (strout, "No Assigned");

    ProTKFprintf (pfile, "\n SIMPLIFIED REPRESENTATION\n    %s\n", strout);

    err = ProArraySizeSet((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArraySizeSet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	
/*-------------------------------------------------------------------------*\
    Get Explode State
\*-------------------------------------------------------------------------*/

    err = ProUtilProcstepDataGet (&procstep, PRO_E_EXPLODE_STATE,&valuedata);

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

    if (err == PRO_TK_NO_ERROR && size_array != 0)
    {
	ProExpldstateActiveGet (solid, &expld_state);
	err = ProModelitemNameGet ((ProModelitem*)&expld_state, mdl_wname);
	TEST_CALL_REPORT("ProModelitemNameGet()", 
			 "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	ProWstringToString (strout, mdl_wname);
    }
    else
	ProUtilstrcpy (strout, "No Explode");

    ProTKFprintf (pfile, "\n EXPLODE STATE\n    %s\n", strout);
    
    err = ProArraySizeSet ((ProArray*)&valuedata, 0);
    TEST_CALL_REPORT("ProArraySizeSet()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);
	
/*-------------------------------------------------------------------------*\
    Get Full Description
\*-------------------------------------------------------------------------*/
    err = ProUtilProcstepDataGet (&procstep, PRO_E_DESCRIPTION, &valuedata);

    status = ProArraySizeGet ((ProArray)valuedata, &size_array);
    TEST_CALL_REPORT("ProArraySizeGet()",
		     "ProTestInfo", status, status != PRO_TK_NO_ERROR);

    ProUtilstrcpy (s_description, "");
    if (err == PRO_TK_NO_ERROR && size_array != 0)
	for (i=size_array-1; i>=0; i--)
	{
	    ProWstringToString (strout, valuedata[i].v.w);
	    ProUtilstrcat (s_description, (const char*)strout);
	    ProUtilstrcat (s_description, "\n");
	}
    else 
	ProUtilstrcpy (s_description, "No description"); 

    ProTKFprintf (pfile, "\n FULL DESCRIPTION\n    %s\n", s_description);
     
/*-------------------------------------------------------------------------*\
    Display Info
\*-------------------------------------------------------------------------*/
    fclose (pfile);

    err = ProArrayFree ((ProArray*)&valuedata);
    TEST_CALL_REPORT("ProArrayFree()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);

    ProStringToWstring (msgfile, messagefile);

    err = ProInfoWindowDisplay(msgfile, NULL, NULL);
    TEST_CALL_REPORT("ProInfoWindowDisplay()", 
		     "ProTestInfo", err, err != PRO_TK_NO_ERROR);

    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : ProTestProcstep
  Purpose  :  
\*====================================================================*/
int ProTestProcstep()
{
    ProProcstep *p_steps, active;
    ProSolid solid;
    ProError err;
    int n_steps, menu_id, action;
    const int prev = 0, next = 1;

    err = ProMdlCurrentGet((ProMdl*)&solid);
    TEST_CALL_REPORT("ProMdlCurrentGet()", 
			    "ProTestProcstep", err, err != PRO_TK_NO_ERROR);
/*-------------------------------------------------------------------------*\
    Find all process steps in the model
\*-------------------------------------------------------------------------*/

    err = ProUtilCollectProcstep(solid, &p_steps);
    if (err != PRO_TK_NO_ERROR)
	return (0);

    err = ProArraySizeGet((ProArray)p_steps, &n_steps);
    TEST_CALL_REPORT("ProArraySizeGet()", 
			    "ProTestProcstep", err, err != PRO_TK_NO_ERROR);
    if (n_steps <= 0)
	return (0);

/*-------------------------------------------------------------------------*\
    Add -Step#Regen menu
\*-------------------------------------------------------------------------*/

    ProMenuPush();
    
    ProMenuFileRegister ((char *)"-Step Regen", (char *)"playstep.mnu", &menu_id);
    ProMenubuttonActionSet ((char *)"-Step Regen", (char *)"Set step",
			    (ProMenubuttonAction)ProTestSetStep, &solid, 0);
    ProMenubuttonActionSet ((char *)"-Step Regen", (char *)"Previous step",
			    (ProMenubuttonAction)ProTestStep, &solid, prev);
    ProMenubuttonActionSet ((char *)"-Step Regen", (char *)"Next step",
			    (ProMenubuttonAction)ProTestStep, &solid, next);
    ProMenubuttonActionSet ((char *)"-Step Regen", (char *)"Info",
			    (ProMenubuttonAction)ProTestInfo, &solid, 0);
    ProMenubuttonActionSet ((char *)"-Step Regen", (char *)"Tk done -Step Regen",
			    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    ProMenubuttonActionSet ((char *)"-Step Regen", (char *)"-Step Regen",
			    (ProMenubuttonAction)ProMenuDelete, NULL, 0);

    err = ProMenuCreate (PROMENUTYPE_MAIN,(char *)"-Step Regen", &menu_id );


    err = ProProcstepActiveGet (solid, &active);
    TEST_CALL_REPORT("ProProcstepActiveGet()",
		     "ProtestSetStep", err, err != PRO_TK_NO_ERROR);

    ProUtilMenubuttonActivate ((char *)"-Step Regen",(char *)"Previous step",
			       p_steps[0].id != active.id &&
			       err == PRO_TK_NO_ERROR);
    ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Next step",
			       p_steps[n_steps-1].id != active.id);
    ProUtilMenubuttonActivate ((char *)"-Step Regen", (char *)"Info", err == PRO_TK_NO_ERROR);

    ProMenuProcess ((char *)"-Step Regen", &action);
    ProMenuPop();
            
    return (0);
}