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



/*----------------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*----------------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProSelection.h>
#include <ProCavitylayout.h>
#include <ProMenu.h>
#include <ProUtil.h>
#include <ProArray.h>
#include <ProAsmcomp.h>
#include <ProMfg.h>
#include <ProCsys.h>
#include <ProModelitem.h>
#include <ProMessage.h>
#include <ProFamtable.h>
#include <ProFaminstance.h>
/*----------------------------------------------------------------------------*\
C System includes
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
Application includes
\*----------------------------------------------------------------------------*/
#include "TestError.h"
#include "UtilMessage.h"
#include "UtilString.h"
#include "UtilMenu.h"
#include "UtilFiles.h"
#include "UtilCollect.h"
#include "PTApplsUnicodeUtils.h"
/*----------------------------------------------------------------------------*\
Application macros
\*----------------------------------------------------------------------------*/
#define RULE_FILE_READ 5

/*----------------------------------------------------------------------------*\
Application prototypes
\*----------------------------------------------------------------------------*/
ProError ProTestCavityLayoutModelNamesSet (ProCavityLayout *cvlayout_ptr);
char* ProTestCavityLayoutTypeToStr (ProCvLayoutType type);
ProError ProTestCavityLayoutSetup(ProCavityLayout *cvlayout);
ProError ProTestCavlayruleSet(ProCvLayoutRule *rule);
ProError ProUtilSelectCsys(ProCsys *csys, ProAsmcomppath *comppath);
ProError ProTestCavlayruleOrientSet(ProCvLayoutOrient *orient);
/*----------------------------------------------------------------------------*\
Application global/external data
\*----------------------------------------------------------------------------*/

/*============================================================================*\
    FUNCTION : ProTestCavityLayoutMenu	
    PURPOSE  : Setup menu for testing
\*============================================================================*/
ProError ProTestCavityLayoutMenu()
{
    ProError status;
    ProMdl mdl;
    int menu_id, action;
    ProMdlType type;
    ProAssembly assy_obj;
    ProError  ProTestCavityLayoutInfo();
    ProError  ProTestCavityLayoutRedefine();
    ProError  ProTestCavityLayoutCreate();
    
    status = ProMdlCurrentGet(&mdl);
    if (status != PRO_TK_NO_ERROR)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"NO current object");
        return(PRO_TK_NO_ERROR);
    }
    status = ProMdlTypeGet(mdl, &type);
    if(type == PRO_MDL_MFG)
    {
        status = ProMfgAssemGet((ProMfg)mdl, &assy_obj);
        mdl = assy_obj;   
    }
    
    status = ProMenuFileRegister((char*)"TkCavityLayout",(char*)"tkcavitylayout.mnu", &menu_id);
    status = ProMenubuttonActionSet((char*)"TkCavityLayout", (char*)"TkCavityLayout",
	(ProMenubuttonAction)ProMenuDelete, NULL, 0);
    status = ProMenubuttonActionSet((char*)"TkCavityLayout", (char*)"Info",
	(ProMenubuttonAction)ProTestCavityLayoutInfo, &mdl, 0);
    status = ProMenubuttonActionSet((char*)"TkCavityLayout", (char*)"Create",
	(ProMenubuttonAction)ProTestCavityLayoutCreate, &mdl, 0);
    status = ProMenubuttonActionSet((char*)"TkCavityLayout", (char*)"Redefine",
	(ProMenubuttonAction)ProTestCavityLayoutRedefine, &mdl, 0);
    status = ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkCavityLayout", NULL);
    status= ProMenuProcess((char*)"", &action);
    
    return ((ProError)0);
}

/*============================================================================*\
    FUNCTION : ProTestCavityLayoutInfo	
    PURPOSE  : Test Cavity Layout info functions 
\*============================================================================*/
ProError ProTestCavityLayoutInfo(ProMdl *mdl)
{
    ProError status;
    ProCavityLayout cvlayout;
    ProAsmcomppath csys_comp_path, leader_comp;
    ProCsys         csys;
    int count, i, j, csys_id;
    double min_x, min_y, min_z, max_x, max_y, max_z;
    ProMdl mdl_leader;
    ProModelitem item_lider;
    ProPath w_path;
    ProSelection sel;
    char fname[PRO_FILE_NAME_SIZE] = "cavity_layout.inf";
    char leader_name[PRO_MDLNAME_SIZE];
    FILE *fp;
    ProCvLayoutRule rule;
    ProCvLayoutType type, basic_type;
    int cavity_num, cavity_num_x, cavity_num_y;
    double *increment1_arr, *increment2_arr, *increment3_arr;
    ProCvLayoutOrient orient;
    ProMdlName *model_names;
	ProMdlName mdl_name;

    fp = PTApplsUnicodeFopen(fname, "w");
    if(fp == NULL)
        return(PRO_TK_GENERAL_ERROR);
                      
    status = ProCavitylayoutCountGet(*mdl, &count);
    TEST_CALL_REPORT("ProCavitylayoutCountGet()",
        "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
    if(count == 0)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Cavity Layout not found");
        return(PRO_TK_E_NOT_FOUND);
    }
    for (i = 0; i<count;i++)
    {
        status = ProCavitylayoutGetByNumber(*mdl, i, &cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutGetByNumber()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
                    
        status = ProCavitylayoutLeaderGet(cvlayout, &mdl_leader);
        TEST_CALL_REPORT("ProCavitylayoutLeaderGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
                    
        status = ProMdlToModelitem(mdl_leader, &item_lider);
        TEST_CALL_REPORT("ProMdlToModelitem()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
        status = ProMdlMdlnameGet(*mdl, mdl_name);
        TEST_CALL_REPORT("ProMdlMdlnameGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
             
        ProWstringToString(leader_name, mdl_name);
        ProTKFprintf(fp, (char*)"\n Cavity Layout nuber %d",i+1);
        ProTKFprintf(fp,(char*)"\n Leader name : %s", leader_name);
        
        status = ProCavitylayoutOutlineGet(cvlayout, &min_x, &min_y, &min_z,
            &max_x, &max_y, &max_z);
        TEST_CALL_REPORT("ProCavitylayoutOutlineGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
        ProTKFprintf(fp, (char*)"\n Outline:"); 
        ProTKFprintf(fp, (char*)"\n min_x = %.2f\t min_y = %.2f\t min_z = %.2f\n"
                " max_x = %.2f\t max_y = %.2f\t max_z = %.2f",
                min_x, min_y, min_z, max_x, max_y, max_z);
                
        status = ProCavitylayoutLeaderCompGet (cvlayout, &leader_comp);
        TEST_CALL_REPORT("ProCavitylayoutLeaderCompGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
                    
        status = ProSelectionAlloc(&leader_comp, &item_lider, &sel);
        TEST_CALL_REPORT("ProSelectionAlloc()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
                    
        status = ProSelectionHighlight(sel, PRO_COLOR_HIGHLITE);
        TEST_CALL_REPORT("ProSelectionHighlight()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
    
        status = ProCavitylayoutLeaderCsysGet (cvlayout, &csys_comp_path,
            &csys);
        TEST_CALL_REPORT("ProCavitylayoutLeaderCsysGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
                    
        status = ProCsysIdGet(csys, &csys_id);
        TEST_CALL_REPORT("ProCsysIdGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
        ProTKFprintf(fp, (char*)"\n csys_leader_id = %d", csys_id);
        
        status = ProCavitylayoutOriginGet(cvlayout, &csys_comp_path, &csys);
        TEST_CALL_REPORT("ProCavitylayoutOriginGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
        
        status = ProCsysIdGet(csys, &csys_id);
        TEST_CALL_REPORT("ProCsysIdGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
        ProTKFprintf(fp, (char*)"\n csys_origin_id = %d", csys_id); 
           
        status = ProCavitylayoutRuleGet(cvlayout, &rule);
        TEST_CALL_REPORT("ProCavitylayoutRuleGet()",
		    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
                    
        status = ProCavlayruleTypeGet(rule, &type, &basic_type);
        TEST_CALL_REPORT("ProCavlayruleTypeGet()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
        ProTKFprintf(fp,(char*)"\n type : %s \t basic_type : %s \n",
            ProTestCavityLayoutTypeToStr(type), 
            ProTestCavityLayoutTypeToStr(basic_type));
             
        switch (type)
        {
        case PRO_CVLAYOUT_CIRCULAR :
            status = ProCavlayruleCircDataGet(rule, &orient, &cavity_num, 
                &min_x,  &min_y, &min_z);
            TEST_CALL_REPORT("ProCavlayruleCircDataGet()",
	        "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
            ProTKFprintf(fp,(char*)" Orientation type : %d \n number of Components : %d \n"
                " Angular displacement : %.2f \n Angle for the first component : "
                "%.2f \n Raduis of the layout : %.2f", orient, cavity_num, min_x, 
                 min_y, min_z);  
                
            break;
        case  PRO_CVLAYOUT_RECTANG :
            status = ProCavlayruleRectDataGet(rule, &orient, &cavity_num_x, 
                &cavity_num_y, &min_x, &min_y);
            TEST_CALL_REPORT("ProCavlayruleRectDataGet()",
	        "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
            ProTKFprintf(fp,(char*)" Orientation type : %d \n Number of columns : %d \n"
            " Number of rows : %d \n Displacement step in x direction : %.2f \n"
            " Displacement step in y direction : %.2f \n", orient, cavity_num_x,
            cavity_num_y, min_x, min_y);
            
            break;
        case PRO_CVLAYOUT_VARIABLE :
            status = ProArrayAlloc(0, sizeof(double), 1, 
                (ProArray*)&increment1_arr);
            status = ProArrayAlloc(0, sizeof(double), 1, 
                (ProArray*)&increment2_arr);
            status = ProArrayAlloc(0, sizeof(double), 1, 
                (ProArray*)&increment3_arr);
            status = ProCavlayruleVarDataGet(rule, &cavity_num, &increment1_arr, 
                &increment2_arr, &increment3_arr);
            TEST_CALL_REPORT("ProCavlayruleVarDataGet()",
	            "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
            ProTKFprintf(fp,(char*)" Number of rows : %d \n", cavity_num);    
            ProTKFprintf(fp,(char*)" Table dimension :\n first   second   third\n");
            for (j = 0; j <  cavity_num; j++)
            {
                ProTKFprintf(fp,(char*)" %.2f    %.2f     %.2f \n", increment1_arr[j], 
                    increment2_arr[j], increment3_arr[j]);
            }
            ProArrayFree((ProArray*)&increment1_arr);
            ProArrayFree((ProArray*)&increment2_arr);
            ProArrayFree((ProArray*)&increment3_arr);
            
            status = ProCavitylayoutModelMdlnamesGet (cvlayout, &model_names);
            TEST_CALL_REPORT("ProCavitylayoutModelMdlnamesGet()",
    	        "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
            ProTKFprintf(fp,(char*)" Model names:\n");
            for (j = 0; j < cavity_num; j++)
            {
                ProTKFprintf(fp,(char*)" Name[%d]: %s\n", j, 
                    ProWstringToString (leader_name, model_names[j]));
            } 
            ProArrayFree((ProArray*)&model_names);
            
            break;
        default :;
        }
        
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Enter name of file to store rule");
        status = ProMessageStringRead (PRO_NAME_SIZE, w_path);
        status = ProCavlayruleFileWrite(rule, w_path); 
        TEST_CALL_REPORT("ProCavlayruleFileWrite()",
	    "ProTestCavityLayoutInfo()", status, status != PRO_TK_NO_ERROR);
    }
    fclose(fp);
    ProStringToWstring(w_path, fname);
    ProInfoWindowDisplay(w_path, NULL, NULL);     
    return(PRO_TK_NO_ERROR);

}

/*============================================================================*\
    FUNCTION : ProTestCavityLayoutRedefine	
    PURPOSE  : Recreates an existing Cavity Layout 
\*============================================================================*/
ProError ProTestCavityLayoutRedefine( ProMdl *mdl)
{
    ProError status;
    ProCavityLayout cvlayout;
     
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select cavity layout.");
    status = ProCavitylayoutSelect(*mdl, &cvlayout);
    TEST_CALL_REPORT("ProCavitylayoutSelect()",
	"ProTestCavityLayoutRedefine()", status, status != PRO_TK_NO_ERROR);
        
    status = ProTestCavityLayoutSetup(&cvlayout);
    if(status != PRO_TK_NO_ERROR)
        return(status);    
    status = ProCavitylayoutRedefine(cvlayout);
    TEST_CALL_REPORT("ProCavitylayoutRedefine()",
	"ProTestCavityLayoutRedefine()", status, status != PRO_TK_NO_ERROR);
                    
    return(status); 
    
}

/*============================================================================*\
    FUNCTION : ProTestCavityLayoutCreate
    PURPOSE  : Create new Cavity Layout 
\*============================================================================*/
ProError ProTestCavityLayoutCreate( ProMdl *mdl)
{
    ProError status;
    ProCavityLayout cvlayout;
    int opt = 0, n_sel = 0;
    ProMdlName name_leader;
    ProMdl out_leader;
    ProModelitem item_leader;
    ProSelection *p_sel;
    
    static ProUtilMenuButtons create_opt[] = { 
        {"TkCLCreate",  0, TEST_CALL_PRO_MENU_DELETE},
        {"New",         0, 0},
        {"AddComp",     1, 0},
        {"SetMdlNames", 2, 0},
        {"",            0, 0}
    };
    
    status = ProUtilMenuIntValueSelect(create_opt, &opt);
    switch(opt)
    {
    case 0:       
        status = ProCavitylayoutAlloc(*mdl, &cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutAlloc()",
	        "ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
        
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select leader model");
        status = ProSelect((char*)"prt_or_asm", 1, NULL, NULL, NULL, NULL, 
            &p_sel, &n_sel);
        TEST_CALL_REPORT("ProSelect()", "ProTestCavityLayoutCreate()",
	    status, status != PRO_TK_NO_ERROR );
        
        if (status != PRO_TK_NO_ERROR)
	        return (status);
        
        ProUtilMsgPrint ((char*)"gen", (char*)"TEST %0s",
            "Enter name for the reference model");
        status = ProMessageStringRead (PRO_NAME_SIZE, name_leader);
        status = ProSelectionModelitemGet(p_sel[0], &item_leader);
        TEST_CALL_REPORT("ProSelectionModelitemGet()", 
            "ProTestCavityLayoutCreate()",status, status != PRO_TK_NO_ERROR );
        
        status = ProCavitylayoutLeaderMdlnameSet(cvlayout, item_leader.owner, 
            name_leader, &out_leader);
        TEST_CALL_REPORT("ProCavitylayoutLeaderMdlnameSet()",
	        "ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
        
        status = ProTestCavityLayoutSetup(&cvlayout);
        if(status != PRO_TK_NO_ERROR)
            break;
        
        status = ProCavitylayoutCreate(cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutCreate()",
        	"ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
        break;
    case 1:
        status = ProCavitylayoutSelect (*mdl, &cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutSelect()",
	        "ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
        
        status = ProTestCavityLayoutSetup(&cvlayout);
        if(status != PRO_TK_NO_ERROR)
            break;
        
        status = ProCavitylayoutCreate(cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutCreate()",
	        "ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
        break;
    case 2:
        status = ProCavitylayoutSelect (*mdl, &cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutSelect()",
	        "ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
        status = ProTestCavityLayoutModelNamesSet (&cvlayout);

        status = ProCavitylayoutCreate(cvlayout);
        TEST_CALL_REPORT("ProCavitylayoutCreate()",
        	"ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);

        break;
    } 

    status = ProCavitylayoutFree ((ProCavityLayout*)cvlayout);
    TEST_CALL_REPORT("ProCavitylayoutFree()",
        "ProTestCavityLayoutCreate()", status, status != PRO_TK_NO_ERROR);
                     
    return(status); 
}

/*============================================================================*\
    FUNCTION : ProTestCavityLayoutSetup	
    PURPOSE  : Initialize Cavity Layout handle
\*============================================================================*/
ProError ProTestCavityLayoutSetup(ProCavityLayout *cvlayout)
{
    ProError status; 
    ProAsmcomppath leader_abs_path, leader_path, origin_path;
    ProCvLayoutRule rule;
    ProCsys leader_csys, origin_csys;
      
    /* Set leader csys */ 
    ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s", (char*)"Select leader csys:");
    status = ProUtilSelectCsys(&leader_csys, &leader_abs_path);
    if(status != PRO_TK_NO_ERROR)
        return(status);

    /* The function ProCavitylayoutLeaderCsysSet takes leader_path
        with respect to leader model. So it is necessary to
        shorten leader_path */
    status = ProAsmcomppathInit( leader_abs_path.owner,
        &(leader_abs_path.comp_id_table[1]),
        leader_abs_path.table_num-1, &leader_path );
    TEST_CALL_REPORT( "ProAsmcomppathInit", "ProTestCavityLayoutSetup()",
        status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
        return (status);

    status = ProCavitylayoutLeaderCsysSet(*cvlayout, &leader_path, 
        leader_csys);
     TEST_CALL_REPORT("ProCavitylayoutLeaderCsysSet()",
	"ProCavitylayoutLeaderCsysSet()", status, status != PRO_TK_NO_ERROR);
    if(status != PRO_TK_NO_ERROR)
        return(status);

    /* Set origin */    
    ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s", (char*)"Select origin csys;");    
    status = ProUtilSelectCsys(&origin_csys, &origin_path);
    if(status != PRO_TK_NO_ERROR)
        return(status);

    status = ProCavitylayoutOriginSet(*cvlayout, &origin_path, 
        origin_csys); 
    TEST_CALL_REPORT("ProCavitylayoutOriginSet()",
	"ProTestCavityLayoutSetup()", status, status != PRO_TK_NO_ERROR);

    /* Set rule */
    status = ProCavlayruleAlloc(&rule);
    TEST_CALL_REPORT("ProCavlayruleAlloc()",
	"ProTestCavityLayoutSetup()", status, status != PRO_TK_NO_ERROR);
   
    status = ProTestCavlayruleSet(&rule);
    
    status = ProCavitylayoutRuleSet(*cvlayout, rule);
    TEST_CALL_REPORT("ProCavitylayoutRuleSet()",
	"ProTestCavityLayoutSetup()", status, status != PRO_TK_NO_ERROR);
    
    status = ProCavlayruleFree (rule); 
    TEST_CALL_REPORT("ProCavlayruleFree()",
	"ProTestCavityLayoutSetup()", status, status != PRO_TK_NO_ERROR);
       
    return(status);
}

/*============================================================================*\
    FUNCTION : ProTestCavlayruleSet	
    PURPOSE  : Setup  Cuvity Layout rule
\*============================================================================*/
ProError ProTestCavlayruleSet(ProCvLayoutRule *rule)
{
    char                sel_path[PRO_PATH_SIZE];    
    int                 i, type;
    int                 cavity_num_x = 2, cavity_num_y = 2, cavity_num;
    int                 range_int[2] = {0, 200}, def_int = 1;
    double              range[2] = {0, 200}, def = 1;
    double              cavity_step_x = 1, cavity_step_y = 1;
    double              cavity_step, start_angle, radius;
    double              param;
    double              *increment1_arr, *increment2_arr, *increment3_arr;
    ProError            status;
    ProPath	            w_curr_path, w_new_path, w_file_name, w_sel_path;
    ProMdlName          w_mdlname;
	ProMdlExtension     w_file_ext;
    ProCvLayoutOrient   orient;
static ProUtilMenuButtons rule_type[] = { 
                            {"TkRuleSet",   0, TEST_CALL_PRO_MENU_DELETE},
                            {"Single",      PRO_CVLAYOUT_SINGLE,    0},
                            {"Rectang",     PRO_CVLAYOUT_RECTANG,   0},
                            {"Circular",    PRO_CVLAYOUT_CIRCULAR,  0},
                            {"Variable",    PRO_CVLAYOUT_VARIABLE,  0},
                            {"ReadFile",    RULE_FILE_READ,         0},
                            {"",            0,                      0}};

    status = ProUtilMenuIntValueSelect(rule_type, &type);
    switch(type)
    {
    case PRO_CVLAYOUT_SINGLE:
        status = ProCavlayruleSingleSet(*rule);
        TEST_CALL_REPORT("ProCavlayruleSingleSet()", "ProTestCavlayruleSet()",
					    status, status != PRO_TK_NO_ERROR);
        break;
    case PRO_CVLAYOUT_RECTANG :
        status = ProTestCavlayruleOrientSet (&orient);
        if (status != PRO_TK_NO_ERROR)
            return(status);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter number of columns in the layout");
        ProUtilIntGet(range_int, &def_int, &cavity_num_x);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter number of rows in the layout");
        ProUtilIntGet(range_int, &def_int, &cavity_num_y);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter displacement step in x direction");
        ProUtilDoubleGet(range, &def, &cavity_step_x);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter displacement step in y direction");
        ProUtilDoubleGet(range, &def, &cavity_step_y);
        status = ProCavlayruleRectSet(*rule, orient, cavity_num_x, 
            cavity_num_y, cavity_step_x, cavity_step_y);
        TEST_CALL_REPORT("ProCavlayruleRectSet()", "ProTestCavlayruleSet()",
					    status, status != PRO_TK_NO_ERROR);

        break;
    case PRO_CVLAYOUT_CIRCULAR :
        status = ProTestCavlayruleOrientSet(&orient);
        if (status != PRO_TK_NO_ERROR)
            return(status);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter number of components in the layout");
        ProUtilIntGet(range_int, &def_int, &cavity_num);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter angular displacement");
        ProUtilDoubleGet(range, &def, &cavity_step);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter angle for the first component");
        ProUtilDoubleGet(range, &def, &start_angle);
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter raduis of the layout");
        ProUtilDoubleGet(range, &def, &radius);
        status = ProCavlayruleCircSet(*rule, orient, cavity_num, cavity_step, 
            start_angle, radius);
        TEST_CALL_REPORT("ProCavlayruleCircSet()", "ProTestCavlayruleSet()",
					    status, status != PRO_TK_NO_ERROR);
        break;
    case PRO_CVLAYOUT_VARIABLE :
        status = ProArrayAlloc(0, sizeof(double), 1, 
            (ProArray*)&increment1_arr);
        status = ProArrayAlloc(0, sizeof(double), 1, 
            (ProArray*)&increment2_arr);
        status = ProArrayAlloc(0, sizeof(double), 1, 
            (ProArray*)&increment3_arr);
            
        ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
            "Enter number of rows in Variable Layout Table");
        ProUtilIntGet(range_int, &def_int, &cavity_num);   
         
        for(i=0; i < cavity_num; i++)
        {
            ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
                "Enter increments for the first table dimension");
            status = (ProError)ProUtilDoubleGet(range, &def, &param);    
            status = ProArrayObjectAdd((ProArray*)&increment1_arr,
             PRO_VALUE_UNUSED, 1, &param);
           
            ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
                "Enter increments for the second table dimension");
            status = (ProError)ProUtilDoubleGet(range, &def, &param);
            status = ProArrayObjectAdd((ProArray*)&increment2_arr, 
                PRO_VALUE_UNUSED, 1, &param);
            
            ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s",
                "Enter increments for the third table dimension");
            status = (ProError)ProUtilDoubleGet(range, &def, &param);
            status = ProArrayObjectAdd((ProArray*)&increment3_arr, 
                PRO_VALUE_UNUSED, 1, &param);
        }
        status = ProCavlayruleVarSet(*rule, cavity_num, increment1_arr, 
            increment2_arr, increment3_arr);
        TEST_CALL_REPORT("ProCavlayruleVarSet()", "ProTestCavlayruleSet()",
					    status, status != PRO_TK_NO_ERROR);
        
        ProArrayFree((ProArray*)&increment1_arr);
        ProArrayFree((ProArray*)&increment2_arr);
        ProArrayFree((ProArray*)&increment3_arr);
        break;
    case RULE_FILE_READ:
        status = ProDirectoryCurrentGet (w_curr_path);
	    /* Bring up the file selecton dialog */
	    status = ProUtilFileOpen( (char*)"*.*", sel_path );
	    if( status != PRO_TK_NO_ERROR )
	        return status;

        ProStringToWstring (w_sel_path, sel_path);
        status = ProFileMdlnameParse (w_sel_path, w_new_path,
                                   w_mdlname, w_file_ext, NULL);

        ProUtilWstrcpy (w_file_name, w_mdlname);
        ProUtilWstrStrcatToWstr (w_file_name, (char*)".");
        ProUtilWstrcat (w_file_name, w_file_ext);

        /* Read the selected file */
        status = ProDirectoryChange (w_new_path);
	    status = ProCavlayruleFileRead( *rule, w_file_name);
	    TEST_CALL_REPORT( "ProCavlayruleFileRead()",  "ProTestCavlayruleSet()",
		    status, status != PRO_TK_NO_ERROR);
        ProDirectoryChange (w_curr_path);
        break;
    default:
        break;
    }
    return (status);
}

/*============================================================================*\
    FUNCTION : ProTestCavlayruleOrientSet	
    PURPOSE  : Get orient type 
\*============================================================================*/
ProError ProTestCavlayruleOrientSet(ProCvLayoutOrient *orient)
{
    ProError status;
    int type;
    static ProUtilMenuButtons orient_type[] = { 
        {"OrientSet",  0,                       TEST_CALL_PRO_MENU_DELETE},
        {"Constant",   PRO_CVLAYOUT_CONSTANT,   0},
        {"Xsymmetric", PRO_CVLAYOUT_XSYMMETRIC, 0},
        {"Ysymmetric", PRO_CVLAYOUT_YSYMMETRIC, 0},
        {"Radial",     PRO_CVLAYOUT_RADIAL,     0},
        {"",           0,                       0}
    };
   status = ProUtilMenuIntValueSelect(orient_type, &type);
   *orient =  (ProCvLayoutOrient)type;
   return(status);
}

/*============================================================================*\
    FUNCTION : ProUtilSelectCsys	
    PURPOSE  : Select Csys and get path
\*============================================================================*/
ProError ProUtilSelectCsys(ProCsys *csys, 
                           ProAsmcomppath *comppath)
{
    ProError status;
    ProSelection *p_sel;
    int n_sel;
    ProAsmcomppath comp_path;
    ProModelitem item_csys;
    
    status = ProSelect((char*)"csys", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel);
    TEST_CALL_REPORT("ProSelect()", "ProUtilSelectCsys()",
	    status, status != PRO_TK_NO_ERROR );
    if (status != PRO_TK_NO_ERROR)
	return (status);
        
    status = ProSelectionModelitemGet(p_sel[0], &item_csys);
    TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProUtilSelectCsys()",
					    status, status != PRO_TK_NO_ERROR);
        
    status = ProSelectionAsmcomppathGet(p_sel[0], &comp_path);
    TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProUtilSelectCsys()",
					    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()", "ProUtilSelectCsys()",
					    status, status != PRO_TK_NO_ERROR);
    status = ProCsysInit((ProSolid)item_csys.owner, item_csys.id, csys);
    TEST_CALL_REPORT("ProCsysInit()", "ProUtilSelectCsys()",
					    status, status != PRO_TK_NO_ERROR);
    return(status);
}

/*============================================================================*\
    FUNCTION : 	ProTestCavityLayoutTypeToStr
    PURPOSE  :	Retrieve name of layout's type.
\*============================================================================*/
char* ProTestCavityLayoutTypeToStr (ProCvLayoutType type)
{
    switch (type)
    {
    case PRO_CVLAYOUT_VARIABLE:
        return ((char*)"VARIABLE");
    case PRO_CVLAYOUT_CIRCULAR:
        return ((char*)"CIRCULAR");
    case PRO_CVLAYOUT_RECTANG:
        return ((char*)"RECTANG");
    case PRO_CVLAYOUT_SINGLE:
        return ((char*)"SINGLE");
    }
    return ((char*)"");
}

ProError ProTestCavityLayoutModelNamesSet (
    ProCavityLayout *cvlayout_ptr)
{
    int                 i, cavity_num, opt, butn_num = 0;
    double              *increment1_arr = NULL, *increment2_arr = NULL,
                        *increment3_arr = NULL;
    char                c_line[PRO_PATH_SIZE], c_name[PRO_MDLNAME_SIZE];
    ProError            status;
    ProCvLayoutRule     rule;
    ProCvLayoutType     type, basic_type;
    ProMdlName          *old_model_names = NULL;
    ProMdlName          *new_model_names = NULL;
    ProFamtable         famtable;
    ProFaminstance      *famtable_items = NULL;
    ProMdl              mdl;
    ProMdlName          w_name;
    ProUtilMenuButtons  *itm_btns = NULL;
    ProSolid            solid;
    
    status = ProCavitylayoutLeaderGet (*cvlayout_ptr, &mdl);
    TEST_CALL_REPORT("ProCavitylayoutLeaderGet()",
		"ProTestCavityLayoutModelNamesSet()", status, 
        status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);
    
    if (status != PRO_TK_NO_ERROR)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
            "The cavity layout corresponding to the handle does not exists.");
        return status;
    }

    status = ProFaminstanceGenericGet (mdl, PRO_B_TRUE, (ProMdl*)&solid);
    TEST_CALL_REPORT("ProFaminstanceGenericGet()",
		"ProTestCavityLayoutModelNamesSet()", status, 
        status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

    if (status != PRO_TK_NO_ERROR)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s",
           "The specified model is not an instance - it has no generic model.");
        
        return status;
    }
    
    status = ProFamtableInit ((ProMdl)solid, &famtable);
    TEST_CALL_REPORT("ProFamtableInit()",
		"ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);

    status = ProUtilCollectFamtableInstance(&famtable, &famtable_items);

    if (status == PRO_TK_NO_ERROR)
    {
        status = ProArraySizeGet ((ProArray)famtable_items, &cavity_num);        
        
        status = ProArrayAlloc (cavity_num+2, sizeof(ProUtilMenuButtons), 1, 
            (ProArray*)&itm_btns);
        strcpy (itm_btns[butn_num].button, "TkClSetNames");
        itm_btns[butn_num].value        = 0;
        itm_btns[butn_num].special_flag = TEST_CALL_PRO_MENU_DELETE;
        butn_num = 1;
        for (i=0; i<cavity_num; i++)
        {
            status = ProFaminstanceMdlGet (&famtable_items[i], &mdl);
            TEST_CALL_REPORT("ProFaminstanceMdlGet()",
		        "ProTestCavityLayoutModelNamesSet()", status,
                status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND);

            if (status != PRO_TK_NO_ERROR)
            {
                status = ProFaminstanceRetrieve (famtable_items+i, &mdl);
                TEST_CALL_REPORT("ProFaminstanceRetrieve()",
		            "ProTestCavityLayoutModelNamesSet()", status,
                    status!=PRO_TK_NO_ERROR && status!=PRO_TK_E_NOT_FOUND);

                if (status != PRO_TK_NO_ERROR)
                    continue;
            }

            status = ProMdlMdlnameGet (mdl, w_name);
            TEST_CALL_REPORT("ProMdlMdlnameGet()",
                "ProTestCavityLayoutModelNamesSet()", status,
                status!=PRO_TK_NO_ERROR && status!=PRO_TK_E_NOT_FOUND);

            ProWstringToString (itm_btns[butn_num].button, w_name);
            itm_btns[butn_num].value       = butn_num;
            itm_btns[butn_num].special_flag= 0;
            butn_num++;
        }
        
        strcpy (itm_btns[butn_num].button, "");
        itm_btns[butn_num].value        = 0;
        itm_btns[butn_num].special_flag = 0;
        butn_num++;
    }
    ProArrayFree ((ProArray*)&famtable_items);
    
    status = ProCavitylayoutRuleGet (*cvlayout_ptr, &rule);
    TEST_CALL_REPORT("ProCavitylayoutRuleGet()",
		"ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);

    status = ProCavlayruleTypeGet (rule, &type, &basic_type);
    TEST_CALL_REPORT("ProCavlayruleTypeGet()",
	    "ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);

    ProTKPrintf((char*)"Rule type : %s \t basic_type : %s \n",
        ProTestCavityLayoutTypeToStr(type), 
        ProTestCavityLayoutTypeToStr(basic_type));

    if (type != PRO_CVLAYOUT_VARIABLE)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Its not variable cavity layout.");
        return PRO_TK_E_NOT_FOUND;
    }

    status = ProArrayAlloc(0, sizeof(double), 1, 
            (ProArray*)&increment1_arr);
    status = ProArrayAlloc(0, sizeof(double), 1, 
            (ProArray*)&increment2_arr);
    status = ProArrayAlloc(0, sizeof(double), 1, 
            (ProArray*)&increment3_arr);

    status = ProCavlayruleVarDataGet (rule, &cavity_num, &increment1_arr, 
            &increment2_arr, &increment3_arr);
    TEST_CALL_REPORT("ProCavlayruleVarDataGet()",
        "ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);

    ProArrayFree((ProArray*)&increment1_arr);
    ProArrayFree((ProArray*)&increment2_arr);
    ProArrayFree((ProArray*)&increment3_arr);

    ProTKSprintf (c_line, (char*)" Number of rows: %d", cavity_num);
    ProUtilMsgPrint ((char*)"gen", (char*)"TEST %0s", c_line);

    status = ProCavitylayoutModelMdlnamesGet (*cvlayout_ptr, &old_model_names);
    TEST_CALL_REPORT("ProCavitylayoutModelMdlnamesGet()",
        "ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);

    ProTKPrintf ((char*)"Old names:\n");
    for (i=0; i<cavity_num; i++)
    {
        ProTKPrintf ((char*)"\t%s.\n",
            ProWstringToString (c_name, old_model_names[i]));
    }
    
    ProTKPrintf ((char*)"We can set %d ProMdlName types in ProArray.\n", i);

    status = ProArrayAlloc (cavity_num, sizeof(ProMdlName), 1, 
            (ProArray*)&new_model_names);

    for (i=0; i<cavity_num; i++)
    {
        ProTKSprintf (c_line, (char*)"Select name of pattern model %s [%d].",
            ProWstringToString (c_name, old_model_names[i]), i);
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", c_line);

        status = ProUtilMenuIntValueSelect (itm_btns, &opt);
        
         ProStringToWstring (new_model_names[i], itm_btns[opt].button);
    }
    
    ProArrayFree((ProArray*)&itm_btns);

    status = ProCavitylayoutModelMdlnamesSet (*cvlayout_ptr, new_model_names);
    TEST_CALL_REPORT("ProCavitylayoutModelMdlnamesSet()",
        "ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);

    ProArrayFree((ProArray*)&old_model_names);
    
    status = ProCavitylayoutModelMdlnamesGet (*cvlayout_ptr, &old_model_names);
    TEST_CALL_REPORT("ProCavitylayoutModelMdlnamesGet()",
        "ProTestCavityLayoutModelNamesSet()",
        status, status != PRO_TK_NO_ERROR);
    ProTKPrintf ((char*)"New names:\n");
    for (i=0; i<cavity_num; i++)
    {
        ProTKPrintf ((char*)"\t%s.\n",
            ProWstringToString (c_name, old_model_names[i]));
    }
    ProArrayFree((ProArray*)&old_model_names);
    
    ProArrayFree((ProArray*)&new_model_names);
    
    return PRO_TK_NO_ERROR;
}