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


/*--------------------------------------------------------------------*\
Pro/Toolkit includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProFeature.h>
#include <ProAsmcomp.h>
#include <ProModelitem.h>
#include <ProSolid.h>
#include <ProMfg.h>
#include <ProMenu.h>
#include <ProUtil.h>

#include <ctype.h>

#include <TestMfgNew.h>
#include <UtilMfgNew.h>
#include <MfgMenu.h>
#include <TestError.h>
#include <UtilTree.h>
#include <UtilMenu.h>
#include <UtilString.h>
#include <UtilMessage.h>
#include <ProTKRunTime.h>

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

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

/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/
#define TK_FIXT_CREATE     1 << 15
#define TK_FIXT_MODIFY     1 << 16
#define TK_FIXT_DELETE     1 << 17
#define TK_FIXT_ACTIVATE   1 << 18


ProError test_func(ProAppData, ProAppData, int);

/*====================================================================*\
FUNCTION : ProTestFixtureCreate
PURPOSE  : Create Fixture feature
\*====================================================================*/
ProError ProTestFixtureCreate(MfgMenuChoice *obj_action)
{
    ProElement     fixt_elem_tree = (ProElement)NULL; /* Entire tree   */
    ProElement     fixt_elem      = (ProElement)NULL; /* One element   */
    ProError       status = PRO_TK_NO_ERROR;
    int            feat_type = PRO_FEAT_FIXSETUP;

    static char*   menu[] = {"TkFixtSet","TkMfgDQ",""};
    int            menu_id, n_menus;
    

/*--------------------------------------------------------------------*\
    Allocate space for workcell element tree
\*--------------------------------------------------------------------*/
    if (status == PRO_TK_NO_ERROR)
    {
	status = ProElementAlloc ( PRO_E_FEATURE_TREE, &fixt_elem_tree );
	TEST_CALL_REPORT("ProElementAlloc()", "ProTestFixtureCreate()",
				status, (status != PRO_TK_NO_ERROR));
/*--------------------------------------------------------------------*\
	Set feature type
\*--------------------------------------------------------------------*/
	if (status == PRO_TK_NO_ERROR)
	{
	    status = ProElementAlloc ( PRO_E_FEATURE_TYPE, 
	    			       &fixt_elem );
	    TEST_CALL_REPORT("ProElementAlloc()", "ProTestFixtureCreate()",
					status, (status != PRO_TK_NO_ERROR));
	    
	    if (status == PRO_TK_NO_ERROR)
		status = ProUtilElementBuild ( PRO_VALUE_TYPE_INT, &feat_type, 
	    						 	&fixt_elem); 
	    
	    if (status == PRO_TK_NO_ERROR)
		status = ProElemtreeElementAdd(fixt_elem_tree, NULL, fixt_elem);
	    TEST_CALL_REPORT("ProElemtreeElementAdd()","ProTestFixtureCreate()",
					status, (status != PRO_TK_NO_ERROR));

	}
    }


/*--------------------------------------------------------------------*\
    Create the setup menu
\*--------------------------------------------------------------------*/
    ProMenuFileRegister((char*)"TkFixtSet",(char*)"tkfixtset.mnu",&menu_id);
    ProMenubuttonActionSet((char*)"TkFixtSet",(char*)"TkFixtSet", 
				(ProMenubuttonAction)ProUtilMenuKill, NULL,2);
    ProMenubuttonActionSet((char*)"TkFixtSet",(char*)"-Name", (ProMenubuttonAction)ProTestFixtAction, 
					(ProAppData)&fixt_elem_tree,PRO_E_FEAT_NAME );
    ProMenubuttonActionSet((char*)"TkFixtSet",(char*)"-Component", (ProMenubuttonAction)ProTestFixtAction,
					(ProAppData)&fixt_elem_tree, PRO_E_COMPONENTS );
    ProMenubuttonActionSet((char*)"TkFixtSet",(char*)"-Setup time", (ProMenubuttonAction)ProTestFixtAction,
					(ProAppData)&fixt_elem_tree, PRO_E_SETUP_TIME );

    ProMenuFileRegister((char*)"TkMfgDQ",(char*)"tkmfgdq.mnu", &menu_id );
    ProMenubuttonActionSet((char*)"TkMfgDQ",(char*)"TkMfgDQ",
				 (ProMenubuttonAction) ProMenuDelete, NULL, 0);
    ProMenubuttonActionSet((char*)"TkMfgDQ",(char*)"Done", (ProMenubuttonAction)ProTestFixtCreate,
						   (ProAppData) &fixt_elem_tree, 0 );
    ProMenubuttonActionSet((char*)"TkMfgDQ",(char*)"Quit",(ProMenubuttonAction) ProUtilMenuKill,
						    NULL, 2 );

    ProCompoundmenuCreate(menu, &n_menus);
    
    return ((ProError)1);
}


/*====================================================================*\
FUNCTION :  ProTestFixtCreate
PURPOSE  :  Create the fixture from the element tree
\*====================================================================*/
int ProTestFixtCreate (
    ProAppData element_tree,
    int dummy )
{
    ProSelection   selection;
    ProFeature     fixture;
    ProErrorlist   errors;
    ProMfg         mfg_model;
    ProSolid       mfg_solid;
    ProAssembly    mfg_asm;
    ProAsmcomppath comp_path;
    ProModelitem   model_item;
    ProError       status;
    int            id;
    ProFeatureCreateOptions *opts = 0;

    if ( element_tree == NULL)
	return PRO_TK_BAD_INPUTS;

    (void) ProUtilElementtreePrint(*((ProElement*)element_tree), 
    			PRO_TEST_INFO_WINDOW, NULL);

    status = ProTestGetModels( &mfg_model, &mfg_solid, &comp_path);

    if (status == PRO_TK_NO_ERROR)
    {
	status = ProMfgAssemGet( mfg_model, &mfg_asm );
	TEST_CALL_REPORT("ProMfgAssemGet()", "ProTestFixtCreate()", 
				status, (status != PRO_TK_NO_ERROR));

    }

    if (status == PRO_TK_NO_ERROR)
    {
	status = ProMdlIdGet((ProMdl) mfg_asm, &id );
	TEST_CALL_REPORT("ProMfgAssemGet()", "ProTestFixtCreate()", 
				status, (status != PRO_TK_NO_ERROR));
    }

    if (status == PRO_TK_NO_ERROR)
    {
	status = ProModelitemInit( mfg_asm, id, PRO_ASSEMBLY, &model_item );
	TEST_CALL_REPORT("ProModelitemInit()","ProTestFixtCreate()",
				status, (status != PRO_TK_NO_ERROR));
    }

    if ( status == PRO_TK_NO_ERROR)
    {
	status = ProSelectionAlloc(NULL, &model_item, &selection);
	TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestFixtCreate()",
				status, (status != PRO_TK_NO_ERROR));
    }

    if (status == PRO_TK_NO_ERROR)
    {
	status = ProArrayAlloc(1,sizeof(ProFeatureCreateOptions),
		1, (ProArray*)&opts);

	opts[0]= PRO_FEAT_CR_NO_OPTS;

	status = ProFeatureWithoptionsCreate( selection, *((ProElement*)element_tree),
		opts, PRO_REGEN_NO_FLAGS, &fixture, &errors);
	TEST_CALL_REPORT("ProFeatureWithoptionsCreate()", "ProTestFixtCreate()",
				status, (status != PRO_TK_NO_ERROR));

	status = ProArrayFree((ProArray*)&opts);
    }
 
    /*
    status = ProElementFree(*((ProElement*)element_tree);
    TEST_CALL_REPORT("ProElementFree()", "ProTestCreateWkcell()",
			    status, (status != PRO_TK_NO_ERROR));

    */
    ProMenuDelete();
    return(status);
}

/*====================================================================*\
FUNCTION : ProTestFixtAction
PURPOSE  : Prompt user for a specified element and add it to tree.
\*====================================================================*/
int ProTestFixtAction ( ProAppData element, int element_id )
{
    wchar_t    wstr[PRO_LINE_SIZE];
    char       str[PRO_LINE_SIZE];
    void      *entry;
    ProError   status = PRO_TK_NO_ERROR;
    ProElement elem = (ProElement)NULL;
    int        value_type, comp_id, c_range[2] = {0,9999};
    double     d_val, d_range[2] = {0.0, 9999.9};
    
    status = ProElementAlloc( element_id, &elem );

    if (status == PRO_TK_NO_ERROR) 
    {
	switch ( element_id )
	{
	    case PRO_E_FEAT_NAME:
	        ProTKSprintf(str,(char*)"Enter fixture name : ");
		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", str);
		if (!ProUtilStringGet(wstr, NULL, PRO_LINE_SIZE))
		{
		    status = PRO_TK_USER_ABORT;
		}
		else
		{
		    value_type = PRO_VALUE_TYPE_WSTRING;
		    entry = wstr;
		}
		break;
	    case PRO_E_COMPONENTS:
	        ProTKSprintf(str,(char*)"Enter fixture component id : ");
		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", str);
		if (!ProUtilIntGet(c_range, NULL, &comp_id))
		{
		    status = PRO_TK_USER_ABORT;
		}
		else 
		{
		    value_type = PRO_VALUE_TYPE_INT;
                    entry = &comp_id;
		}
		break;
	    case PRO_E_SETUP_TIME:
	        ProTKSprintf(str,(char*)"Enter fixture setup time : ");
		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", str);
                if (!ProUtilDoubleGet(d_range, NULL, &d_val)) 
		{
                    status = PRO_TK_USER_ABORT;
		}
		else
		{
		    value_type = PRO_VALUE_TYPE_DOUBLE;
		    entry = &d_val;
		}
		break;
	    default:
		status = PRO_TK_BAD_INPUTS;
	}

	if (status == PRO_TK_NO_ERROR)
	{
	    status = ProUtilElementBuild((ProValueDataType)value_type, entry, &elem);

	    if (status == PRO_TK_NO_ERROR)
	    {
		status = ProElemtreeElementAdd(*(ProElement*)element, NULL,
						elem);
		TEST_CALL_REPORT("ProElemtreeElementAdd()",
				 "ProTestFixtAction()",
				 status, (status != PRO_TK_NO_ERROR));
	    }
	}
    }
   
    return ((int)status);
}

ProError test_func(ProAppData p_fixt, ProAppData app_data, int ts)
{
    ProTKFprintf(stderr, (char*)"In test_func()\n");
    ProTKFprintf(stderr, (char*)"Fixture id  = %d\n", ((ProFixture*)p_fixt)->id );
    ProTKFprintf(stderr, (char*)"Test double = %f\n", *((double*)app_data));
    ProTKFprintf(stderr, (char*)"Test int    = %d\n", ts );

    return PRO_TK_NO_ERROR;
}


/*====================================================================*\
FUNCTION : ProTestFixtList
PURPOSE  : 
\*====================================================================*/
int ProTestFixtList( MfgMenuChoice *obj_action )
{
    ProError status;
    double   dval = 678.323;
    int      ival = 123;
    status = ProUtilMfgobjAction ( obj_action, MFGOBJ_FIXTURE,
        obj_action->mfgobj_list->n_fixture, test_func, &dval, ival );


    return 0;
}


/*====================================================================*\
FUNCTION : ProTestFixtureDisp
PURPOSE  :
\*====================================================================*/
ProError ProTestFixtureDisp(
    MfgMenuChoice *obj_action)
{
    int menu_id, action;

/*--------------------------------------------------------------------*\
    Create the fixture menu
\*--------------------------------------------------------------------*/
    ProMenuFileRegister((char*)"TkFixt", (char*)"tkfixt.mnu", &menu_id);
    ProMenubuttonActionSet((char*)"TkFixt", (char*)"Activate", 
                     (ProMenubuttonAction)ProTestFixtureActivate,
                                               (ProAppData)obj_action, 0);
    ProMenubuttonActionSet((char*)"TkFixt", (char*)"Deactivate All", 
                         (ProMenubuttonAction)ProTestFixtDeactivate, NULL, 0);
    ProMenubuttonActionSet((char*)"TkFixt", (char*)"Done",
                            (ProMenubuttonAction)ProMenuDelete, NULL, 0);
    ProMenubuttonActionSet((char*)"TkFixt", (char*)"TkFixt",
                            (ProMenubuttonAction)ProMenuDelete, NULL, 0);

    ProMenuCreate (PROMENUTYPE_MAIN, (char*)"TkFixt", &menu_id);
    ProMenuProcess ((char*)"", &action);

    return PRO_TK_NO_ERROR;
}

/*====================================================================*\
FUNCTION : ProTestFixtDeactivate
PURPOSE  : Deactivate all fixtures
\*====================================================================*/
ProError ProTestFixtDeactivate()
{
    ProError       status = PRO_TK_NO_ERROR;
    ProMfg         mfg_model;
    ProSolid       mfg_solid;
    ProAsmcomppath comp_path;

    status = ProTestGetModels ( &mfg_model, &mfg_solid, &comp_path );

    status = ProMfgFixtActivate ( mfg_model, NULL);
    TEST_CALL_REPORT("ProMfgFixtActivate()", "ProTestFixtDeactivate",
                                    status, status != PRO_TK_NO_ERROR ); 
 
    return status;
}

/*====================================================================*\
FUNCTION : ProTestFixtureActivate
PURPOSE  : general function to activate a fixture
\*====================================================================*/
ProError ProTestFixtureActivate (
    MfgMenuChoice *obj_action)
{
    ProError status;
    double   dval = 0;
    int      ival = 0;

    status = ProUtilMfgobjAction ( obj_action, MFGOBJ_FIXTURE, 1,
                                  ProTestFixtActivate, &dval, ival );

    return status;
}


/*====================================================================*\
FUNCTION : ProTestFixtActivate
PURPOSE  : Activate selected fixture
\*====================================================================*/
ProError ProTestFixtActivate ( 
    ProAppData p_fixt,
    ProAppData app_data,
    int dummy)
    
{
    ProError       status = PRO_TK_NO_ERROR;
    ProMfg         mfg_model;
    ProSolid       mfg_solid;
    ProAsmcomppath comp_path;

    status = ProTestGetModels ( &mfg_model, &mfg_solid, &comp_path );

    status = ProMfgFixtActivate( mfg_model, (ProFixture *) p_fixt);
    TEST_CALL_REPORT("ProMfgFixtActivate", "ProTestFixtActivate",
                                    status, status != PRO_TK_NO_ERROR);
    return status;
}

/*====================================================================*\
FUNCTION : ProTestFixtureDelete
PURPOSE  : general function to delete fixtures
\*====================================================================*/
ProError ProTestFixtureDelete(
    MfgMenuChoice *obj_action )
{
    ProError status;
    double   dval = 0;
    int      ival = 0;

    status = ProUtilMfgobjAction(obj_action, MFGOBJ_FIXTURE,
         obj_action->mfgobj_list->n_fixture, ProTestFixtDelete, &dval, ival );

    return status;
}



/*====================================================================*\
FUNCTION : ProTestFixtDelete
PURPOSE  : Delete selected fixture from the mfg model
\*====================================================================*/
ProError ProTestFixtDelete (
    ProAppData p_fixt,
    ProAppData app_data,
    int dummy)
{
    ProError       status = PRO_TK_NO_ERROR;
    ProMfg         mfg_model;
    ProSolid       mfg_solid;
    ProAsmcomppath comp_path;
    ProFeatureDeleteOptions *delete_opts = 0;
    int *feat_ids = NULL;

    status = ProTestGetModels ( &mfg_model, &mfg_solid, &comp_path );

    status = ProArrayAlloc(1,sizeof(ProFeatureDeleteOptions),
        1, (ProArray*)&delete_opts);

    delete_opts[0] = PRO_FEAT_DELETE_NO_OPTS;

    status = ProArrayAlloc(1,sizeof(int),
        1, (ProArray*)&feat_ids);

    feat_ids[0] = ((ProFixture *)p_fixt)->id;

    status = ProFeatureWithoptionsDelete ( mfg_solid, feat_ids, delete_opts,
      PRO_REGEN_NO_FLAGS);
    TEST_CALL_REPORT("ProFeatureWithoptionsDelete()", "ProTestFixturesDelete()",
				  status, status != PRO_TK_NO_ERROR );

    status = ProArrayFree((ProArray*)&delete_opts);
    status = ProArrayFree((ProArray*)&feat_ids);

    return status;
}