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


/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProAssembly.h>
#include <ProElemId.h>
#include <ProElement.h>
#include <ProExpldstate.h>
#include <ProFeatType.h>
#include <ProMdl.h>
#include <ProMessage.h>
#include <ProModelitem.h>
#include <ProMenu.h>
#include <ProSelection.h>
#include <ProSolid.h>
#include <ProUtil.h>
#include <ProValue.h>
#include <ProWindows.h>
#include <ProSkeleton.h>
#include <ProAsmcomp.h>

#if (PRO_MACHINE == SUN4 || PRO_MACHINE == SOLARISx64 || PRO_MACHINE == HP8000)
#include <unistd.h>
#elif(PRO_MACHINE == i486_nt || PRO_MACHINE == x86_win64)  
#include <windows.h>
#endif

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "TestSleep.h"
#include "TestFiletypes.h"
#include "UtilFiles.h"
#include "UtilMessage.h"
#include "UtilString.h"
#include "UtilNames.h"
#include "UtilCollect.h"
#include "UtilTree.h"
#include "UtilMenu.h"
#include "PTApplsUnicodeUtils.h"

/*--------------------------------------------------------------------*\
    Application macros
\*--------------------------------------------------------------------*/
#define TEST_ASM_EXPLODE		1
#define TEST_ASM_UNEXPLODE		2
#define TEST_ASM_EXPLODE_LIST   	3
#define TEST_ASM_SET_CURRENT_EXPLODE	4

#define TEST_ASMCOMP_CONSTR_REDEF	10
#define TEST_ASMCOMP_REGENERATE		11
#define TEST_ASMCOMP_INFO		12
#define TEST_ASMCOMP_PACKAGE_MOVE	13
#define TEST_ASMCOMP_CONSTR_REMOVE	14	
#define TEST_ASMCOMP_ASSEMBLE		15
#define TEST_ASMCOMP_REDEFINE		16
#define TEST_ASMCOMP_TREE_INFO		17

#define TEST_ASMCOMP_PACKAGE_MOVE20     18

#define TEST_ASMCOMP_MECHANISM      19

#define TEST_ASMCOMP_CREATE		20
#define TEST_ASMCOMP_REPLACE		21



#define TEST_ASMCOMP_MOTION_UNDEF       PRO_M_UNDEF
#define TEST_ASMCOMP_MOTION_ORIENTMODE  PRO_M_ORIENTMODE
#define TEST_ASMCOMP_MOTION_TRANSLATE   PRO_M_TRANSLATE
#define TEST_ASMCOMP_MOTION_ROTATE      PRO_M_ROTATE
#define TEST_ASMCOMP_MOTION_ADJUST      PRO_M_ADJUST
#define TEST_ASMCOMP_SHOWUI_DIALOG      PRO_B_TRUE
#define TEST_ASMCOMP_SHOWUI_ACTION      PRO_B_FALSE
#define TEST_ASMCOMP_REF_VIEW_PLANE     PRO_M_VIEW_PLANE
#define TEST_ASMCOMP_REF_SEL_PLANE      PRO_M_SEL_PLANE
#define TEST_ASMCOMP_REF_ENTITY_EDGE    PRO_M_ENTITY_EDGE
#define TEST_ASMCOMP_REF_PLANE_NORMAL   PRO_M_PLANE_NORMAL
#define TEST_ASMCOMP_REF_2_POINTS       PRO_M_2_POINTS
#define TEST_ASMCOMP_REF_CSYS_X         PRO_M_CSYS_X
#define TEST_ASMCOMP_REF_CSYS_Y         PRO_M_CSYS_Y
#define TEST_ASMCOMP_REF_CSYS_Z         PRO_M_CSYS_Z

/*--------------------------------------------------------------------*\
Application data types
\*--------------------------------------------------------------------*/
typedef struct pro_test_asm_comp_type_str
{
    ProAsmcompType type;
    char *str;
} ProTestAsmcompTypeStr;

typedef struct app_data
{
    ProAssembly assembly;
    FILE *fp;
} ProTestAppData;

typedef struct tag_menubut
{
    char *button;
    int action;
} ProTestMenuButton;

ProError ProTestExpldstateVisit(ProGeomitem	*p_geomitem,
                          ProError err, ProAppData p_appdata);
/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/

/*====================================================================*\
  Function : ProTestMenuDynamicRegister ()
  Purpose  : Dinamically register of menu
\*====================================================================*/
int ProTestMenuDynamicRegister (
    char* name_menu,
    ProTestMenuButton buttons[],
    int n_but)
{
    int i, dummy;
    ProError status;
    wchar_t **names;

    ProUtilMenuStringsAlloc( &names );

    for (i=0; i<n_but; i++)
    {
        ProUtilMenuStringsStrAdd( &names, buttons[i].button );
    }

    status = ProMenuFromStringsRegister ( name_menu, NULL, names, NULL,
        NULL, &dummy);
    TEST_CALL_REPORT("ProMenuFromStringsRegister()",
        "ProTestAsmcompFunc()", status, status != PRO_TK_NO_ERROR);

    ProUtilMenuStringsFree( &names );

    return (dummy);
}

/*====================================================================*\
  Function : ProTestAsmFunc()
  Purpose  : to test some ProAssembly functions
\*====================================================================*/
int ProTestAsmFunc(ProMdl *model)
{
    ProError 		status;
    int                 menu_id;    /* The identifier of the created menu */
    int                 menu_action;
 
    int			ProTestAsmExplode(ProAppData _appdata,int option);


    /* Load menu from file */
    status = ProMenuFileRegister((char *)"TkExplodeState", (char *)"tkexpld.mnu",
                                  &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestAsmFunc()",
                        status, status != PRO_TK_NO_ERROR );

    /* Define menu buttons */
    ProMenubuttonActionSet((char *)"TkExplodeState", (char *)"Explode",
        (ProMenubuttonAction)ProTestAsmExplode, model, TEST_ASM_EXPLODE );
    ProMenubuttonActionSet((char *)"TkExplodeState", (char *)"Unexplode",
        (ProMenubuttonAction)ProTestAsmExplode, model, TEST_ASM_UNEXPLODE );
    ProMenubuttonActionSet((char *)"TkExplodeState",(char *)"Set Current",
        (ProMenubuttonAction)ProTestAsmExplode, model, 
	TEST_ASM_SET_CURRENT_EXPLODE );
    ProMenubuttonActionSet((char *)"TkExplodeState", (char *)"List",
        (ProMenubuttonAction)ProTestAsmExplode, model, TEST_ASM_EXPLODE_LIST );
    ProMenubuttonActionSet((char *)"TkExplodeState", (char *)"TkExplodeState Done",
        (ProMenubuttonAction)ProMenuDelete, model, 0 );
    ProMenubuttonActionSet((char *)"TkExplodeState", (char *)"TkExplodeState",
        (ProMenubuttonAction)ProMenuDelete, model, 0 );

    /* Run menu */
    status = ProMenuCreate( PROMENUTYPE_MAIN, (char *)"TkExplodeState", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestAsmFunc()",
                        status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
        status = ProMenuProcess((char *)"TkExplodeState", &menu_action );
        TEST_CALL_REPORT( "ProMenuProcess()", "ProTestAsmFunc()",
                            status, status != PRO_TK_NO_ERROR );
    }


    return (0);
}



/*====================================================================*\
  Function : ProTestAsmExplode()
  Purpose  : to test assembly explosions
\*====================================================================*/
int ProTestAsmExplode( 
    ProAppData		p_appdata,
    int			option
)
{
    ProError		status;
    ProAssembly		p_assembly;
    ProExpldstate	expldstate;
    ProExpldstate       current_expldstate;
    ProBoolean		is_exploded;
    FILE		*fp;
    ProGeomitem         *geomitems;
    int                 i, geomitems_num;


    p_assembly = *((ProAssembly*)p_appdata);
    memset( &expldstate, 0, sizeof(ProExpldstate) );
    memset( &current_expldstate, 0, sizeof(ProExpldstate) );

    status = ProAssemblyIsExploded( p_assembly, &is_exploded );
    TEST_CALL_REPORT( "ProAssemblyIsExploded()", "ProTestAsmExplode()",
				    status, status != PRO_TK_NO_ERROR);

    status = ProExpldstateActiveGet( p_assembly, &current_expldstate );
    TEST_CALL_REPORT( "ProExpldstateActiveGet()", "ProTestAsmExplode()",
                                    status, status != PRO_TK_NO_ERROR);

    switch( option )
    {
      case TEST_ASM_EXPLODE:
	if( is_exploded != PRO_B_TRUE )
	{
            status = ProAssemblyExplode( p_assembly );
            TEST_CALL_REPORT( "ProAssemblyExplode()", "ProTestAsmExplode()",
            	status, status != PRO_TK_NO_ERROR);
       	    
	    if( status == PRO_TK_NO_ERROR ) 
	    	ProUtilMsgPrint( "gen", "TEST %0s", "Assembly exploded" );
	}
	else
	    ProUtilMsgPrint( "gen", "TEST %0s", "Assembly already exploded" );
	break;

      case TEST_ASM_UNEXPLODE:
        if( is_exploded != PRO_B_FALSE )
        {
            status = ProAssemblyUnexplode( p_assembly );
            TEST_CALL_REPORT( "ProAssemblyUnexplode()", "ProTestAsmExplode()",
            	status, status != PRO_TK_NO_ERROR);

            if( status == PRO_TK_NO_ERROR )
        	ProUtilMsgPrint( "gen", "TEST %0s", "Assembly unexploded" );
        }
        else
            ProUtilMsgPrint( "gen", "TEST %0s", "Assembly already unexploded" );
	break;

      case TEST_ASM_EXPLODE_LIST:
	fp = PTApplsUnicodeFopen( "explode.lst", "wt" );
	if( fp != NULL )
	{
            ProTKFprintf( fp, "!--------------------------\n" );
	    ProTKFprintf( fp, "!EXPLODE NAME\tOWNER NAME\n" );
            ProTKFprintf( fp, "!--------------------------\n" );
                
            status = ProUtilCollectExplstate (p_assembly, &geomitems);
            TEST_CALL_REPORT("ProUtilCollectExplstate()", "ProTestAsmExplode()",
                status, status != PRO_TK_NO_ERROR);
            if (status == PRO_TK_NO_ERROR)
            {
                status = ProArraySizeGet ((ProArray)geomitems, &geomitems_num);
                TEST_CALL_REPORT( "ProArraySizeGet()", "ProTestAsmExplode()", 
                    status, status != PRO_TK_NO_ERROR );
                for (i = 0; i < geomitems_num; i++)
                {
                    status = ProTestExpldstateVisit (&geomitems[i],
	                PRO_TK_NO_ERROR, (ProAppData)fp);
                }
                status = ProArrayFree ((ProArray*)&geomitems);
                TEST_CALL_REPORT( "ProArrayFree()", "ProTestAsmExplode()", 
                    status, status != PRO_TK_NO_ERROR );
            }

	    fclose( fp );
	}
	break;

      case TEST_ASM_SET_CURRENT_EXPLODE:
    	status = ProExpldstateSelect( p_assembly, &expldstate );
    	TEST_CALL_REPORT("ProExpldstateSelect()", "ProTestAsmExplode()",
    		status, status != PRO_TK_NO_ERROR);

    	status = ProExpldstateActivate( p_assembly, &expldstate );
    	TEST_CALL_REPORT( "ProExpldstateActivate()", "ProTestAsmExplode()",
        	status, status != PRO_TK_NO_ERROR);
        break;
    }

    if( current_expldstate.id != expldstate.id )
    {
    	status = ProWindowRepaint( PRO_VALUE_UNUSED );
    	TEST_CALL_REPORT( "ProWindowRepaint()", "ProTestAsmExplode()",
		status, status != PRO_TK_NO_ERROR );
    }


    return 0;
}



/*====================================================================*\
  Function : ProTestExpldstateVisit(
  Purpose  : visit action to visit assembly explosions
\*====================================================================*/
ProError ProTestExpldstateVisit(
    ProGeomitem		*p_geomitem,
    ProError		err,
    ProAppData		p_appdata
)
{
    ProError		status;
    FILE		*fp;
    ProMdlName		wname;
    char		explode_name[ PRO_MDLNAME_SIZE ];
    char                model_name[ PRO_MDLNAME_SIZE ];
    ProMdl		p_model;


    TEST_CALL_REPORT("ProGeomitemAction()", "ProTestExpldstateVisit()",
    PRO_TK_NO_ERROR, 0);

    fp = (FILE*)p_appdata;

    status = ProModelitemNameGet( p_geomitem, wname );
    TEST_CALL_REPORT( "ProModelitemNameGet()", "ProTestExpldstateVisit()",
        status, status != PRO_TK_NO_ERROR );

    ProWstringToString( explode_name, wname );

    status = ProModelitemMdlGet( p_geomitem, &p_model );
    TEST_CALL_REPORT( "ProModelitemMdlGet()", "ProTestExpldstateVisit()",
        status, status != PRO_TK_NO_ERROR );

    status = ProMdlMdlnameGet( p_model, wname );
    TEST_CALL_REPORT( "ProMdlMdlnameGet()", "ProTestExpldstateVisit()",
        status, status != PRO_TK_NO_ERROR );

    ProWstringToString( model_name, wname );

    ProTKFprintf( fp, "%s\t\t%s\n", explode_name, model_name );


    return PRO_TK_NO_ERROR;
}



/*====================================================================*\
  Function : ProTestExpldstateFilter
  Purpose  : filter action to filter assembly explosions
\*====================================================================*/
ProError ProTestExpldstateFilter(
    ProGeomitem         *p_geomitem,
    ProAppData          p_appdata
)
{
    TEST_CALL_REPORT("ProGeomitemFilter()", "ProTestExpldstateFilter()",
    PRO_TK_NO_ERROR, 0);

    if( p_geomitem->type == PRO_EXPLD_STATE )
	return PRO_TK_NO_ERROR;

    return PRO_TK_CONTINUE;
}



/*====================================================================*\
  Function : ProTestAsmcomppathFunc()
  Purpose  : to test some ProAssembly functions
\*====================================================================*/
int ProTestAsmcomppathFunc(ProMdl *mdl)
{
    ProError status;
    ProAsmcomppath comppath, comp_path;
    ProAssembly assembly = *(ProAssembly *)mdl;
    ProMdl model;
    ProSelection *p_sel;
    char name[PRO_NAME_SIZE], type[PRO_TYPE_SIZE];
    ProCharLine str;
    int n_sel,i;
    ProMatrix matrix;
    ProVector tvec;
    ProBoolean bool_val;

    ProUtilMsgPrint( "gen", "Test %0s", "Select an assembly component");

    n_sel = 0;
    status = ProSelect((char *)"prt_or_asm", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel);
    TEST_CALL_REPORT("ProSelect()", "ProTestAsmcomppathFunc()",
	    status, status != PRO_TK_NO_ERROR && status != PRO_TK_USER_ABORT &&
	    status != PRO_TK_PICK_ABOVE);
    if (status != PRO_TK_NO_ERROR && n_sel<1)
	return (0);

    status = ProSelectionAsmcomppathGet(p_sel[0], &comp_path);
    TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProTestAsmcomppathFunc()",
					    status, status != PRO_TK_NO_ERROR);

    status = ProAsmcomppathInit(comp_path.owner, comp_path.comp_id_table, 
				comp_path.table_num, &comppath);
    TEST_CALL_REPORT("ProAsmcomppathInit()", "ProTestAsmcomppathFunc()",
					    status, status != PRO_TK_NO_ERROR);
        
    status = ProAssemblyDynPosGet(assembly, &bool_val);
    TEST_CALL_REPORT("ProAssemblyDynPosGet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
        
    status = ProAssemblyDynPosSet(assembly, PRO_B_TRUE);
    TEST_CALL_REPORT("ProAssemblyDynPosSet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);

    status = ProAsmcomppathMdlGet(&comppath, &model);
    TEST_CALL_REPORT("ProAsmcomppathMdlGet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);

    ProUtilModelnameGet(&model, name, type);
    ProTKSprintf(str, "Now rotate component %s.%s", name, type);
    ProUtilMsgPrint( "gen", "Test %0s", str);

    status = ProAsmcomppathTrfGet(&comppath, PRO_B_TRUE, matrix);
    TEST_CALL_REPORT("ProAsmcomppathTrfGet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);

/*----------------------------------------------------------------*\
    now shift the matrix
\*----------------------------------------------------------------*/
       for(i=0; i<3; i++) tvec[i]      = matrix[0][i];
       for(i=0; i<3; i++) matrix[0][i] = matrix[1][i];
       for(i=0; i<3; i++) matrix[1][i] = matrix[2][i];
       for(i=0; i<3; i++) matrix[2][i] = tvec[i];      

    status = ProAsmcomppathTrfSet(&comppath, PRO_B_TRUE, matrix);
    TEST_CALL_REPORT("ProAsmcomppathTrfSet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
    status = ProSolidRegenerate((ProSolid)assembly, PRO_REGEN_NO_FLAGS);
    TEST_CALL_REPORT("ProSolidRegenerate()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
#ifndef PT_PRODUCTS_BUILD
    status = ProSolidDisplay((ProSolid)assembly);
    TEST_CALL_REPORT("ProSolidDisplay()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
#endif

    ProTestSleep(1);
/*----------------------------------------------------------------*\
    now shift the matrix
\*----------------------------------------------------------------*/
    for(i=0; i<3; i++) tvec[i]      = matrix[0][i];
    for(i=0; i<3; i++) matrix[0][i] = matrix[1][i];
    for(i=0; i<3; i++) matrix[1][i] = matrix[2][i];
    for(i=0; i<3; i++) matrix[2][i] = tvec[i];      

    status = ProAsmcomppathTrfSet(&comppath, PRO_B_TRUE, matrix);
    TEST_CALL_REPORT("ProAsmcomppathTrfSet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
    status = ProSolidRegenerate((ProSolid)assembly, PRO_REGEN_NO_FLAGS);
    TEST_CALL_REPORT("ProSolidRegenerate()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
#ifndef PT_PRODUCTS_BUILD
    status = ProSolidDisplay((ProSolid)assembly);
    TEST_CALL_REPORT("ProSolidDisplay()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
#endif

    ProTestSleep(1);
/*----------------------------------------------------------------*\
    now shift the matrix
\*----------------------------------------------------------------*/
    for(i=0; i<3; i++) tvec[i]      = matrix[0][i];
    for(i=0; i<3; i++) matrix[0][i] = matrix[1][i];
    for(i=0; i<3; i++) matrix[1][i] = matrix[2][i];
    for(i=0; i<3; i++) matrix[2][i] = tvec[i];      

    status = ProAsmcomppathTrfSet(&comppath, PRO_B_TRUE, matrix);
    TEST_CALL_REPORT("ProAsmcomppathTrfSet()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
    status = ProSolidRegenerate((ProSolid)assembly, PRO_REGEN_NO_FLAGS);
    TEST_CALL_REPORT("ProSolidRegenerate()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
#ifndef PT_PRODUCTS_BUILD
    status = ProSolidDisplay((ProSolid)assembly);
    TEST_CALL_REPORT("ProSolidDisplay()", "ProTestAsmcomppathFunc()",
				    status, status != PRO_TK_NO_ERROR);
#endif

    return (0);
}



/*====================================================================*\
  Function : ProUtilAsmcompStr
  Purpose  : return string tyoe for  ProAsmcompType
\*====================================================================*/
char *ProUtilAsmcompStr(ProAsmcompType type)
{
    static ProTestAsmcompTypeStr tab[] = {
	{PRO_ASM_COMP_TYPE_NONE, (char *)"PRO_ASM_COMP_TYPE_NONE"},
	{PRO_ASM_COMP_TYPE_WORKPIECE, (char *)"PRO_ASM_COMP_TYPE_WORKPIECE"},
	{PRO_ASM_COMP_TYPE_REF_MODEL, (char *)"PRO_ASM_COMP_TYPE_REF_MODEL"},
	{PRO_ASM_COMP_TYPE_FIXTURE, (char *)"PRO_ASM_COMP_TYPE_FIXTURE"},
	{PRO_ASM_COMP_TYPE_MOLD_BASE, (char *)"PRO_ASM_COMP_TYPE_MOLD_BASE"},
	{PRO_ASM_COMP_TYPE_MOLD_ASSEM, (char *)"PRO_ASM_COMP_TYPE_MOLD_ASSEM"},
	{PRO_ASM_COMP_TYPE_GEN_ASSEM, (char *)"PRO_ASM_COMP_TYPE_GEN_ASSEM"},
	{PRO_ASM_COMP_TYPE_CAST_ASSEM, (char *)"PRO_ASM_COMP_TYPE_CAST_ASSEM"},
	{PRO_ASM_COMP_TYPE_DIE_BLOCK, (char *)"PRO_ASM_COMP_TYPE_DIE_BLOCK"},
	{PRO_ASM_COMP_TYPE_DIE_COMP, (char *)"PRO_ASM_COMP_TYPE_DIE_COMP"},
	{PRO_ASM_COMP_TYPE_SAND_CORE, (char *)"PRO_ASM_COMP_TYPE_SAND_CORE"},
	{PRO_ASM_COMP_TYPE_CAST_RESULT, (char *)"PRO_ASM_COMP_TYPE_CAST_RESULT"}
    };

    static int tabsize=sizeof(tab)/sizeof(tab[0]);
    int i;

    for (i=0; i<tabsize; i++)
	if (type == tab[i].type)
	    return tab[i].str;
    return (char *)"UNKNOWN";
}



/*====================================================================*\
  Function : ProUtilAsmcompFilter()
  Purpose  : to allow select only  asmcomps 
\*====================================================================*/
ProError  ProUtilAsmcompFilter(
    ProSelection sel,
    ProAppData data)
{
    ProError status;
    ProAsmcomppath asmcomppath;

   status = ProSelectionAsmcomppathGet(sel, &asmcomppath);
   TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProUtilAsmcompSelect()",
                                status, status != PRO_TK_NO_ERROR);
   if (asmcomppath.table_num != 1)
        return (PRO_TK_CONTINUE);
   else
	return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : ProUtilAsmcompSelect()
  Purpose  : to select one asmcomp 
\*====================================================================*/
ProError ProUtilAsmcompSelect(ProAsmcomp *p_asmcomp)
{
   ProSelection *p_sel;
   ProError status;
   ProSelFunctions filter = {NULL, (ProSelectionPostFilter)ProUtilAsmcompFilter,
                             NULL, NULL};
   int n_sel;
   ProAsmcomppath asmcomppath;

   status = ProSelect((char *)"prt_or_asm", 1, NULL, &filter, NULL, NULL,
	&p_sel, &n_sel);
   TEST_CALL_REPORT("ProSelect()", 
	"ProUtilAsmcompSelect()", status, status != PRO_TK_NO_ERROR);
   if (status != PRO_TK_NO_ERROR)
	return (status);
   status = ProSelectionAsmcomppathGet(p_sel[0], &asmcomppath);
   TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProUtilAsmcompSelect()", 
				status, status != PRO_TK_NO_ERROR);
   p_asmcomp->owner = asmcomppath.owner;
   p_asmcomp->id =  asmcomppath.comp_id_table[0];
   p_asmcomp->type = PRO_FEATURE;
 
   return (PRO_TK_NO_ERROR);  
}

/*====================================================================*\
FUNCTION : ProTestAsmcompAssembleBycsys ()
PURPOSE  : Assemble a component by coordinate system.
\*====================================================================*/
ProError ProTestAsmcompAssembleBycsys (
    ProSolid       assembly,
    ProSelection   _asm_csys,
    ProSolid       component,
    ProSelection   _comp_csys)
{
    ProError       err;
    ProElement     elem_root;
    ProSelection   sel;
    ProModelitem   modelitem;
    ProErrorlist   errors;
    ProFeature     feature;
    ProFeatureCreateOptions *opts = 0;

    static ElemTreeData tree[] = {
 	{0, PRO_E_FEATURE_TREE, {(ProValueDataType)-1}},
	{1, PRO_E_FEATURE_TYPE, {PRO_VALUE_TYPE_INT, {PRO_FEAT_COMPONENT}}},
	{1, PRO_E_COMPONENT_MODEL, {PRO_VALUE_TYPE_POINTER}},
	{1, PRO_E_COMPONENT_CONSTRAINTS, {(ProValueDataType)-1}},
	{2, PRO_E_COMPONENT_CONSTRAINT, {(ProValueDataType)-1}},
	{3, PRO_E_COMPONENT_CONSTR_TYPE, {PRO_VALUE_TYPE_INT, {PRO_ASM_CSYS}}},
	{3, PRO_E_COMPONENT_COMP_CONSTR_REF, {PRO_VALUE_TYPE_SELECTION}},
	{3, PRO_E_COMPONENT_ASSEM_CONSTR_REF, {PRO_VALUE_TYPE_SELECTION}}};
	
/*--------------------------------------------------------------------*\
    Prepare value for the component model element.
\*--------------------------------------------------------------------*/
    tree[2].data.v.p = (void *)component;

/*--------------------------------------------------------------------*\
    Prepare value for the component and assembly reference element.
\*--------------------------------------------------------------------*/
    tree[6].data.v.r=_comp_csys;
    tree[7].data.v.r=_asm_csys;
/*--------------------------------------------------------------------*\
    Create element tree
\*--------------------------------------------------------------------*/
    err = ProUtilElemtreeCreate(tree, sizeof(tree)/sizeof(tree[0]),
	NULL, &elem_root);

/*--------------------------------------------------------------------*\
    Set up a selection structure for the feature context.
\*--------------------------------------------------------------------*/
    err = ProMdlToModelitem (assembly, &modelitem);
    TEST_CALL_REPORT("ProMdlToModelitem()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);
    err = ProSelectionAlloc (NULL, &modelitem, &sel);
    TEST_CALL_REPORT("ProSelectionAlloc ()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Assemble the component by feature creation.
\*--------------------------------------------------------------------*/
     err = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions),
        1, (ProArray*)&opts);

    opts[0]= PRO_FEAT_CR_INCOMPLETE_FEAT;

    err = ProFeatureWithoptionsCreate (sel, elem_root,
        opts, PRO_REGEN_NO_FLAGS, &feature, &errors);
    TEST_CALL_REPORT("ProFeatureWithoptionsCreate()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);

  err = ProArrayFree((ProArray*)&opts);

    if (err != PRO_TK_NO_ERROR)
    {
	ProUtilShowTreeInInfo(elem_root);
        ProUtilFeatErrsPrint (&errors);
    }
/*--------------------------------------------------------------------*\
    Free Allocated memory
\*--------------------------------------------------------------------*/
    err = ProElementFree(&elem_root);
    TEST_CALL_REPORT("ProElementFree()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);
    err = ProSelectionFree(&sel);
    TEST_CALL_REPORT("ProSelectionFree()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);
    if (tree[6].data.v.r!=NULL) {
	err = ProSelectionFree(&tree[6].data.v.r);
	TEST_CALL_REPORT("ProSelectionFree()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);
    }
    if (tree[7].data.v.r!=NULL) {
	err = ProSelectionFree(&tree[7].data.v.r);
	TEST_CALL_REPORT("ProSelectionFree()", 
		"ProTestAsmcompAssembleBycsys()", err, err != PRO_TK_NO_ERROR);
    }
    return (err);
}


/*====================================================================*\
FUNCTION : ProTestAsmcompReplaceBycsys()
PURPOSE  : Replace a component whose constraint is by CSYS.
\*====================================================================*/
ProError ProTestAsmcompReplaceBycsys(
    ProSolid parent_asm,      /*  parent assembly */
    ProName  w_asm_csys_name, /*  new assembly CSYS (can be NULL) */
    ProSolid new_comp,        /*  new (replacement) component */
    ProName  w_comp_csys_name,/*  name of component's CSYS */
    ProFeature *p_component)  /* As input, this argument is the component to be
                               replaced.  As output, it's the new component. */
{
    ProError err;
    ProGeomitem asm_csys, comp_csys;
    ProSelection sel;
    ProElement elemtree, elem_comp, elem_comp_ref, elem_asm_ref;
    ProValueData value_data;
    ProModelitem modelitem;
    ProAsmcomppath path;    
   ProFeatureCreateOptions *opts = 0;
    ProErrorlist   errors;
    
    static ProElempathItem comp_mod_path[]= {
	{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_COMPONENT_MODEL}};
    static ProElempathItem comp_ref_path[]= {
	{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_COMPONENT_CONSTRAINTS},
	{PRO_ELEM_PATH_ITEM_TYPE_INDEX, 0},
	{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_COMPONENT_COMP_CONSTR_REF}};
    static ProElempathItem asm_ref_path[] = {
	{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_COMPONENT_CONSTRAINTS},
	{PRO_ELEM_PATH_ITEM_TYPE_INDEX, 0},
	{PRO_ELEM_PATH_ITEM_TYPE_ID, PRO_E_COMPONENT_ASSEM_CONSTR_REF}};

/*--------------------------------------------------------------------*\
    Find the named assembly coordinate system.
\*--------------------------------------------------------------------*/
    if (w_asm_csys_name != NULL)
    {
	err = ProUtilFindCsysByName (parent_asm, w_asm_csys_name, &asm_csys);
	if (err != PRO_TK_NO_ERROR)
	    return (PRO_TK_E_NOT_FOUND);
    }
/*--------------------------------------------------------------------*\
    Find the named component coordinate system.
\*--------------------------------------------------------------------*/
    err = ProUtilFindCsysByName (new_comp, w_comp_csys_name, &comp_csys);
    if (err != PRO_TK_NO_ERROR)
        return (PRO_TK_E_NOT_FOUND);

/*--------------------------------------------------------------------*\
    Get element tree for component to be replaced.
\*--------------------------------------------------------------------*/
    err = ProFeatureElemtreeExtract(p_component, NULL, PRO_FEAT_EXTRACT_NO_OPTS, &elemtree) ; 
    TEST_CALL_REPORT("ProFeatureElemtreeExtract()", 
	"ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
        return (err);

/*--------------------------------------------------------------------*\
    Modify the tree to reference the new component.
    Will have to change PRO_E_COMPONENT_MODEL and
    PRO_E_COMPONENT_COMP_CONSTR_REF
\*--------------------------------------------------------------------*/
    err = ProUtilElemtreeElementGet(elemtree, comp_mod_path,
	sizeof(comp_mod_path)/sizeof(comp_mod_path[0]), &elem_comp);

    if (err == PRO_TK_NO_ERROR)
    {
	value_data.type = PRO_VALUE_TYPE_POINTER;
	value_data.v.p = new_comp;
	ProUtilElementValueSet(elem_comp, &value_data);

	err = ProUtilElemtreeElementGet(elemtree, comp_ref_path,
	    sizeof(comp_ref_path)/sizeof(comp_ref_path[0]), &elem_comp_ref);

	if (err == PRO_TK_NO_ERROR)
	{
	    value_data.type = PRO_VALUE_TYPE_SELECTION;
	    err = ProSelectionAlloc (NULL, &comp_csys, &sel);
	    TEST_CALL_REPORT("ProSelectionAlloc()", 
		"ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
	    value_data.v.r = sel;
	    ProUtilElementValueSet(elem_comp_ref, &value_data);
	    err = ProSelectionFree(&sel);
	    TEST_CALL_REPORT("ProSelectionFree()", 
		"ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
	}
    }

/*--------------------------------------------------------------------*\
    If new assembly csys used, change PRO_E_COMPONENT_ASSEM_CONSTR_REF
\*--------------------------------------------------------------------*/
    if (err == PRO_TK_NO_ERROR && w_asm_csys_name != NULL)
    {
	err = ProUtilElemtreeElementGet(elemtree, asm_ref_path,
	    sizeof(asm_ref_path)/sizeof(asm_ref_path[0]), &elem_asm_ref);

	if (err == PRO_TK_NO_ERROR)
	{
	    value_data.type = PRO_VALUE_TYPE_SELECTION;
	    err = ProAsmcomppathInit(parent_asm, NULL, 0, &path);    
	    TEST_CALL_REPORT("ProAsmcomppathInit()", 
		"ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
	    err = ProSelectionAlloc (&path, &asm_csys, &sel);
	    TEST_CALL_REPORT("ProSelectionAlloc()", 
		"ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
	    value_data.v.r = sel;
	    ProUtilElementValueSet(elem_asm_ref, &value_data);
	    err = ProSelectionFree(&sel);
	    TEST_CALL_REPORT("ProSelectionFree()", 
		"ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
	}
    }
/*--------------------------------------------------------------------*\
    Call ProFeatureRedefine 
\*--------------------------------------------------------------------*/
    if (err == PRO_TK_NO_ERROR)
    {
	err = ProMdlToModelitem (parent_asm, &modelitem);
	TEST_CALL_REPORT("ProFeatureRedefine()", 
	    "ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);
	err = ProSelectionAlloc (NULL, &modelitem, &sel);
	TEST_CALL_REPORT("ProFeatureRedefine()", 
	    "ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);

	err = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions),
        1, (ProArray*)&opts);

    opts[0]= PRO_FEAT_CR_FIX_MODEL_ON_FAIL;

	err = ProFeatureWithoptionsRedefine(NULL, p_component, elemtree,
        opts, PRO_REGEN_NO_FLAGS, &errors);
	TEST_CALL_REPORT("ProFeatureWithoptionsRedefine()", 
	    "ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);

 err = ProArrayFree((ProArray*)&opts);

    }

    if (err != PRO_TK_NO_ERROR)
    {
	ProUtilShowTreeInInfo(elemtree);
        ProUtilFeatErrsPrint (&errors);
    }

/*--------------------------------------------------------------------*\
    Free Allocated memory
\*--------------------------------------------------------------------*/
    err = ProFeatureElemtreeFree(p_component,elemtree);
    TEST_CALL_REPORT("ProFeatureElemtreeFree()", 
	    "ProTestAsmcompReplaceBycsys()", err, err != PRO_TK_NO_ERROR);

    return(err) ; 
}

/*=============================================================*\
  FUNCTION: ProTestAsmcompCreateRedefine()
  PURPOSE:  User interface to funcs UsrAsmcompAssembleBycsys,
				    UsrAsmcompReplaceBycsys  
\*=============================================================*/
int ProTestAsmcompCreateRedefine(
    ProSolid assembly,
    ProFeature *component,
    int action)
{
    ProSolid comp;
    ProError err, er1;
    int version, win_id,sel_n, Oldwin_id;
    ProCharLine line, str;
    ProLine buff;
    ProPath *path_arr, sel_path, def_path, cur_path;
    ProName *path_lab_arr;
	ProMdlName w_name, w_sel_name;
	ProMdlExtension w_type;
    static ProCharName asm_csys = {"ACS0"}, comp_csys = {"CS0"};
    ProName w_asm_csys, w_comp_csys;
    ProType type;
    ProSelection *win_sel, sel_C, sel_A;
	ProBoolean tree_flag=PRO_B_FALSE;

/*------------------------------------------------------------------*\
    Choose the component to assembly or redefine
\*--------------------------------------------------------------------*/
    ProStringToWstring(buff, (char *)"*.prt,*.asm");
    ProStringToWstring(def_path, (char *)".");

    ProTKSprintf(str, "Choose new component to %s.",
	action == TEST_ASMCOMP_ASSEMBLE ? "assemble" : "redefine");
    ProUtilMsgPrint( "gen", "TEST %0s", str);

    /* No default dirs */
    err = ProArrayAlloc(0, sizeof(ProPath), 1, (ProArray*)&path_arr);
    TEST_CALL_REPORT("ProArrayAlloc()", 
	"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
    err = ProArrayAlloc(0, sizeof(ProPath), 1, (ProArray*)&path_lab_arr);
    TEST_CALL_REPORT("ProArrayAlloc()", 
	"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

    /* Open file */
    err = ProFileMdlnameOpen(NULL, buff, path_arr, path_lab_arr, def_path, NULL,
	sel_path);
    TEST_CALL_REPORT("ProFileMdlnameOpen()", 
	"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

    if (err == PRO_TK_NO_ERROR)
    {
	err = ProFileMdlnameParse(sel_path, def_path, w_name, w_type, &version);
	TEST_CALL_REPORT("ProFileMdlnameParse()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
	
	ProUtilWstrcpy(sel_path, def_path);
	err = ProPathMdlnameCreate(NULL, w_name, w_type, PRO_VALUE_UNUSED, def_path);
	TEST_CALL_REPORT("ProPathMdlnameCreate()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
	
	ProWstringToString(str, def_path);
	if( ProUtilConfirmNameType(str, line, &type) != PRO_TK_BAD_INPUTS)
	{

	    err = ProDirectoryCurrentGet(cur_path); 
	    TEST_CALL_REPORT("ProDirectoryCurrentGet()", 
		"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	    err = ProDirectoryChange(sel_path); 
	    TEST_CALL_REPORT("ProDirectoryCurrentGet()", 
		"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
	
	    err = ProMdlnameRetrieve (w_name, (ProMdlfileType)type, (ProMdl*)&comp);
	    TEST_CALL_REPORT("ProMdlnameRetrieve ()", 
		"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	    er1 = ProDirectoryChange(cur_path); 
	    TEST_CALL_REPORT("ProDirectoryCurrentGet()", 
		"ProTestAsmcompCreateRedefine()", er1, er1 != PRO_TK_NO_ERROR);

	    if (err != PRO_TK_NO_ERROR)
	    {
		ProTKSprintf(line , "Failed to retrieve %s", str);
		ProUtilMsgPrint( "gen", "TEST %0s", line);
	    }
	}
    }
/*------------------------------------------------------------------*\
    Free Allocated memory
\*--------------------------------------------------------------------*/
    er1 = ProArrayFree((ProArray*)&path_arr);
    TEST_CALL_REPORT("ProArrayFree()", 
	"ProTestAsmcompCreateRedefine()", er1, er1 != PRO_TK_NO_ERROR);
    er1 = ProArrayFree((ProArray*)&path_lab_arr);
    TEST_CALL_REPORT("ProArrayFree()", 
	"ProTestAsmcompCreateRedefine()", er1, er1 != PRO_TK_NO_ERROR);

    if (err != PRO_TK_NO_ERROR)
	return (0);

    if (action == TEST_ASMCOMP_ASSEMBLE)
    {
	/*------------------------------------------------------------------*\
	    Select the assembly 
	\*--------------------------------------------------------------------*/
    
    	    sel_n=0;
    	    err = ProSelect((char *)"csys",1,NULL,NULL,NULL,NULL,&win_sel,&sel_n);
	    TEST_CALL_REPORT("ProSelect()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
	 
        
	if (err != PRO_TK_NO_ERROR)
	  return (0);  
    
	err = ProSelectionCopy(win_sel[0],&sel_A);
	TEST_CALL_REPORT("ProSelectionCopy()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
	/*------------------------------------------------------------------*\
	    Select the component csys 
	\*--------------------------------------------------------------------*/
	err = ProMdlMdlnameGet((ProMdl)comp, w_sel_name);
	TEST_CALL_REPORT("ProMdlMdlnameGet()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err = ProWindowCurrentGet(&Oldwin_id);
	TEST_CALL_REPORT("ProWindowCurrentGet()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err= ProAccessorywindowWithTreeMdlnameCreate(w_sel_name,type,tree_flag,&win_id);
	TEST_CALL_REPORT("ProAccessorywindowWithTreeMdlnameCreate()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err = ProMdlDisplay((ProMdl)comp);
	TEST_CALL_REPORT("ProMdlDisplay()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err = ProWindowCurrentSet(win_id);
	TEST_CALL_REPORT("ProWindowCurrentSet()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);


	    sel_n=0;
	    err = ProSelect((char *)"csys",1,NULL,NULL,NULL,NULL,&win_sel,&sel_n);
	    TEST_CALL_REPORT("ProSelect()", 
		"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
	 

	if (err != PRO_TK_NO_ERROR)
	  return (0);    

	err = ProSelectionCopy(win_sel[0],&sel_C);
	TEST_CALL_REPORT("ProSelectionCopy()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err = ProWindowCurrentSet(Oldwin_id);
	TEST_CALL_REPORT("ProWindowCurrentSet()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err = ProWindowDelete(win_id);
	TEST_CALL_REPORT("ProWindowDelete()", 
	    "ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);

	err = ProTestAsmcompAssembleBycsys (assembly,sel_A,
		comp,sel_C);
    }
    else
    {
	/*------------------------------------------------------------------*\
	    Enter the assembly csys name
	\*--------------------------------------------------------------------*/
    
	ProStringToWstring(w_asm_csys, asm_csys);
	ProTKSprintf(str, "Enter the assembly csys name [%s].", asm_csys);
	ProUtilMsgPrint( "gen", "TEST %0s", str);
	if (ProUtilStringGet(w_asm_csys, w_asm_csys, PRO_NAME_SIZE)==0)
	return (0);
	ProWstringToString(asm_csys, w_asm_csys);

	/*------------------------------------------------------------------*\
	    Enter the component csys name
	\*--------------------------------------------------------------------*/
	ProStringToWstring(w_comp_csys, comp_csys);
	ProTKSprintf(str, "Enter the component csys name [%s].", comp_csys);
	ProUtilMsgPrint( "gen", "TEST %0s", str);
	if (ProUtilStringGet(w_comp_csys, w_comp_csys, PRO_NAME_SIZE)==0)
	return (0);
	ProWstringToString(comp_csys, w_comp_csys);    

	err = ProTestAsmcompReplaceBycsys (assembly, w_asm_csys, comp, 
	    w_comp_csys, component);
    }

    if (err != PRO_TK_NO_ERROR)
	ProTKSprintf(str, "Failed to %s component.",
	    action == TEST_ASMCOMP_ASSEMBLE ? "assemble" : "redefine");
    else
	ProTKSprintf(str, "Component successfully %s.",
	    action == TEST_ASMCOMP_ASSEMBLE ? "assembled" : "redefined");
    ProUtilMsgPrint( "gen", "TEST %0s", str);

    err = ProTreetoolRefresh(assembly);
    TEST_CALL_REPORT("ProArrayFree()", 
	"ProTestAsmcompCreateRedefine()", err, err != PRO_TK_NO_ERROR);
    return (0);
}

/*====================================================================*\
  Function : ProTestAsmcompPackageMoveAct()
  Purpose  : Act to test ProAsmcompPackageMove function
\*====================================================================*/
ProError ProTestAsmcompPackageMoveAct (ProAppData data, int action)
{
    char *sel_ptr = NULL;
    int num_sel;
    ProError status;
    ProSelection **sel_array_ptr = (ProSelection**)data;
    ProCharLine str;

/*------------------------------------------------------------------*\
    Select reference motions 
\*--------------------------------------------------------------------*/
    if (sel_array_ptr != NULL)
    {
        switch (action)
        {
        case TEST_ASMCOMP_REF_VIEW_PLANE:
            sel_ptr = NULL;
            num_sel = 0;
            break;
        case TEST_ASMCOMP_REF_SEL_PLANE:
        case TEST_ASMCOMP_REF_PLANE_NORMAL:   
            sel_ptr = (char *)"datum,surface";
            num_sel = 1;
            break;
        case TEST_ASMCOMP_REF_ENTITY_EDGE:
            sel_ptr = (char *)"axis,edge,curve";
            num_sel = 1;
            break; 
        case TEST_ASMCOMP_REF_2_POINTS:
            sel_ptr = (char *)"point,edge_end";
            num_sel = 2;
            break; 
        case TEST_ASMCOMP_REF_CSYS_X:
        case TEST_ASMCOMP_REF_CSYS_Y:
        case TEST_ASMCOMP_REF_CSYS_Z:
            sel_ptr = (char *)"csys";
            num_sel = 1;
            break;
	default:
	    sel_ptr = NULL;
	    break;
        }

        if ( sel_ptr != NULL )
        {
            ProTKSprintf (str,"Select %d %s", num_sel, sel_ptr);
            ProUtilMsgPrint ( "gen", "TEST %0s", str);
            status = ProSelect ( sel_ptr, num_sel,
                NULL, NULL, NULL, NULL, 
                sel_array_ptr, &num_sel);
            ProMessageClear();
            if ( status == PRO_TK_USER_ABORT ||
                 status == PRO_TK_PICK_ABOVE)
                 sel_ptr = (char*)NULL;
        }
    }

/*------------------------------------------------------------------*\
    Return action for reusing
\*--------------------------------------------------------------------*/
    ProMenuDeleteWithStatus ( action );
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : ProTestAsmcompPackageMove ()
  Purpose  : to test ProAsmcompPackageMove function
\*====================================================================*/
ProError ProTestAsmcompPackageMove (ProAsmcomp *asmcomp_ptr)
{
   ProTestMenuButton  menubut_motion[] = {
        {(char *)"-Orient Mode", TEST_ASMCOMP_MOTION_ORIENTMODE},
        {(char *)"-Translate", TEST_ASMCOMP_MOTION_TRANSLATE},
        {(char *)"-Rotate",    TEST_ASMCOMP_MOTION_ROTATE},
        {(char *)"-Adjust",    TEST_ASMCOMP_MOTION_ADJUST},
        {(char *)"Done",      -1}
    };

  ProTestMenuButton  menubut_showui[] = {
        {(char *)"-Dialog",     TEST_ASMCOMP_SHOWUI_DIALOG},
        {(char *)"-Action",     TEST_ASMCOMP_SHOWUI_ACTION},
        {(char *)"Done",       -1}
    };

   ProTestMenuButton  menubut_ref[] = {
        {(char *)"-View Plane",  TEST_ASMCOMP_REF_VIEW_PLANE},
        {(char *)"-Sel Plane",   TEST_ASMCOMP_REF_SEL_PLANE},
        {(char *)"-Entity Edge", TEST_ASMCOMP_REF_ENTITY_EDGE},
        {(char *)"-Plane Normal",TEST_ASMCOMP_REF_PLANE_NORMAL},
        {(char *)"-2 points",    TEST_ASMCOMP_REF_2_POINTS},
        {(char *)"-Csys X",      TEST_ASMCOMP_REF_CSYS_X},
        {(char *)"-Csys Y",      TEST_ASMCOMP_REF_CSYS_Y},
        {(char *)"-Csys Z",      TEST_ASMCOMP_REF_CSYS_Z},
        {(char *)"Done",        -1}
    };

    char menus_names[][14] =
    { "MotionType",
      "ShowUI",
      "Reference" };

    int i, n_but_motion, n_but_ref, n_but_showui;
    static int first=1;
    ProError status;
    ProSelection *sel_array = NULL;

    n_but_motion = sizeof(menubut_motion)/sizeof(menubut_motion[0]);
    n_but_showui = sizeof(menubut_showui)/sizeof(menubut_showui[0]);
    n_but_ref    = sizeof(menubut_ref)/sizeof(menubut_ref[0]);
/*--------------------------------------------------------------------------*\
        For a first call register a menu from strings
\*--------------------------------------------------------------------------*/
    if (first)
    {
        ProTestMenuDynamicRegister ( menus_names[0],
            menubut_motion, n_but_motion);

        ProTestMenuDynamicRegister ( menus_names[1],
            menubut_showui, n_but_showui);

        ProTestMenuDynamicRegister ( menus_names[2],
            menubut_ref, n_but_ref);

        first = 0;
    }
/*--------------------------------------------------------------------------*\
    Set action for the menu button 
\*--------------------------------------------------------------------------*/
    for (i=0; i<n_but_showui; i++)
        ProMenubuttonActionSet ( menus_names[1], menubut_showui[i].button,
            (ProMenubuttonAction)ProTestAsmcompPackageMoveAct, NULL,
            menubut_showui[i].action);
    ProMenubuttonActionSet ( menus_names[1], menus_names[1],
            (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    ProMenuCreate (PROMENUTYPE_MAIN, menus_names[1], &i);
    ProMenuProcess ( menus_names[1], &n_but_showui);

    if ( n_but_showui == -1 )
        return (PRO_TK_USER_ABORT);

    if ( (ProBoolean)n_but_showui == PRO_B_FALSE )
    {
       for (i=0; i<n_but_motion; i++)
            ProMenubuttonActionSet ( menus_names[0], menubut_motion[i].button,
                (ProMenubuttonAction)ProTestAsmcompPackageMoveAct, NULL,
                menubut_motion[i].action);
        ProMenubuttonActionSet ( menus_names[0], menus_names[0],
            (ProMenubuttonAction)ProMenuDelete, NULL, 0);
        ProMenuCreate (PROMENUTYPE_MAIN, menus_names[0], &i);
        ProMenuProcess ( menus_names[0], &n_but_motion);

        if ( n_but_motion == -1)
            return (PRO_TK_USER_ABORT);

        for (i=0; i<n_but_ref; i++)
            ProMenubuttonActionSet ( menus_names[2], menubut_ref[i].button,
                 (ProMenubuttonAction)ProTestAsmcompPackageMoveAct,
                 (ProAppData)&sel_array,
                 menubut_ref[i].action);
         ProMenubuttonActionSet ( menus_names[2], menus_names[2],
                 (ProMenubuttonAction)ProMenuDelete, NULL, 0);
         ProMenuCreate (PROMENUTYPE_MAIN, menus_names[2], &i);
         ProMenuProcess ( menus_names[2], &n_but_ref);

         if ( n_but_ref == -1 )
             return (PRO_TK_USER_ABORT);
    }
    else
    {
       n_but_ref = TEST_ASMCOMP_REF_VIEW_PLANE;
       n_but_motion = TEST_ASMCOMP_MOTION_UNDEF; 
    }
/*--------------------------------------------------------------------------*\
    Call ProAsmcompPackageMove 
\*--------------------------------------------------------------------------*/
    if (sel_array != NULL)
        status = ProArraySizeGet (sel_array, &i);
    else
        i = 0;

    status = ProAsmcompPackageMove ( asmcomp_ptr, (ProMotionType)n_but_motion,
        (ProBoolean)n_but_showui, (ProMotionRefType)n_but_ref,
        sel_array, i);
    TEST_CALL_REPORT("ProAsmcompPackageMove()", "ProTestAsmcompFunc()",
        status, status != PRO_TK_NO_ERROR);

    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : ProTestAsmcompAct()
  Purpose  : to test some ProAsmcomp functions
\*====================================================================*/
ProError ProTestAsmcompAct(ProMdl *mdl, int action)
{
   int ProTestSkelCopyCreate(ProAssembly current_assy);
   int ProTestCompSkelReplace (ProAssembly current_assy);
   /* TestSkelet.c */
	
   int  ProTestAsmcompMechanismMenu (ProAppData data, int dummy);
   /* TestMechanism.c*/

   
    ProAssembly    assembly = *(ProAssembly *)mdl;
    ProElement     elemtree;
    ProMdl         model;
    ProMdlfileType     mdltype;
    ProCharLine    str;
    char           name[PRO_FAMILY_MDLNAME_SIZE], type[PRO_TYPE_SIZE];
    ProFamilyMdlName        w_name;
    ProError       status;
    ProAsmcomp    *asmcomps, asmcomp;
    FILE          *fp;
    int            i, n, range[2]={0,3}, index;
    ProAsmcompType r_type;
    ProBoolean     bool_type;
    ProMotionType motion_type =PRO_M_UNDEF;
    ProMotionRefType motion_ref_type=PRO_M_VIEW_PLANE;
    ProSelection *motion_ref=NULL;
    int sel_sz=0;
	

	
    if (action != TEST_ASMCOMP_INFO 
     && action != TEST_ASMCOMP_ASSEMBLE
     && action !=TEST_ASMCOMP_MECHANISM
     && action != TEST_ASMCOMP_CREATE
     && action != TEST_ASMCOMP_REPLACE)
    {
        ProUtilMsgPrint( "gen", "TEST %0s", "Select assembly component." );
	status = ProUtilAsmcompSelect(&asmcomp);
	if (status != PRO_TK_NO_ERROR)
	    return (status);
    }

    switch (action)
    {
    case TEST_ASMCOMP_ASSEMBLE:
	ProTestAsmcompCreateRedefine(assembly, NULL, TEST_ASMCOMP_ASSEMBLE);
	break;
    case TEST_ASMCOMP_REDEFINE:
	ProTestAsmcompCreateRedefine(assembly, (ProFeature*)&asmcomp, 
	    TEST_ASMCOMP_REDEFINE);
	break;
    case TEST_ASMCOMP_TREE_INFO:
      status = ProFeatureElemtreeExtract((ProFeature*)&asmcomp, NULL, PRO_FEAT_EXTRACT_NO_OPTS, &elemtree);
    	TEST_CALL_REPORT("ProFeatureElemtreeExtract()",
		    "ProTestAsmcompFunc()", status, status != PRO_TK_NO_ERROR);
	ProUtilShowTreeInInfo(elemtree);
	status = ProFeatureElemtreeFree((ProFeature*)&asmcomp, elemtree);
    	TEST_CALL_REPORT("ProFeatureElemtreeFree()", 
		    "ProTestAsmcompFunc()", status, status != PRO_TK_NO_ERROR);
	break;
    case TEST_ASMCOMP_INFO:
    	status = ProUtilCollectAsmcomp(assembly, &asmcomps);
    	if (status != PRO_TK_NO_ERROR)
	    return (status);

    	ProTestQcrName(mdl, (char *)".cmp", str);
    	fp = PTApplsUnicodeFopen(str, "w");

    	status = ProArraySizeGet((ProArray)asmcomps, &n);
    	TEST_CALL_REPORT("ProArraySizeGet()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
    	for (i=0; i<n; i++)
   	    {
        status = ProAsmcompMdlGet(asmcomps+i, &model);
	    TEST_CALL_REPORT("ProAsmcompMdlGet()", "ProTestAsmcompFunc()",
					status, status != PRO_TK_NO_ERROR);
	    if (status != PRO_TK_NO_ERROR)
	    	continue;

	    status = ProAsmcompMdlMdlnameGet(asmcomps+i, &mdltype, w_name); 
	    TEST_CALL_REPORT("ProAsmcompMdlMdlnameGet()", "ProTestAsmcompFunc()",
					status, status != PRO_TK_NO_ERROR);
 	
	    ProUtilModelnameGet(&model, name, type);
	    ProWstringToString(name, w_name);
	    ProTKSprintf(str, "Found component %s.%s", name, type);
	    ProTKFprintf(fp, "%s\n", str);
	    ProUtilMsgPrint( "gen", "TEST %0s", str);

#ifndef PT_PRODUCTS_BUILD
	    status = ProAsmcompIsBulkitem(asmcomps+i, &bool_type);
	    TEST_CALL_REPORT("ProAsmcompIsBulkitem()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
    
	    ProMessageClear();
	    ProTKSprintf(str, "component is %sa bulk item", bool_type ? "" : "not ");
	    ProTKFprintf(fp, "\t%s\n", str);
	    ProUtilMsgPrint( "gen", "TEST %0s", str);
#endif    
	    status = ProAsmcompTypeGet(asmcomps+i, assembly, &r_type);
	    TEST_CALL_REPORT("ProAsmcompTypeGet()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);

	    ProMessageClear();
	    ProTKSprintf(str, "component type is %s", ProUtilAsmcompStr(r_type));
	    ProTKFprintf(fp, "\t%s\n", str);
	    ProUtilMsgPrint( "gen", "Test %0s", str);
    
	    status = ProAsmcompTypeSet(asmcomps+i, assembly, r_type);
	    TEST_CALL_REPORT("ProAsmcompTypeSet()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
/* check "is skeleton?" */
		 
	    status = ProMdlIsSkeleton (model, &bool_type);
	    TEST_CALL_REPORT("ProMdlIsSkeleton()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
	    
	    if (bool_type)
	    {
		    ProMessageClear();
	        ProTKSprintf(str, "component is a skeleton");
	        ProTKFprintf(fp, "\t%s\n", str);
	        ProUtilMsgPrint( "gen", "TEST %0s", str);
	    }
		
		 
/* check "is unplaced?" */
		
		 
	    status = ProAsmcompIsUnplaced(asmcomps+i, &bool_type);
	    TEST_CALL_REPORT("ProAsmcompIsUnplaced()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
        if (bool_type)
	    {
	        ProMessageClear();
	        ProTKSprintf(str, "component is unplaced");
	        ProTKFprintf(fp, "\t%s\n", str);
	        ProUtilMsgPrint( "gen", "TEST %0s", str);
	    }

/* check "is substitute?" */
		
		 
	    status = ProAsmcompIsSubstitute (asmcomps+i, &bool_type);
	    TEST_CALL_REPORT("ProAsmcompIsSubstitute()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
        if (bool_type)
	    {
	        ProMessageClear();
	        ProTKSprintf(str, "component is substitute");
	        ProTKFprintf(fp, "\t%s\n", str);
	        ProUtilMsgPrint( "gen", "TEST %0s", str);
	    }

    	}/* end of for */
        
    	ProArrayFree((ProArray*)&asmcomps);
    	TEST_CALL_REPORT("ProArrayFree()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
    	fclose(fp);
	break;
    case TEST_ASMCOMP_CONSTR_REDEF:
	status = ProAsmcompConstrRedefUI(&asmcomp); 
    	TEST_CALL_REPORT("ProAsmcompConstrRedefUI()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
	break;
    case TEST_ASMCOMP_CONSTR_REMOVE:
	ProUtilMsgPrint("gen", "TEST %0s", 
	    "Enter index of constrains to remove [QUIT]:");
	status = ProMessageIntegerRead(range, &index);
	if (status!= PRO_TK_NO_ERROR)
	    break;
	status = ProAsmcompConstrRemove(&asmcomp, index); 
    	TEST_CALL_REPORT("ProAsmcompConstrRemove()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
	break;
    case  TEST_ASMCOMP_REGENERATE:
	status = ProAsmcompRegenerate(&asmcomp, PRO_B_TRUE);
    	TEST_CALL_REPORT("ProAsmcompRegenerate()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
	break;
    case TEST_ASMCOMP_PACKAGE_MOVE20:
	status = ProAsmcompPackageMove(&asmcomp,(ProMotionType)motion_type,PRO_B_TRUE,motion_ref_type,motion_ref,sel_sz);
    	TEST_CALL_REPORT("ProAsmcompPackageMove()", "ProTestAsmcompFunc()",
					    status, status != PRO_TK_NO_ERROR);
	break;	
    case TEST_ASMCOMP_PACKAGE_MOVE:
        ProTestAsmcompPackageMove (&asmcomp);
        break;

    case TEST_ASMCOMP_MECHANISM:
		
	     ProTestAsmcompMechanismMenu (NULL, 0);
	break;

    case TEST_ASMCOMP_CREATE:

         ProTestSkelCopyCreate (assembly);
	
	break;
    case TEST_ASMCOMP_REPLACE:
         ProTestCompSkelReplace (assembly);
	break;
	
    }
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
  Function : ProTestAsmcompFunc()
  Purpose  : to test some ProAsmcomp functions
\*====================================================================*/
int ProTestAsmcompFunc(ProMdl *mdl)
{
    ProTestMenuButton  menubut[] = {
	{(char *)"Assemble", TEST_ASMCOMP_ASSEMBLE},
	{(char *)"Redefine", TEST_ASMCOMP_REDEFINE},
	{(char *)"ConstrRedef", TEST_ASMCOMP_CONSTR_REDEF},
	{(char *)"ConstrRedef", TEST_ASMCOMP_CONSTR_REDEF},
	{(char *)"ConstrRemove",TEST_ASMCOMP_CONSTR_REMOVE},
	{(char *)"Regenerate", TEST_ASMCOMP_REGENERATE},
	{(char *)"Package Move", TEST_ASMCOMP_PACKAGE_MOVE},
	{(char *)"Package Move20", TEST_ASMCOMP_PACKAGE_MOVE20},
	{(char *)"Info", TEST_ASMCOMP_INFO},
	{(char *)"Tree Info", TEST_ASMCOMP_TREE_INFO},
	{(char *)"Mechanism", TEST_ASMCOMP_MECHANISM},
	{(char *)"AsmcompCreate", TEST_ASMCOMP_CREATE},
	{(char *)"AsmcompReplace", TEST_ASMCOMP_REPLACE},
	{(char *)"Done TkAsmcomp", 0}
    };
    int n_but, i;
    static int first=1;

    n_but = sizeof(menubut)/sizeof(menubut[0]);
/*--------------------------------------------------------------------------*\
	For a first call register a menu from strings
\*--------------------------------------------------------------------------*/
    if (first)
    {
        ProTestMenuDynamicRegister ( (char *)"TkAsmcomp", menubut, n_but);
	first = 0;
    }
    for (i=0; i<n_but; i++)
    	ProMenubuttonActionSet( (char *)"TkAsmcomp", menubut[i].button,
       	    (i == n_but-1 ? (ProMenubuttonAction)ProMenuDelete : 
	    (ProMenubuttonAction)ProTestAsmcompAct), mdl, menubut[i].action); 
    ProMenubuttonActionSet( (char *)"TkAsmcomp", (char *)"TkAsmcomp", 
       	    (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    
    ProMenuCreate(PROMENUTYPE_MAIN, (char *)"TkAsmcomp", NULL);
    ProMenuProcess((char *)"TkAsmcomp", &i);

    return (0);
}