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

#ifndef lint
static char TestMfgOper_h [] = "@(#)TestMfgOper.c	1.4 11/26/96";
#endif

/*--------------------------------------------------------------------*\
System includes
\*--------------------------------------------------------------------*/
#include <math.h>

/*--------------------------------------------------------------------*\
Pro/Toolkit  includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProModelitem.h>
#include <ProSelection.h>
#include <ProMdl.h>
#include <ProElement.h>
#include <ProElemId.h>
#include <ProElempath.h>
#include <ProFeature.h>
#include <ProFeatType.h>
#include <ProSolid.h>
#include <ProCsys.h>

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestConsts.h"
#include "TestError.h"
#include "MfgMenu.h"
#include "TestMfgNew.h"
#include "UtilTree.h"
#include "UtilMessage.h"
#include "UtilString.h"
#include "UtilGeom.h"
#include <ProTKRunTime.h>
#include <ProUtil.h>

/*--------------------------------------------------------------------*\
Local functions
\*--------------------------------------------------------------------*/

ProError ProTestOperationCreate(MfgMenuChoice*);

/*====================================================================*\
FUNCTION : ProTestOperationCreate
PURPOSE  : ProTestOperationCreate
\*====================================================================*/
ProError ProTestOperationCreate(MfgMenuChoice *obj_action)
{
    ProMfg       mfg_model = NULL;
    ProSolid     mfg_solid = NULL;
    ProFeature   op_feature;
    ProAsmcomppath  comp_path;
    ProError     status = PRO_TK_NO_ERROR;
    ProSelection *sel;
    int sel_num, wcell_id = -1;
    ProModelitem sel_obj;
    wchar_t      wname[PRO_LINE_SIZE];
    wchar_t      oper_wname[PRO_LINE_SIZE];
    Operation    oper;
    ProError ProTestWkcellId(ProAppData p_wcell,
                                     ProAppData app_data, int ts);

        /* Choose Wcell name. */
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Enter MFG Operation name: ");
    if(!ProUtilStringGet(oper_wname, NULL, PRO_LINE_SIZE))
        return(PRO_TK_BAD_INPUTS);

	oper.wname = oper_wname;

       /* Select Operation CSYS */
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select Operation CSYS.");

    status = ProSelect((char*)"csys", 1, NULL, NULL, NULL, NULL, &sel, &sel_num);
    TEST_CALL_REPORT("ProSelect()", "ProTestOperationCreate()",
                      status, status == PRO_TK_COMM_ERROR);

    if( status != PRO_TK_NO_ERROR || sel_num <= 0 )
        return((ProError)-1);

    ProSelectionHighlight(sel[0], PRO_COLOR_ERROR);
    status = ProSelectionModelitemGet(sel[0], &sel_obj);
    TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestOperationCreate()",
                      status, status != PRO_TK_NO_ERROR);
    oper.csys_id = sel_obj.id;


       /* Get Operation Workcell */
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Enter Workcell name that Operation belongs to: ");
    if(!ProUtilStringGet(wname, NULL, PRO_LINE_SIZE))
        return(PRO_TK_BAD_INPUTS);

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

    status = ProUtilMfgobjAction(obj_action, MFGOBJ_WKCELL, 1,
                                             ProTestWkcellId, &wcell_id, 0 );
    oper.wcell_id = wcell_id;

    ProTKFprintf(stderr, (char*)"In ProTestOperationCreate()\n");
    ProTKFprintf(stderr, (char*)"Workcell id  = %d\n", wcell_id);
    
    if(wcell_id == -1)
        return((ProError)-1);

    status = ProTempOperationCreate(oper, &op_feature);

    return ((ProError)1);
}

/*====================================================================*\
FUNCTION : ProTestCreateOper
PURPOSE  : Create an operation op_name using specified wcell
\*====================================================================*/
ProError ProTempOperationCreate(
    Operation oper, 
    ProFeature *p_op_feature)
{
    ProElement     oper_elem_tree = (ProElement)NULL; /* Entire tree        */
    ProElement     oper_elem      = (ProElement)NULL; /* Individual element */
    ProSelection   selection;
    ProValueData   value_data;
    ProValue       value = (ProValue)NULL;
    ProErrorlist   errors;
    ProError       status = PRO_TK_NO_ERROR;
    int            i = 0;
    ProFeatureCreateOptions *opts = 0;
	ProReference   ref1;

/*--------------------------------------------------------------------*\
    Set up the top level element values and sizes
\*--------------------------------------------------------------------*/
    static ElemTable  oper_elem_table[] =  {
		{ PRO_E_FEATURE_TYPE,     PRO_VALUE_TYPE_INT },
		{ PRO_E_STD_FEATURE_NAME, PRO_VALUE_TYPE_WSTRING },
		{ PRO_E_OPER_CSYS,        PRO_VALUE_TYPE_SELECTION },
        { PRO_E_MFG_WCELL_REF,    PRO_VALUE_TYPE_SELECTION}
		};	
    int            wc_elem_type_size = sizeof(oper_elem_table)/
                                sizeof(ElemTable);

/*--------------------------------------------------------------------*\
    Allocate space for operation element tree
\*--------------------------------------------------------------------*/
    if (status == PRO_TK_NO_ERROR)
    {
	status = ProElementAlloc ( PRO_E_FEATURE_TREE, &oper_elem_tree );
	TEST_CALL_REPORT("ProElementAlloc()", "ProTestCreateOper()",
					status, (status != PRO_TK_NO_ERROR));
    }

/*--------------------------------------------------------------------*\
    Set all of the top level elements
\*--------------------------------------------------------------------*/
    for (i =0; i < wc_elem_type_size; i++)
    {
	if (status == PRO_TK_NO_ERROR)
	{
	    status = ProElementAlloc(oper_elem_table[i].elem_type,
	    							&oper_elem);
	    TEST_CALL_REPORT("ProElementAlloc()", "ProTestCreateOper()",
				    status, (status != PRO_TK_NO_ERROR));
	}

        switch (oper_elem_table[i].elem_type)
	{
	    case PRO_E_FEATURE_TYPE:
		 status = ProElementIntegerSet ( oper_elem, PRO_FEAT_OPERATION);
         TEST_CALL_REPORT("ProElementIntegerSet()", "ProTestCreateOper()",
				    status, (status != PRO_TK_NO_ERROR));
		break;

	    case PRO_E_MFG_WCELL_REF:
			ProTestCreateSelection(oper.wcell_id, PRO_FEATURE, &selection);

			status = ProSelectionToReference(selection, &ref1);
			TEST_CALL_REPORT("ProSelectionToReference()", "ProTestCreateOper()",
				status, (status != PRO_TK_NO_ERROR));

			status = ProElementReferenceSet(oper_elem, ref1);
			TEST_CALL_REPORT("ProElementReferenceSet()", "ProTestCreateOper()",
				status, (status != PRO_TK_NO_ERROR));
		break;

	    case PRO_E_OPER_CSYS:
		ProTestCreateSelection(oper.csys_id, PRO_CSYS, &selection);
		
		status = ProSelectionToReference(selection, &ref1 );
		TEST_CALL_REPORT("ProSelectionToReference()", "ProTestCreateOper()",
				    status, (status != PRO_TK_NO_ERROR));
		
        status = ProElementReferenceSet(oper_elem, ref1);
        TEST_CALL_REPORT("ProElementReferenceSet()", "ProTestCreateOper()",
				    status, (status != PRO_TK_NO_ERROR));
		break;

	    case PRO_E_STD_FEATURE_NAME:
		status=ProElementWstringSet(oper_elem, oper.wname);
		TEST_CALL_REPORT("ProElementWstringSet()", "ProTestCreateOper()",
				    status, (status != PRO_TK_NO_ERROR));
		break;

	    default:
	        ProTKFprintf(stderr, (char*)"Error finding element type\n");
		return PRO_TK_GENERAL_ERROR;
	}


	if ( status == PRO_TK_NO_ERROR )
	{
	    status = ProElemtreeElementAdd (oper_elem_tree, NULL, oper_elem );
	    TEST_CALL_REPORT("ProElemtreeElementAdd()","ProTestCreateOper()",
				status, (status != PRO_TK_NO_ERROR));
	}
    
    }

    status = ProUtilElementtreePrint(oper_elem_tree, PRO_TEST_INFO_WINDOW,NULL);

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

	opts[0]= PRO_FEAT_CR_NO_OPTS;

	status = ProFeatureWithoptionsCreate( selection, oper_elem_tree,
		opts, PRO_REGEN_NO_FLAGS, p_op_feature, &errors);
	TEST_CALL_REPORT("ProFeatureWithoptionsCreate()", "ProTestCreateOper()",
				    status, (status != PRO_TK_NO_ERROR));

	status = ProArrayFree((ProArray*)&opts);
    }
    
    status = ProElementFree(&oper_elem_tree);
    TEST_CALL_REPORT("ProElementFree()", "ProTestCreateOper()",
			    status, (status != PRO_TK_NO_ERROR));

    return(status);   
}


/*====================================================================*\
FUNCTION : ProTestOperationDisplay
PURPOSE  : Top level function to display a tool path of an operation
\*====================================================================*/
ProError ProTestOperationDisplay(
    MfgMenuChoice *obj_action)
{
    ProError status;
    double   dval = 0;
    int      ival = 0;
    ProMfg mfg_model;
    ProSolid mfg_solid;
    ProAsmcomppath comp_path;
    ProMfgoper oper;
    char oper_name[PRO_NAME_SIZE] = "";
    ProName name;
    
    status = ProTestGetModels (&mfg_model, &mfg_solid, &comp_path);
             
    status = ProMfgoperActiveGet (mfg_solid, &oper);
    TEST_CALL_REPORT("ProMfgoperActiveGet()", 
        "ProTestOperationDisplay", status, (status != PRO_TK_NO_ERROR)&&
        (status != PRO_TK_E_NOT_FOUND));             

    if( status == PRO_TK_NO_ERROR )
    {
	status = ProModelitemNameGet (&oper, name);
	TEST_CALL_REPORT("ProModelitemNameGet()", "ProTestOperationDisplay()",
	    status, (status != PRO_TK_NO_ERROR));
    
	ProWstringToString(oper_name, (wchar_t*)&name);       
    }

    ProTKPrintf((char*)"\n Current operation : %s \n", oper_name);

    status = ProUtilMfgobjAction (obj_action, MFGOBJ_OPER, 1,
            ProTestOperToolPathDisp, &dval, ival);

    return status;
}


/*====================================================================*\
FUNCTION : ProTestOperToolPathDisp
PURPOSE  : Display a tool path of a given operation
\*====================================================================*/
ProError ProTestOperToolPathDisp(
    ProAppData p_oper,
    ProAppData app_data,
    int dummy)
{
    ProError status;
    
    status = ProMfgoperToolpathDisplay((ProMfgoper *) p_oper);
    TEST_CALL_REPORT("ProMfgoperToolpathDisplay()", 
             "ProTestOperToolPathDisp", status, status != PRO_TK_NO_ERROR);
  
    return status;
}