/*
	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 <ProAsmcomp.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 <ProScope.h>

#include "TestError.h"
#include <PTApplsUnicodeUtils.h>
#include <ProTKRunTime.h>
#include <UtilMessage.h>

/*--------------------------------------------------------------------*\
Application macros
\*--------------------------------------------------------------------*/
#define BUTTON_CANCEL 0
#define BUTTON_DONE 1

#define TOTAL_ITEMS( array_name ) \
(sizeof (array_name)/sizeof (MenuButt))

/*--------------------------------------------------------------------*\
Application data types
\*--------------------------------------------------------------------*/
typedef struct tag_menu_but{
	char *button;
	int action;	
    } MenuButt;


/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/
    MenuButt butts1[] =
    {
	{(char *)"All", PRO_REFCTRL_ALLOW_ALL},
	{(char *)"Subassembly",PRO_REFCTRL_ALLOW_SUBASSEMBLY },
	{(char *)"Skeleton",PRO_REFCTRL_ALLOW_SKELETON },
	{(char *)"None", PRO_REFCTRL_ALLOW_NONE },
	{(char *)"", -1}	
    };
    
    MenuButt butts2[] =
    {
	{(char *)"Create backup",PRO_REFCTRL_BACKUP_REF },
	{(char *)"Prohobit out-of-scope",PRO_REFCTRL_PROHIBIT_REF },
	{(char *)"", -1}
    };

    MenuButt butts3[] =
    {
	{(char *)"Done",BUTTON_DONE },
	{(char *)"Cancel",BUTTON_CANCEL },
	{(char *)"", -1}
    };

ProError ProTestXRControlOptionsGet (ProExtRefScope * xr_scope,
    ProInvalidRefBehavior* behavior);
int ProTestRefCtrlSolidSelectSet (ProAppData data, int dummy);
int ProTestRefCtrlEnvirSet (ProAppData data, int dummy);
int  ProTestRefCtrlSolidCurrentSet (ProAppData data, int dummy);
int ProTestRefCtrlEnvirGet (ProAppData data, int dummy);
int  ProTestRefCtrlSolidSelectGet (ProAppData data, int dummy);
int  ProTestRefCtrlSolidAllGet (ProAppData data, int dummy);
int  ProTestRefCtrlCheckScope (ProAppData data, int dummy);
/*-------------------------------------------------------------------*\
  COPIED REFERENCES MENU
\*-------------------------------------------------------------------*/
int ProTestCopiedRefSolidSelectStateGet (ProAppData data, int dummy);
int  ProTestCopiedRefSolidAllGet (ProAppData data, int dummy);
int ProTestCopiedRefDependSet (ProAppData data, int dummy);
int ProTestCopiedRefInDependSet (ProAppData data, int dummy);



/*====================================================================*\
  Function : ProTestCopiedRefMenuProcc
  Purpose  : Menu callback
\*====================================================================*/
int ProTestCopiedRefMenuProcc (ProAppData data, int dummy)
{
    int dummyx, i;
    char * tk_copiedref_items[] = {
	"CRSolidStateGet",
	"CRAllStateGet",
	"CopiedRefDependSet",
	"CRInDependSet",
	""
    };
    wchar_t * wnames1 [sizeof(tk_copiedref_items)/sizeof (char*)];

    for (i=0; i<sizeof(tk_copiedref_items)/sizeof (char*); i++)
    {
	wnames1[i] = (wchar_t*)calloc(PRO_NAME_SIZE, sizeof(wchar_t));
	ProStringToWstring(wnames1[i], tk_copiedref_items[i]);
    }

    ProMenuFromStringsRegister((char *)"-TkCopiedRef", NULL, wnames1, NULL, 
	    NULL, &dummyx);
    ProMenubuttonActionSet((char *)"-TkCopiedRef", tk_copiedref_items[0],
	    (ProMenubuttonAction)ProTestCopiedRefSolidSelectStateGet,
	(ProAppData) data , 0);
    ProMenubuttonActionSet((char *)"-TkCopiedRef", tk_copiedref_items[1],
	    (ProMenubuttonAction)ProTestCopiedRefSolidAllGet,
	(ProAppData) data ,0);
    ProMenubuttonActionSet((char *)"-TkCopiedRef", tk_copiedref_items[2],
	    (ProMenubuttonAction)ProTestCopiedRefDependSet,
	(ProAppData) data , 0);
    ProMenubuttonActionSet((char *)"-TkCopiedRef", tk_copiedref_items[3],
	    (ProMenubuttonAction)ProTestCopiedRefInDependSet,
	(ProAppData) data , 0);
    ProMenubuttonActionSet((char *)"-TkCopiedRef", tk_copiedref_items[4],
	    (ProMenubuttonAction)ProMenuDelete,
	(ProAppData) data ,0);
   
    ProMenubuttonActionSet((char *)"-TkCopiedRef",(char *)"-TkCopiedRef" , 
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) data ,
	0);

    ProMenuCreate(PROMENUTYPE_MAIN,(char *)"-TkCopiedRef" , NULL);
    ProMenuProcess((char *)"-TkCopiedRef", &dummyx);

    return (0);
}

    



/*====================================================================*\
  Function : 
  Purpose  : 
\*====================================================================*/
char * ProTestScopeToString ( ProExtRefScope scope)
{
    switch (scope)
    {
	case PRO_REFCTRL_ALLOW_ALL:
	    return (char *)"All";
	case PRO_REFCTRL_ALLOW_SUBASSEMBLY:
	    return (char *)"Subassembly";
	case PRO_REFCTRL_ALLOW_SKELETON:
	    return (char *)"Skeleton";
	case PRO_REFCTRL_ALLOW_NONE:
	    return (char *)"None";
    }

    return (char *)"";
}
/*====================================================================*\
  Function : 
  Purpose  : 
\*====================================================================*/
char * ProTestBehToString (ProInvalidRefBehavior bh)
{
    switch (bh)
    {
	case PRO_REFCTRL_BACKUP_REF:
	    return (char *)"Copy backup";
	case PRO_REFCTRL_PROHIBIT_REF:
	    return (char *)"Prohibit";
    }

    return (char *)"";
}

/*====================================================================*\
  Function : ProTestFileOpen()
  Purpose  : is used to open qcr file (if it is not open)
             in info functions.
\*====================================================================*/
int ProTestFileOpen (FILE ** qcr_ref)
{
    if (*qcr_ref != NULL)
	return 0;
   *qcr_ref = (FILE *)PTApplsUnicodeFopen ("extref.info", "w+t");
   /*printf ("trying open <qcr_ref>\n");*/
   if (*qcr_ref == NULL)
       return 1;
   /*printf ("open <qcr_ref> OK\n");*/
   return 0;
}

/*====================================================================*\
  Function : ProTestContrefHighlight()
  Purpose  : 
\*====================================================================*/
ProError ProTestScopeHighlight(
    ProExtRefScope  xr_scope)
{
    ProError err;
    int i;

    for (i=0; i<TOTAL_ITEMS(butts1); i++)
    {
	if (xr_scope != butts1[i].action)
	{
	    err = ProMenubuttonUnhighlight((char *)"RefControl",
		    butts1[i].button);
            TEST_CALL_REPORT ("ProMenubuttonUnhighlight()",
	            "ProTestScopeHighlight()",
                     err, err != PRO_TK_NO_ERROR);
	}
	else
	{
	    err = ProMenubuttonHighlight((char *)"RefControl",
		    butts1[i].button);
            TEST_CALL_REPORT ("ProMenubuttonHighlight()",
	            "ProTestScopeHighlight()",
                     err, err != PRO_TK_NO_ERROR);
	}
    }

    return err;
}

/*====================================================================*\
  Function : ProTestContrefHighlight()
  Purpose  : 
\*====================================================================*/
ProError ProTestBehaviorHighlight(
    ProInvalidRefBehavior  behavior)
{
    ProError err;
    int i;

    for (i=0; i<TOTAL_ITEMS(butts2); i++)
    {
	if (behavior != butts2[i].action)
	{
	    err = ProMenubuttonUnhighlight((char *)"RefScope",
		    butts2[i].button);
            TEST_CALL_REPORT ("ProMenubuttonUnhighlight()",
	            "ProTestBehaviorHighlight()",
                     err, err != PRO_TK_NO_ERROR);
	}
	else
	{
	    err = ProMenubuttonHighlight((char *)"RefScope",
		    butts2[i].button);
            TEST_CALL_REPORT ("ProMenubuttonHighlight()",
	            "ProTestBehaviorHighlight()",
                     err, err != PRO_TK_NO_ERROR);
	}
    }

    return err;
}


/*====================================================================*\
  Function : ProTestContrefHighlight()
  Purpose  : 
\*====================================================================*/
int ProTestAssign(ProAppData p_member, int option)
{
    *((int *)p_member) = option;

    return (0);
}

/*====================================================================*\
  Function : ProTestContrefHighlight()
  Purpose  : 
\*====================================================================*/
void ProTestBackcopyActivSet (ProExtRefScope scope)
{

    ProError status;
     if (scope == PRO_REFCTRL_ALLOW_ALL)
    {
	status = ProMenubuttonDeactivate((char *)"RefScope", butts2[0].button);     
        TEST_CALL_REPORT ("ProMenubuttonDeactivate()", 
		"ProTestBackcopyActivSet()",
	        status, status != PRO_TK_NO_ERROR);
		status = ProMenubuttonDeactivate((char *)"RefScope", butts2[1].button);     
        TEST_CALL_REPORT ("ProMenubuttonDeactivate", 
		"ProTestBackcopyActivSet",
	        status, status != PRO_TK_NO_ERROR);
    }
    else
    {
	status = ProMenubuttonActivate((char *)"RefScope", butts2[0].button); 
        	TEST_CALL_REPORT ("ProMenubuttonActivate()", 
	           "ProTestBackcopyActivSet()",
	           status, status != PRO_TK_NO_ERROR);
                status = ProMenubuttonActivate((char *)"RefScope", butts2[1].button);
        	TEST_CALL_REPORT ("ProMenubuttonActivate()", 
	           "ProTestBackcopyActivSet()",
	           status, status != PRO_TK_NO_ERROR);
    }

     return;
}

/*====================================================================*\
  Function : ProTestContrefHighlight()
  Purpose  : 
\*====================================================================*/
int ProTestScopeAssign(ProAppData p_member, int option)
{
    *((int *)p_member) = option;
    ProTestBackcopyActivSet ((ProExtRefScope) option );
   

    return (0);
}

/*====================================================================*\
  Function : ProTestContrefHighlight()
  Purpose  : 
\*====================================================================*/
int ProTestDoneCancelAssign(ProAppData p_member, int option)
{
    ProError status;

    *((int *)p_member) = option;

    status = ProMenuDelete();
    status = ProMenuDelete();
    status = ProMenuDelete();

    TEST_CALL_REPORT("ProMenuDelete()","ProTestDoneCancelAssign()", status,
    				status != PRO_TK_NO_ERROR);
    
    return (0);
}

int  ProTestExtrefinfoMenuAction (ProAppData data, int dummy);

/*====================================================================*\
  Function : ProTestExtrnReferences()
  Purpose  : 
\*====================================================================*/
int ProTestExtrnReferences (ProMdl *model)
{
    FILE * qcr_ref = NULL;
    int dummy, i;

    char * tk_xrefcon_items[] = {
	"XRCSolidSet",
	"XRCEnvSet",
	"XRCCheckScope",
	"XRCSolidGet",
	"XRCEnvGet",
	"XRCAllSolidGet",
	"XRRefInfoGet",
	"-TkCopiedRef",
	"quit",
	""
    };
    wchar_t * wnames1 [sizeof(tk_xrefcon_items)/sizeof (char*)];

    for (i=0; i<sizeof(tk_xrefcon_items)/sizeof (char*); i++)
    {
	wnames1[i] = (wchar_t*)calloc(PRO_NAME_SIZE, sizeof(wchar_t));
	ProStringToWstring(wnames1[i], tk_xrefcon_items[i]);
    }

    ProMenuFromStringsRegister((char *)"-TkXrefCont", NULL, wnames1, NULL, 
	    NULL, &dummy);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[0],
	    (ProMenubuttonAction)ProTestRefCtrlSolidSelectSet,
	(ProAppData) &qcr_ref , 0);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[1],
	    (ProMenubuttonAction)ProTestRefCtrlEnvirSet,
	(ProAppData) &qcr_ref ,0);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[2],
	    (ProMenubuttonAction)ProTestRefCtrlCheckScope,
	(ProAppData) &qcr_ref , 0);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[3],
	    (ProMenubuttonAction)ProTestRefCtrlSolidSelectGet,
	(ProAppData) &qcr_ref , 0);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[4],
	    (ProMenubuttonAction)ProTestRefCtrlEnvirGet,
	(ProAppData) &qcr_ref ,0);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[5], 
	    (ProMenubuttonAction)ProTestRefCtrlSolidAllGet,
	(ProAppData) &qcr_ref , 0);
     ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[6], 
	    (ProMenubuttonAction)ProTestExtrefinfoMenuAction,
	 (ProAppData) &qcr_ref ,
	0);

     ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[7], 
	    (ProMenubuttonAction)ProTestCopiedRefMenuProcc,
	 (ProAppData) &qcr_ref ,
	0);
     
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[8], 
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) &qcr_ref ,
	0);
    ProMenubuttonActionSet((char *)"-TkXrefCont", tk_xrefcon_items[9], 
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) &qcr_ref ,
	0);
    ProMenubuttonActionSet((char *)"-TkXrefCont",(char *)"-TkXrefCont" , 
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) &qcr_ref ,
	0);

    ProMenuCreate(PROMENUTYPE_MAIN,(char *)"-TkXrefCont" , NULL);
    ProMenuProcess((char *)"-TkXrefCont", &dummy);
    

    


    if (qcr_ref != NULL)
	fclose (qcr_ref);

    return (0);
}

/*====================================================================*\
  Function : ProTestXRControlOptionsGet()
  Purpose  : 
\*====================================================================*/
ProError ProTestXRControlOptionsGet (
    ProExtRefScope * xr_scope,
    ProInvalidRefBehavior* behavior)
{
    ProError err;
   
    wchar_t * wnames1 [TOTAL_ITEMS (butts1)];
    wchar_t * wnames2 [TOTAL_ITEMS (butts2)];
    wchar_t * wnames3 [TOTAL_ITEMS (butts3)];

    static char * menus [] = {"RefDone", "RefControl", "RefScope",  ""};
    int i, dummy;
    int done_cancel;

    for (i=0; i<TOTAL_ITEMS (butts1); i++)
    {
	wnames1[i] = (wchar_t*)calloc(PRO_NAME_SIZE, sizeof(wchar_t));
	ProStringToWstring(wnames1[i], butts1[i].button);
    }

    for (i=0; i<TOTAL_ITEMS (butts2); i++)
    {
	wnames2[i] = (wchar_t*)calloc(PRO_NAME_SIZE, sizeof(wchar_t));
	ProStringToWstring(wnames2[i], butts2[i].button);
    }

    for (i=0; i<TOTAL_ITEMS (butts3); i++)
    {
	wnames3[i] = (wchar_t*)calloc(PRO_NAME_SIZE, sizeof(wchar_t));
	ProStringToWstring(wnames3[i], butts3[i].button);
    }

/*----------------------------------------------------------*/

    err = ProMenuFromStringsRegister((char *)"RefControl", NULL, wnames1, NULL, 
	    NULL, &dummy);
    
    TEST_CALL_REPORT("ProMenuFromStringsRegister()", "ProTestXRControlOptionsGet()",
	    err, err != PRO_TK_NO_ERROR);
    for (i = 0; i< (TOTAL_ITEMS (butts1)) ; i++)
    {
	free(wnames1[i]);	    
    }

    err = ProMenubuttonActionSet(menus[1],menus[1], (ProMenubuttonAction)ProMenuDelete,
	NULL,0);
    
    for (i = 0; i< (TOTAL_ITEMS (butts1) - 1) ; i++)
    {
	ProMenubuttonActionSet( menus[1], butts1[i].button,
	    (ProMenubuttonAction)ProTestScopeAssign, (ProAppData) xr_scope,
	    butts1[i].action);
    }
    i = (TOTAL_ITEMS (butts1) - 1);
    ProMenubuttonActionSet( menus[1], butts1[i].button,
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) xr_scope,
	    butts1[i].action);

/*----------------------------------------------------------*/     

    err = ProMenuFromStringsRegister((char *)"RefScope", NULL, wnames2, NULL, 
	    NULL, &dummy);
    TEST_CALL_REPORT("ProMenuFromStringsRegister()", "ProTestXRControlOptionsGet()",
	    err, err != PRO_TK_NO_ERROR);
    for (i = 0; i< (TOTAL_ITEMS (butts2)) ; i++)
    {
	free(wnames2[i]);	    
    }
    err = ProMenubuttonActionSet(menus[2],menus[2], (ProMenubuttonAction)ProMenuDelete,
	NULL,0);
    for (i = 0; i< (TOTAL_ITEMS (butts2) - 1) ; i++)
    {
	ProMenubuttonActionSet( menus[2], butts2[i].button,
	    (ProMenubuttonAction)ProTestAssign, (ProAppData) behavior,
	    butts2[i].action);
    }
    i =(TOTAL_ITEMS (butts2) - 1) ;
    ProMenubuttonActionSet( menus[2], butts2[i].button,
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) behavior,
	    butts2[i].action);

/*----------------------------------------------------------*/

    err = ProMenuFromStringsRegister((char *)"RefDone", NULL, wnames3, NULL, 
	    NULL, &dummy);
			
    TEST_CALL_REPORT("ProMenuFromStringsRegister()", "ProTestSkelCopyCreate()",
	    err, err != PRO_TK_NO_ERROR);
    for (i = 0; i< (TOTAL_ITEMS (butts3)) ; i++)
    {
	free(wnames3[i]);	    
    }

    err = ProMenubuttonActionSet(menus[0],menus[0], (ProMenubuttonAction)ProMenuDelete,
	NULL,0);

    
    for (i = 0; i< (TOTAL_ITEMS (butts3) - 1) ; i++)
    {
	err = ProMenubuttonActionSet( menus[0], butts3[i].button,
	    (ProMenubuttonAction)ProTestDoneCancelAssign, (ProAppData) &done_cancel,
	    butts3[i].action);
    }

    i = (TOTAL_ITEMS (butts3) - 1);

    err = ProMenubuttonActionSet( menus[0], butts3[i].button,
	    (ProMenubuttonAction)ProMenuDelete, (ProAppData) &done_cancel,
	    butts3[i].action);


/*----------------------------------------------------------*/
   
    err = ProCompoundmenuCreate(menus, &dummy);
    TEST_CALL_REPORT ("ProCompoundmenuCreate()","ProTestXRControlOptionsGet()",
	 err ,
         err != PRO_TK_NO_ERROR);


    ProTestBehaviorHighlight(*behavior);
    ProTestScopeHighlight (*xr_scope);
    ProTestBackcopyActivSet (*xr_scope);
    
    err = ProMenuProcess(menus[0], &dummy);
     TEST_CALL_REPORT ("ProMenuProcess()", 
                   "ProTestXRControlOptionsGet()",
	           err, err != PRO_TK_NO_ERROR);

     if (done_cancel == BUTTON_DONE)
	 return (PRO_TK_NO_ERROR);

     return (PRO_TK_E_NOT_FOUND);
}

/*====================================================================*\
  Function : ProTestRefCtrlSolidSet()
  Purpose  : 
\*====================================================================*/
ProError ProTestRefCtrlSolidSet (
    ProSolid solid)
{
    ProError err = PRO_TK_NO_ERROR;
    ProExtRefScope scope = (ProExtRefScope)0;
    ProInvalidRefBehavior beh = (ProInvalidRefBehavior)0;

	 
    err = ProRefCtrlSolidGet (solid, &scope, &beh);
    TEST_CALL_REPORT ("ProRefCtrlSolidGet()", "ProTestRefCtrlSolidSet()", err ,
         err != PRO_TK_NO_ERROR);
	
    if (err == PRO_TK_E_NOT_FOUND)
    {
	scope = PRO_REFCTRL_ALLOW_ALL;
	beh = PRO_REFCTRL_BACKUP_REF;
    }
    else
	if (err != PRO_TK_NO_ERROR)
	    return err;
    
    err = ProTestXRControlOptionsGet (&scope, &beh);
    if (err==PRO_TK_E_NOT_FOUND)
	return (PRO_TK_NO_ERROR);

    err = ProRefCtrlSolidSet (solid, scope, beh);
    TEST_CALL_REPORT ("ProRefCtrlSolidSet()", "ProTestRefCtrlSolidSet()", err ,
         err != PRO_TK_NO_ERROR);

    return err;
}
    
/*====================================================================*\
  Function : ProTestRefCtrlEnvirSet()
  Purpose  : Menu callback
\*====================================================================*/
int ProTestRefCtrlEnvirSet (ProAppData data, int dummy)
{
    ProError err = PRO_TK_NO_ERROR;
    ProExtRefScope scope = (ProExtRefScope)0;
    ProInvalidRefBehavior beh = (ProInvalidRefBehavior)0;

    err = ProRefCtrlEnvirGet ( &scope, &beh);
    TEST_CALL_REPORT ("ProRefCtrlEnvirGet()", "ProTestRefCtrlEnvirSet()", err ,
         err != PRO_TK_NO_ERROR);
    
    if (err != PRO_TK_NO_ERROR)
	    return 0;
    
    err = ProTestXRControlOptionsGet (&scope, &beh);
    if (err==PRO_TK_E_NOT_FOUND)
	return (0);

    err = ProRefCtrlEnvirSet ( scope, beh);
    TEST_CALL_REPORT ("ProRefCtrlEnvirSet()", "ProTestRefCtrlEnvirSet()", err ,
         err != PRO_TK_NO_ERROR);

    return 0;
}    

/*====================================================================*\
  Function : ProTestRefCtrlSolidSelectSet()
  Purpose  : Menu buttun callback
\*====================================================================*/
int  ProTestRefCtrlSolidSelectSet (ProAppData data, int dummy)
{
    ProError err;
    int n_sel;
    ProSelection *sel_prt;
    ProModelitem mdl;
    ProSolid solid_to_RC_set;
 
    err = ProSelect((char *)"prt_or_asm", 1, NULL, NULL, NULL, NULL, &sel_prt, &n_sel);
    if (n_sel < 1 || err  != PRO_TK_NO_ERROR)
	return 0;
    TEST_CALL_REPORT("ProSelect()", "ProTestRefCtrlSolidSelectSet()",
	    err, err != PRO_TK_NO_ERROR && err != PRO_TK_USER_ABORT &&
	    err != PRO_TK_PICK_ABOVE);
    err = ProSelectionModelitemGet (sel_prt[0], (ProModelitem*) &mdl);
    TEST_CALL_REPORT("ProSelectionModelitemGet()",
	"ProTestRefCtrlSolidSelectSet()",
	    err, err != PRO_TK_NO_ERROR);
/* ??? */	
    err = ProModelitemMdlGet ( &mdl,  (ProMdl*)&solid_to_RC_set);
    TEST_CALL_REPORT("ProModelitemMdlGet()",
	"ProTestRefCtrlSolidSelectSet()",
	    err, err != PRO_TK_NO_ERROR);
   
    err = ProTestRefCtrlSolidSet (solid_to_RC_set);
    

    return (0);
}

/*====================================================================*\
  Function : ProTestRefCtrlSolidCurrentSet()
  Purpose  : Menu buttun callback
\*====================================================================*/
int  ProTestRefCtrlSolidCurrentSet (ProAppData data, int dummy)
{
    ProError err;
    ProSolid solid_to_RC_set;
    

    err = ProMdlCurrentGet ( (ProMdl*)&solid_to_RC_set);
    TEST_CALL_REPORT ("ProMdlCurrentGet",
	            "ProTestRefCtrlSolidCurrentSet",
                     err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
	return (0);
    
    err = ProTestRefCtrlSolidSet (solid_to_RC_set);
    

    return (0);
}


/*====================================================================*\
  Function : ProTestRefCtrlSolidGet()
  Purpose  : 
\*====================================================================*/
ProError ProTestRefCtrlSolidGet (
    FILE * qcr_ref,
    ProSolid solid)
{
    ProError err = PRO_TK_NO_ERROR;
    ProExtRefScope scope = (ProExtRefScope)0;
    ProInvalidRefBehavior beh = (ProInvalidRefBehavior)0;
    ProMdlName mdl_name;
    ProCharName cmdl_name;
    ProMdlType type;
    ProCharLine str;

    err = ProMdlMdlnameGet (solid,mdl_name);
    TEST_CALL_REPORT ("ProMdlMdlnameGet()", "ProTestRefCtrlSolidGet()", err ,
         err != PRO_TK_NO_ERROR);
    
    ProWstringToString (cmdl_name, mdl_name);
    err = ProMdlTypeGet (solid, &type);
    TEST_CALL_REPORT ("ProMdlTypeGet()", "ProTestRefCtrlSolidGet()", err ,
         err != PRO_TK_NO_ERROR);
    ProTKSprintf (str,
	"Model name : %s\n",
	cmdl_name);
    ProTKFprintf (qcr_ref,"%s", str);
    ProUtilMsgPrint( "gen", "TEST %0s", str);
    
    ProTKSprintf (str,
	"Model type : %d\n",
	type);
    
    ProTKFprintf (qcr_ref,"%s", str);
    ProUtilMsgPrint( "gen", "TEST %0s", str);
	
    err = ProRefCtrlSolidGet (solid, &scope, &beh);
    TEST_CALL_REPORT ("ProRefCtrlSolidGet()", "ProTestRefCtrlSolidGet()", err ,
         err != PRO_TK_NO_ERROR);
    
    if (err == PRO_TK_E_NOT_FOUND)
    {
	ProTKSprintf (str,
	    "No reference control options are set in the model \n");
	ProTKFprintf (qcr_ref,"%s", str);
        ProUtilMsgPrint( "gen", "TEST %0s", str);
	return (PRO_TK_NO_ERROR);
	
    }
    else
	if (err != PRO_TK_NO_ERROR)
	    return err;
    ProTKSprintf (str,
	"External reference scope :                 %s\n",
	ProTestScopeToString (scope));
    ProTKFprintf (qcr_ref,"%s", str);
    ProUtilMsgPrint( "gen", "TEST %0s", str);
    ProTKSprintf (str,
	"The system behavior upon scope violation : %s\n",
	ProTestBehToString(beh));
    ProTKFprintf (qcr_ref,"%s", str);
    ProUtilMsgPrint( "gen", "TEST %0s", str);
    
    return (PRO_TK_NO_ERROR);
}

    
/*====================================================================*\
  Function : ProTestRefCtrlEnvirGet()
  Purpose  : Menu callback
\*====================================================================*/
int ProTestRefCtrlEnvirGet (ProAppData data, int dummy)
{
    ProError err = PRO_TK_NO_ERROR;
    ProExtRefScope scope = (ProExtRefScope)0;
    ProInvalidRefBehavior beh = (ProInvalidRefBehavior)0;
    ProCharLine str;
    FILE * qcr_ref = *((FILE**) data);
    

    ProTestFileOpen (&qcr_ref);
    *((FILE**) data) = qcr_ref;

    ProTKFprintf (qcr_ref,
	"Run-time enviroment options for external reference control \n\n");

    err = ProRefCtrlEnvirGet ( &scope, &beh);
    TEST_CALL_REPORT ("ProRefCtrlEnvirGet()", "ProTestRefCtrlEnvirSet()", err ,
         err != PRO_TK_NO_ERROR);

    if (err != PRO_TK_NO_ERROR)
	return 0;

    ProTKSprintf (str,
	"External reference scope is : %s\n",
	ProTestScopeToString(scope));
    ProTKFprintf (qcr_ref,"%s", str);
    ProUtilMsgPrint( "gen", "TEST %0s", str);
    ProTKSprintf (str,
	"The system behavior upon scope violation is : %s\n",
	ProTestBehToString(beh));
    ProTKFprintf (qcr_ref,"%s", str);
    ProUtilMsgPrint( "gen", "TEST %0s", str);
    ProTKFprintf (qcr_ref,"\nEnd\n\n");

    return (0);
}

/*====================================================================*\
  Function : ProTestRefCtrlSolidSelectGet()
  Purpose  : Menu buttun callback
\*====================================================================*/
int  ProTestRefCtrlSolidSelectGet (ProAppData data, int dummy)
{
    ProError err;
    int n_sel;
    ProSelection *sel_prt;
    ProModelitem mdl;
    ProSolid solid_to_RC_set;
    FILE * qcr_ref = *((FILE**) data);

    ProTestFileOpen (&qcr_ref);
    *((FILE**) data) = qcr_ref;
    
    err = ProSelect((char *)"prt_or_asm", 1, NULL, NULL, NULL, NULL,
                    &sel_prt, &n_sel);
    if (n_sel < 1 || err  != PRO_TK_NO_ERROR)
	return 0;
    TEST_CALL_REPORT("ProSelect()", "ProTestRefCtrlSolidSelectGet()",
	    err, err != PRO_TK_NO_ERROR && err != PRO_TK_USER_ABORT &&
	    err != PRO_TK_PICK_ABOVE);
    err = ProSelectionModelitemGet (sel_prt[0], (ProModelitem*) &mdl);
    TEST_CALL_REPORT("ProSelectionModelitemGet()",
	"ProTestRefCtrlSolidSelectGet()",
	    err, err != PRO_TK_NO_ERROR);
	
    err = ProModelitemMdlGet ( &mdl, (ProMdl*) &solid_to_RC_set);
    TEST_CALL_REPORT("ProModelitemMdlGet()",
	"ProTestRefCtrlSolidSelectGet()",
	    err, err != PRO_TK_NO_ERROR);
   ProTKFprintf (qcr_ref, "Get ext. ref. control for selected solid.\n\n");
    err = ProTestRefCtrlSolidGet (qcr_ref, solid_to_RC_set);
    ProTKFprintf (qcr_ref, "\nEnd\n\n");

    return (0);
}

/*====================================================================*\
  Function : ProTestRefCtrlSolidAllGet()
  Purpose  : Menu buttun callback
\*====================================================================*/
int  ProTestRefCtrlSolidAllGet (ProAppData data, int dummy)
{
   ProError err;
   ProMdl *session_mdls;
   FILE * qcr_ref = *((FILE**) data);
   int arr_size = 0, i;

   ProTestFileOpen (&qcr_ref);
   *((FILE**) data) = qcr_ref;
   ProTKFprintf (qcr_ref, "Get ext. ref. controls for all models in session.\n\n");

   err = ProSessionMdlList (PRO_MDL_PART, & session_mdls, &arr_size);
   TEST_CALL_REPORT("ProSessionMdlList()", "ProTestRefCtrlSolidAllGet()",
				  err, err != PRO_TK_NO_ERROR);

   for (i = 0; i<arr_size; i++)
    {
	 err = ProTestRefCtrlSolidGet (qcr_ref, (ProSolid)session_mdls[i]);
    }
    err = ProArrayFree ((ProArray*)& session_mdls);
    TEST_CALL_REPORT("ProArrayFree()", "ProTestRefCtrlSolidAllGet()",
				  err, err != PRO_TK_NO_ERROR);

    
   err = ProSessionMdlList (PRO_MDL_ASSEMBLY, & session_mdls, &arr_size);
   TEST_CALL_REPORT("ProSessionMdlList()", "ProTestRefCtrlSolidAllGet()",
				  err, err != PRO_TK_NO_ERROR);

   for (i = 0; i<arr_size; i++)
    {
	 err = ProTestRefCtrlSolidGet (qcr_ref, (ProSolid)session_mdls[i]);
    }
   /*
---------------------------------
    err = ProArrayFree ((ProArray*)& session_mdls);
    TEST_CALL_REPORT("ProArrayFree()", "ProTestRefCtrlSolidAllGet()",
				  err, err != PRO_TK_NO_ERROR);
----------------------------------
				  */
   
    ProTKFprintf (qcr_ref, "\nEnd\n\n");
    return (0);
}
/*====================================================================*\
  Function : ProTestSolidInfoWrite()
  Purpose  : 
\*====================================================================*/
ProError ProTestSolidInfoWrite (
    FILE * qcr_ref,
    ProSolid solid)
{
    ProError err = PRO_TK_NO_ERROR;
    ProMdlName mdl_name;
    ProCharName cmdl_name;
    ProMdlType type;

    if (solid == NULL)
    {
	ProTKFprintf (qcr_ref,
	     "solid is NULL.\n");
	return PRO_TK_NO_ERROR;
    }
    
    err = ProMdlMdlnameGet (solid,mdl_name);
    TEST_CALL_REPORT ("ProMdlMdlnameGet()", "ProTestSolidInfoWrite()", err ,
         err != PRO_TK_NO_ERROR);
    
    ProWstringToString (cmdl_name, mdl_name);
    err = ProMdlTypeGet (solid, &type);
    TEST_CALL_REPORT ("ProMdlTypeGet()", "ProTestSolidInfoWrite()", err ,
         err != PRO_TK_NO_ERROR);
    ProTKFprintf (qcr_ref,
	"Model : %s\n",
	cmdl_name);
   ProTKFprintf (qcr_ref,
	"Model type : %d\n",
	type);
    return err;
}
    
/*====================================================================*\
  Function : ProTestRefCtrlCheckScope()
  Purpose  : Menu buttun callback
\*====================================================================*/
int  ProTestRefCtrlCheckScope (ProAppData data, int dummy)
{
    ProError err;
    int n_sel;
    ProSelection *sel_p;
    ProMdl mdl = NULL;
    ProModelitem mitem;
    ProSolid solid, ref_solid;
    ProAsmcomppath own_comp, ref_comp;
    FILE * qcr_ref = *((FILE**) data);
    ProCharLine str;

    ProTestFileOpen (&qcr_ref);
    *((FILE**) data) = qcr_ref;

    ProUtilMsgPrint( "gen", "Test %0s", "Select a solid being modified");

    n_sel = 0;
    err = ProSelect((char *)"prt_or_asm", 1, NULL, NULL, NULL, NULL, &sel_p, &n_sel);
    TEST_CALL_REPORT("ProSelect()", "ProTestRefCtrlCheckScope()",
	    err, err != PRO_TK_NO_ERROR && err != PRO_TK_USER_ABORT &&
	    err != PRO_TK_PICK_ABOVE);
    if (err != PRO_TK_NO_ERROR && n_sel<1)
	return (0);

    err = ProSelectionAsmcomppathGet(sel_p[0], &own_comp);
    TEST_CALL_REPORT("ProSelectionAsmcomppathGet()",
	"ProTestRefCtrlCheckScope()",
	err, err != PRO_TK_NO_ERROR);
    
    err = ProSelectionModelitemGet (sel_p[0], (ProModelitem*) &mitem);
    TEST_CALL_REPORT("ProSelectionModelitemGet()",
	"ProTestRefCtrlSolidSelectSet()",
	    err, err != PRO_TK_NO_ERROR);
    err = ProModelitemMdlGet ( &mitem,  (ProMdl*)&solid);
    TEST_CALL_REPORT("ProModelitemMdlGet()",
	"ProTestRefCtrlCheckScope()",
	    err, err != PRO_TK_NO_ERROR);
    
/*------------------second solid ---------------*/    
     ProUtilMsgPrint( "gen", "Test %0s", "Select a solid being referenced");

    n_sel = 0;
    err = ProSelect((char *)"prt_or_asm", 1, NULL, NULL, NULL, NULL, &sel_p, &n_sel);
    TEST_CALL_REPORT("ProSelect()", "ProTestRefCtrlCheckScope()",
	    err, err != PRO_TK_NO_ERROR && err != PRO_TK_USER_ABORT &&
	    err != PRO_TK_PICK_ABOVE);
    if (err != PRO_TK_NO_ERROR && n_sel<1)
	return (0);

    err = ProSelectionAsmcomppathGet(sel_p[0], &ref_comp);
    TEST_CALL_REPORT("ProSelectionAsmcomppathGet()",
	"ProTestRefCtrlCheckScope()",
	err, err != PRO_TK_NO_ERROR);

    err = ProSelectionModelitemGet (sel_p[0], (ProModelitem*) &mitem);
    TEST_CALL_REPORT("ProSelectionModelitemGet()",
	"ProTestRefCtrlCheckScope()",
	    err, err != PRO_TK_NO_ERROR);
    err = ProModelitemMdlGet ( &mitem,  (ProMdl*)&ref_solid);
    TEST_CALL_REPORT("ProModelitemMdlGet()",
	"ProTestRefCtrlCheckScope()",
	    err, err != PRO_TK_NO_ERROR);
/*
    err = ProRefCtrlCheckScope (solid, &own_comp, ref_solid,
	&ref_comp, &mdl);
    TEST_CALL_REPORT("ProRefCtrlCheckScope()",
	"ProTestRefCtrlCheckScope()",
	    err, err != PRO_TK_NO_ERROR);
*/
    ProTKFprintf (qcr_ref, "Solid being modified :\n" );
    ProTestSolidInfoWrite (qcr_ref, solid);
    ProTKFprintf (qcr_ref, "Solid being referenced :\n" );
    ProTestSolidInfoWrite (qcr_ref, ref_solid);
    if (err ==PRO_TK_NO_ERROR)
    {
	ProTKSprintf (str,
	"No scope violation is found\n");
        ProTKFprintf (qcr_ref,"%s", str);
        ProUtilMsgPrint( "gen", "TEST %0s", str);
	return (0);
    }

    if (err == PRO_TK_E_FOUND)
    {
	ProTKSprintf (str,
	"Scope violation is found\n");
        ProTKFprintf (qcr_ref,"%s", str);
        ProUtilMsgPrint( "gen", "TEST %0s", str);
	if (mdl == NULL)
	{
	   ProTKSprintf (str,
	   "Enviroment scope setting is  violated\n");
            ProTKFprintf (qcr_ref,"%s", str);
            ProUtilMsgPrint( "gen", "TEST %0s", str);
	}
	else
	{
	    ProTKSprintf (str,
	   "Model scope setting is  violated\n");
            ProTKFprintf (qcr_ref,"%s", str);
            ProUtilMsgPrint( "gen", "TEST %0s", str);
	    ProTestSolidInfoWrite (qcr_ref, (ProSolid)mdl);
	}
	
    }
    return (0);
}