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


/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProArray.h>
#include <ProSurfacedata.h>
#include <ProEdgedata.h>
#include <ProQuiltdata.h>
#include <ProDatumdata.h>
#include <ProUtil.h>

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "UtilString.h"
#include <UtilMessage.h>
#include <ProTKRunTime.h>

ProError ProUtilCurvedataCopy(ProCurvedata *c_in, ProCurvedata *c_out);
void ProTestEdgeCreationTypeGet (int *creation_type);

ProError ProUtilArrayCopy(
    ProArray array_from, 
    ProArray *array_to,
    int obj_size)
{
    ProError err;
    int n;

    err = ProArraySizeGet(array_from, &n);
    TEST_CALL_REPORT("ProArraySizeGet()", "ProUtilArrayCopy()",
						err, err != PRO_TK_NO_ERROR);
    if (err == PRO_TK_NO_ERROR)
    {
	err = ProArrayAlloc(n, obj_size, 1, array_to);
	TEST_CALL_REPORT("ProArrayAlloc()", "ProUtilArrayCopy()",
						err, err != PRO_TK_NO_ERROR);
	if (err == PRO_TK_NO_ERROR)
	    memcpy(*array_to, array_from, obj_size*n);

    }

    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
    FUNCTION :  ProUtilSurfaceshapedataCopy()
    PURPOSE  :  copy one ProSurfaceshapedata struct to another  
\*====================================================================*/
ProError ProUtilSurfaceshapedataCopy(
    ProSrftype s_type,
    ProSurfaceshapedata *s_in,    /* In : input struct*/
    ProSurfaceshapedata *s_out)   /* Out : output struct */
{
   ProVector e1, e2, e3, *p_u_t_arr, *p_v_t_arr, *p_uvd_arr;
   ProVector *p_new_u_t_arr, *p_new_v_t_arr, *p_new_uvd_arr;
   Pro3dPnt origin, *p_arr, *p_new_arr;
   double rad1, rad2, alpha, *p_u_arr, *p_v_arr, *p_wg_arr;
   double *p_new_u_arr, *p_new_v_arr, *p_new_wg_arr;
   ProCurvedata cur1, cur2, new_cur1, new_cur2;
   int num_u, num_v, num_c_p, deg[2];
   ProSplinedata pnt_spline, ctr_spline, tan_spline;
   ProSplinesrfdata  splsrf;
   ProError err = PRO_TK_NO_ERROR;
   ProSurfaceshapedata shape_data;
   ProCurvedata new_pnt_spline, new_ctr_spline, new_tan_spline;

    switch (s_type)
    {
    case  PRO_SRF_PLANE:
        err = ProPlanedataGet( s_in, e1, e2, e3, origin);
        TEST_CALL_REPORT("ProPlanedataGet()", "ProUtilSurfaceshapedataCopy()",
						err, err != PRO_TK_NO_ERROR);
	err = ProPlanedataInit( e1, e2, e3, origin, s_out);
        TEST_CALL_REPORT("ProPlanedataInit()", "ProUtilSurfaceshapedataCopy()",
						err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_CYL:
        err = ProCylinderdataGet( s_in, e1, e2, e3, origin, &rad1);
        TEST_CALL_REPORT("ProCylinderdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProCylinderdataInit( e1, e2, e3, origin, rad1, s_out);
        TEST_CALL_REPORT("ProCylinderdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_CONE:
        err = ProConedataGet( s_in, e1, e2, e3, origin, &alpha);
        TEST_CALL_REPORT("ProConedataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProConedataInit( e1, e2, e3, origin, alpha, s_out);
        TEST_CALL_REPORT("ProConedataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_TORUS:
        err = ProTorusdataGet( s_in, e1, e2, e3, origin, &rad1, &rad2);
        TEST_CALL_REPORT("ProTorusdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProTorusdataInit( e1, e2, e3, origin, rad1, rad2, s_out);
        TEST_CALL_REPORT("ProTorusdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_SPL:
        err = ProSplinesrfdataGet( s_in, &p_u_arr, &p_v_arr, &p_arr,
	    &p_u_t_arr, &p_v_t_arr, &p_uvd_arr, &num_u, &num_v);
        TEST_CALL_REPORT("ProSplinesrfdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilArrayCopy ((ProArray)p_u_arr, (ProArray*)&p_new_u_arr,
				sizeof (double));
	err = ProUtilArrayCopy ((ProArray)p_v_arr, (ProArray*)&p_new_v_arr,
				sizeof (double));
	err = ProUtilArrayCopy ((ProArray)p_arr, (ProArray*)&p_new_arr,
				sizeof (Pro3dPnt));
	err = ProUtilArrayCopy ((ProArray)p_u_t_arr, (ProArray*)&p_new_u_t_arr,
				sizeof (Pro3dPnt));
	err = ProUtilArrayCopy ((ProArray)p_v_t_arr, (ProArray*)&p_new_v_t_arr,
				sizeof (Pro3dPnt));
	err = ProUtilArrayCopy ((ProArray)p_uvd_arr, (ProArray*)&p_new_uvd_arr,
				sizeof (Pro3dPnt));
	
	err = ProSplinesrfdataInit( p_new_u_arr, p_new_v_arr,
	    p_new_arr, p_new_u_t_arr, 
	    p_new_v_t_arr, p_new_uvd_arr, num_u, num_v, s_out);
        TEST_CALL_REPORT("ProSplinesrfdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_FIL:
        err = ProFilsrfdataGet( s_in, &pnt_spline, &ctr_spline, &tan_spline);
        TEST_CALL_REPORT("ProFilsrfdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilCurvedataCopy ((ProCurvedata*)&pnt_spline,
				    &new_pnt_spline);
	err = ProUtilCurvedataCopy ((ProCurvedata*)&ctr_spline,
				    &new_ctr_spline);
	err = ProUtilCurvedataCopy ((ProCurvedata*)&tan_spline,
				    &new_tan_spline);
	err = ProFilsrfdataInit( (ProSplinedata*)&new_pnt_spline,
            (ProSplinedata*)&new_ctr_spline,
 	    (ProSplinedata*) &new_tan_spline, s_out);
        TEST_CALL_REPORT("ProFilsrfdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_RUL:
        err = ProRulsrfdataGet( s_in, e1, e2, e3, origin, &cur1, &cur2);
        TEST_CALL_REPORT("ProRulsrfdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilCurvedataCopy (&cur1, &new_cur1);
	err = ProUtilCurvedataCopy (&cur2, &new_cur2);
	err = ProRulsrfdataInit( e1, e2, e3, origin, &new_cur1, &new_cur2,
	    s_out);
        TEST_CALL_REPORT("ProRulsrfdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_REV:
        err = ProSrfrevdataGet( s_in, e1, e2, e3, origin, &cur1);
        TEST_CALL_REPORT("ProSrfrevdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilCurvedataCopy (&cur1, &new_cur1);
	err = ProSrfrevdataInit( e1, e2, e3, origin, &new_cur1, s_out);
        TEST_CALL_REPORT("ProSrfrevdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_TABCYL:
        err = ProTabcyldataGet( s_in, e1, e2, e3, origin, &cur1);
        TEST_CALL_REPORT("ProTabcyldataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);  
	err = ProUtilCurvedataCopy (&cur1, &new_cur1);
	
	err = ProTabcyldataInit( e1, e2, e3, origin, &new_cur1, s_out);
        TEST_CALL_REPORT("ProTabcyldataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_B_SPL:
        err = ProBsplinesrfdataGet( s_in, deg, &p_u_arr, &p_v_arr, &p_wg_arr,
 	    &p_arr, &num_u, &num_v, &num_c_p);
        TEST_CALL_REPORT("ProBsplinesrfdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilArrayCopy ((ProArray)p_u_arr, (ProArray*)&p_new_u_arr,
				sizeof (double));
	err = ProUtilArrayCopy ((ProArray)p_v_arr, (ProArray*)&p_new_v_arr,
				sizeof (double));
	err = ProUtilArrayCopy ((ProArray)p_wg_arr, (ProArray*)&p_new_wg_arr,
				sizeof (double));
	err = ProBsplinesrfdataInit( deg, p_u_arr, p_v_arr, p_wg_arr, 
	    p_arr, num_u, num_v, num_c_p, s_out);
        TEST_CALL_REPORT("ProBsplinesrfdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    case PRO_SRF_CYL_SPL:
        err = ProCylsplsrfdataGet( s_in, e1, e2, e3, origin, &splsrf);
        TEST_CALL_REPORT("ProCylsplsrfdataGet()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	
	err = ProUtilSurfaceshapedataCopy (PRO_SRF_SPL,
	    (ProSurfaceshapedata*)&splsrf, &shape_data);
	
	err = ProCylsplsrfdataInit( e1, e2, e3, origin,
	    (ProSplinesrfdata*)&shape_data, s_out);
        TEST_CALL_REPORT("ProCylsplsrfdataInit()", 
	    "ProUtilSurfaceshapedataCopy()", err, err != PRO_TK_NO_ERROR);
	break;
    default:
	ProUtilMsgPrint("gen", "TEST %0s", "Unknown surface type");
	ProTKFprintf(stderr, "Copy: Unknown surface type %d\n", s_type);	
	s_out[0] = s_in[0];
	break;
   }

   return (err);
}

/*====================================================================*\
    FUNCTION :  ProUtilContourdataCopy()
    PURPOSE  :  copy contour array using different functions
\*====================================================================*/
ProError ProUtilContourdataCopy(
    ProContourdata **p_c_array)   /* In, Out : contourdata array */
{
    ProError err = PRO_TK_GENERAL_ERROR;
    ProContourdata *p_new_array, *p_c_data;
    int i, n, *p_edge_arr, *p_new_edge_arr;
    ProContourTraversal trav;

    err = ProArrayAlloc(0, sizeof(ProContourdata), 1, (ProArray*)&p_new_array);
    TEST_CALL_REPORT("ProArrayAlloc()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProArraySizeGet((ProArray)*p_c_array, &n);
    TEST_CALL_REPORT("ProArraySizeGet()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);

    for (i=0; i<n; i++)
    {
	err = ProContourdataAlloc(&p_c_data);
    	TEST_CALL_REPORT("ProContourdataAlloc()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);

        err = ProContourdataGet(p_c_array[0]+i, &trav);
    	TEST_CALL_REPORT("ProContourdataGet()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);

	err = ProContourdataInit(trav, p_c_data);
    	TEST_CALL_REPORT("ProContourdataInit()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);

	err = ProContourdataEdgeIdArrayGet(p_c_array[0]+i, &p_edge_arr);
    	TEST_CALL_REPORT("ProContourdataEdgeIdArrayGet()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);
	
	err = ProUtilArrayCopy ((ProArray)p_edge_arr,
	    (ProArray*)&p_new_edge_arr, sizeof (int));
	
	err = ProContourdataEdgeIdArraySet(p_c_data, p_new_edge_arr);
    	TEST_CALL_REPORT("ProContourdataEdgeIdArraySet()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);
	
	err = ProArrayObjectAdd((ProArray*)&p_new_array, PRO_VALUE_UNUSED,
	    1, p_c_data);
    	TEST_CALL_REPORT("ProArrayObjectAdd()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);
	
        memset(p_c_data, '\0', sizeof(ProContourdata));

	err = ProContourdataFree(p_c_data);
	TEST_CALL_REPORT("ProContourdataFree()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);
    }
	

    err = ProArrayFree((ProArray*)p_c_array);
    TEST_CALL_REPORT("ProArrayFree()", 
		   "ProUtilContourdataCopy()", err, err != PRO_TK_NO_ERROR);
 
    *p_c_array = p_new_array;
    return (err);
}

/*====================================================================*\
    FUNCTION :  ProUtilSurfacedataCopy()
    PURPOSE  :  copy surfacedata using different functions
\*====================================================================*/
ProError ProUtilSurfacedataCopy(
    ProSurfacedata **p_s_data)   /* In, Out : surface data */
{
    ProError err;
    ProSurfacedata *surf_data;
    ProSrftype srftype;
    ProUvParam uvpar1, uvpar2;
    ProSurfaceOrient s_orient; 
    ProSurfaceshapedata s_shapedata, s_shapedata_new;
    ProContourdata *p_cont_arr;
    int s_id;

    err = ProSurfacedataAlloc( &surf_data);
    TEST_CALL_REPORT("ProSurfacedataAlloc()", 
		   "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProSurfacedataGet(*p_s_data, &srftype, uvpar1, uvpar2, &s_orient, 
	&s_shapedata, &s_id);
    TEST_CALL_REPORT("ProSurfacedataGet()", 
		   "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProUtilSurfaceshapedataCopy(srftype, &s_shapedata, &s_shapedata_new);

    err = ProSurfacedataInit(srftype, uvpar1, uvpar2, s_orient, 
	&s_shapedata_new, s_id, surf_data);
    TEST_CALL_REPORT("ProSurfacedataInit()", 
		   "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProSurfacedataContourArrayGet( *p_s_data, &p_cont_arr);
    TEST_CALL_REPORT("ProSurfacedataContourArrayGet()", 
	           "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProUtilContourdataCopy(&p_cont_arr);

    err = ProSurfacedataContourArraySet( surf_data, p_cont_arr);
    TEST_CALL_REPORT("ProSurfacedataContourArraySet()", 
	           "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProArrayFree((ProArray*)&p_cont_arr);
    TEST_CALL_REPORT("ProArrayFree()", 
	           "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProSurfacedataFree(*p_s_data);
    TEST_CALL_REPORT("ProSurfacedataFree()", 
	           "ProUtilSurfacedataCopy()", err, err != PRO_TK_NO_ERROR);
    *p_s_data = surf_data;
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
    FUNCTION :  ProUtilCurvedataCopy()
    PURPOSE  :  copy curvedata using different functions
\*====================================================================*/
ProError ProUtilComponentArrayCopy(
    ProComponentCurvedata *p_comp_arr,
    ProComponentCurvedata **new_comp_arr)
{
    ProError err;
    int n_comp, i;
    ProComponentCurvedata *p_curve_data;
    ProCurveDir dir;
    ProCurvedata curve_data, new_data;

    err = ProArraySizeGet((ProArray)p_comp_arr, &n_comp);
    TEST_CALL_REPORT("ProArraySizeGet()", 
	        "ProUtilComponentArrayCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProArrayAlloc(0, sizeof(ProComponentCurvedata), 1, 
	(ProArray*)new_comp_arr);
    for (i=0; i<n_comp; i++)
    {
	err = ProComponentCurvedataAlloc(&p_curve_data);
	TEST_CALL_REPORT("ProComponentCurvedataAlloc()", 
	    "ProUtilComponentArrayCopy()", err, err != PRO_TK_NO_ERROR);
	if (err != PRO_TK_NO_ERROR)
	    break;

	err = ProComponentCurvedataGet(&p_comp_arr[i], &curve_data, &dir);
	TEST_CALL_REPORT("ProComponentCurvedataGet()", 
	        "ProUtilComponentArrayCopy()", err, err != PRO_TK_NO_ERROR);
	if (err != PRO_TK_NO_ERROR)
	    break;

	err = ProUtilCurvedataCopy(&curve_data, &new_data);

	err = ProComponentCurvedataInit(&new_data, dir, p_curve_data);
	TEST_CALL_REPORT("ProComponentCurvedataInit()", 
	        "ProUtilComponentArrayCopy()", err, err != PRO_TK_NO_ERROR);
	if (err != PRO_TK_NO_ERROR)
	    break;
	
	err = ProArrayObjectAdd((ProArray*)new_comp_arr, PRO_VALUE_UNUSED,
	    1, p_curve_data);
	if (err != PRO_TK_NO_ERROR)
	    break;

#if 1
	memset(p_curve_data, '\0', sizeof(ProComponentCurvedata));
#endif     
         	
	err = ProComponentCurvedataFree(p_curve_data);
	TEST_CALL_REPORT("ProComponentCurvedataFree()", 
	        "ProUtilComponentArrayCopy()", err, err != PRO_TK_NO_ERROR);

	if (err != PRO_TK_NO_ERROR)
	    break;
    }
    
    return (err);
}

/*====================================================================*\
    FUNCTION :  ProUtilCurvedataCopy()
    PURPOSE  :  copy curvedata using different functions
\*====================================================================*/
ProError ProUtilCurvedataCopy(
    ProCurvedata *c_in,
    ProCurvedata *c_out)	/* In, out : edge data */
{
    int                     n_point, n_knots, degree;
    double                  *p_par_arr, *p_weight_arr, *p_par_arr2,
                            *p_weight_arr2, st_a, en_a, rad;
    double                  d1, d2, d3, d4; 
    ProError                err;
    ProEnttype              c_type;
    Pro3dPnt                p1, p2;
    ProVector               v1, v2;
    ProPoint3d              *p_pnt_arr, *p_tan_arr, *p_pnt_arr2, *p_tan_arr2;
    ProComponentCurvedata   *p_comp_arr, *new_comp_arr;

    err = ProCurvedataTypeGet(c_in, &c_type);
    TEST_CALL_REPORT("ProCurvedataTypeGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
    switch(c_type)
    {
    case PRO_ENT_POINT:
	err = ProPointdataGet(c_in, p1);
    	TEST_CALL_REPORT("ProPointdataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProPointdataInit(p1, c_out);
    	TEST_CALL_REPORT("ProPointdataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    break;
    case PRO_ENT_LINE:
	    err = ProLinedataGet(c_in, p1, p2);
    	TEST_CALL_REPORT("ProLinedataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProLinedataInit(p1, p2, c_out);
    	TEST_CALL_REPORT("ProLinedataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    break;
    case PRO_ENT_ARC:
	    err = ProArcdataGet(c_in, v1, v2, p1, &st_a, &en_a, &rad);
    	TEST_CALL_REPORT("ProArcdataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProArcdataInit(v1, v2, p1, st_a, en_a, rad, c_out);
    	TEST_CALL_REPORT("ProArcdataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    break;
    case PRO_ENT_SPLINE:
	    err = ProSplinedataGet(c_in, &p_par_arr, &p_pnt_arr, &p_tan_arr,
	        &n_point);
    	TEST_CALL_REPORT("ProSplinedataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);

	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProUtilArrayCopy((ProArray)p_par_arr, (ProArray*)&p_par_arr2,
	        sizeof(p_par_arr[0]));
    	TEST_CALL_REPORT("ProUtilArrayCopy()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    err = ProUtilArrayCopy((ProArray)p_pnt_arr, (ProArray*)&p_pnt_arr2,
	        sizeof(p_pnt_arr[0]));
    	TEST_CALL_REPORT("ProUtilArrayCopy()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    err = ProUtilArrayCopy((ProArray)p_tan_arr, (ProArray*)&p_tan_arr2,
	        sizeof(p_tan_arr[0]));
    	TEST_CALL_REPORT("ProUtilArrayCopy()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);

	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProSplinedataInit(p_par_arr2, p_pnt_arr2, p_tan_arr2, n_point,
	        c_out);
    	TEST_CALL_REPORT("ProSplinedataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    break;
    case PRO_ENT_B_SPLINE:
	err = ProBsplinedataGet(c_in, &degree, &p_par_arr, &p_weight_arr,
	        &p_pnt_arr, &n_knots, &n_point);
    	TEST_CALL_REPORT("ProBsplinedataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	if (err != PRO_TK_NO_ERROR)
	        break;
	err = ProUtilArrayCopy((ProArray)p_pnt_arr, (ProArray*)&p_pnt_arr2,
	        sizeof(p_pnt_arr[0]));
    	TEST_CALL_REPORT("ProUtilArrayCopy()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilArrayCopy((ProArray)p_par_arr, (ProArray*)&p_par_arr2,
	        sizeof(p_par_arr[0]));
    	TEST_CALL_REPORT("ProUtilArrayCopy()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	
        if (p_weight_arr != NULL)
        {
            err = ProUtilArrayCopy((ProArray)p_weight_arr, 
	        (ProArray*)&p_weight_arr2, sizeof(p_weight_arr[0]));
    	    TEST_CALL_REPORT("ProUtilArrayCopy()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
        }
        else
               p_weight_arr2 = NULL;

	if (err != PRO_TK_NO_ERROR)
	    break;
	err = ProBsplinedataInit(degree, p_par_arr2, p_weight_arr2, p_pnt_arr2,
	        n_knots, n_point, c_out);
    	TEST_CALL_REPORT("ProBsplinedataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
        break;
    case PRO_ENT_CMP_CRV:
	    err = ProCompositeCurvedataGet(c_in, &p_comp_arr);
    	TEST_CALL_REPORT("ProCompositeCurvedataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProUtilComponentArrayCopy(p_comp_arr, &new_comp_arr);
	    if (err != PRO_TK_NO_ERROR)
	        break;
	    err = ProCompositeCurvedataInit(new_comp_arr, c_out);
    	TEST_CALL_REPORT("ProCompositeCurvedataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    if (err != PRO_TK_NO_ERROR)
	        break;

	    break;
    case PRO_ENT_ELLIPSE:
        err = ProEllipsedataGet (c_in, p1, v1, v2, &d1, &d2, &d3, &d4);
        TEST_CALL_REPORT("ProEllipsedataGet()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
	    if (err != PRO_TK_NO_ERROR)
	        break;
        err = ProEllipsedataInit (p1, v1, v2, d1, d2, d3, d4, c_out);
        TEST_CALL_REPORT("ProEllipsedataInit()", 
	           "ProUtilCurvedataCopy()", err, err != PRO_TK_NO_ERROR);
        break;
    default:
	    ProUtilMsgPrint("gen", "TEST %0s", "Unknown curve type");
        ProTKFprintf(stderr, "Copy: Unknown curve type %d \n", c_type);
	    c_out[0] = c_in[0];
 	    break;
    }
    return (err);
}

/*====================================================================*\
    FUNCTION :  ProUtilEdgedataCopy()
    PURPOSE  :  copy edgedata using different functions
\*====================================================================*/
ProError ProUtilEdgedataCopy(
    ProEdgedata **pp_edge_data)	/* In, out : edge data */
{
    ProError err;
    int		edge_id;
    int		edge_surf_ids[2];
    ProEdgeDir	edge_dirs[2];
    ProUvParam	(*edge_uv_point_arr)[2], (*edge_uv_point_arr_new)[2];
    ProCurvedata edge_uv_curve_0, edge_uv_curve_1;
    ProCurvedata *p_edge_uv_curve[2];
    ProCurvedata edge_xyz_curve;

    ProEdgedata	 *p_edge_data_new;
    ProCurvedata *p_edge_uv_curve_new[2]={NULL, NULL};
    ProCurvedata *p_edge_xyz_curve_new;
    ProEnttype	 curve_type;

    p_edge_uv_curve[0] = &edge_uv_curve_0;
    p_edge_uv_curve[1] = &edge_uv_curve_1;
    err = ProEdgedataGet(*pp_edge_data,
			 &edge_id,
			 edge_surf_ids,
			 edge_dirs,
			 &edge_uv_point_arr,
			 p_edge_uv_curve,
			 &edge_xyz_curve);
    TEST_CALL_REPORT("ProEdgedataGet()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
	           
    err = ProCurvedataTypeGet (p_edge_uv_curve[0], &curve_type);
    TEST_CALL_REPORT("ProCurvedataTypeGet()", 
                   "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
    if ((err == PRO_TK_NO_ERROR) && (curve_type != PRO_ENT_NONE))
    {
	err = ProCurvedataAlloc( &p_edge_uv_curve_new[0] );
	TEST_CALL_REPORT("ProCurvedataAlloc()",
                         "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilCurvedataCopy( p_edge_uv_curve[0], p_edge_uv_curve_new[0]);
    }
    else
	p_edge_uv_curve_new[0] = NULL;

    err = ProCurvedataTypeGet (p_edge_uv_curve[1], &curve_type);
    TEST_CALL_REPORT("ProCurvedataTypeGet()", 
                   "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
    if ((err == PRO_TK_NO_ERROR) && (curve_type != PRO_ENT_NONE))
    { 
        err = ProCurvedataAlloc( &p_edge_uv_curve_new[1] ); 
        TEST_CALL_REPORT("ProCurvedataAlloc()",
                         "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
	err = ProUtilCurvedataCopy(p_edge_uv_curve[1], p_edge_uv_curve_new[1]);
    }
    else
	p_edge_uv_curve_new[1] = NULL; 

    err = ProCurvedataTypeGet (&edge_xyz_curve, &curve_type);
    TEST_CALL_REPORT("ProCurvedataTypeGet()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
    if ((err == PRO_TK_NO_ERROR) && (curve_type != PRO_ENT_NONE))
    {
        err = ProCurvedataAlloc( &p_edge_xyz_curve_new);
        TEST_CALL_REPORT("ProCurvedataAlloc()", 
                         "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
        err = ProUtilCurvedataCopy(&edge_xyz_curve, p_edge_xyz_curve_new);   
    }
    else
	p_edge_xyz_curve_new = NULL;

    err = ProEdgedataAlloc(&p_edge_data_new);
    TEST_CALL_REPORT("ProEdgedataAlloc()",
                   "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
                   
    if ( edge_uv_point_arr != NULL)
    {
        err = ProUtilArrayCopy((ProArray)edge_uv_point_arr,
            (ProArray*)&edge_uv_point_arr_new, sizeof(ProUvParam)*2 );
    }
    else
        edge_uv_point_arr_new = NULL;
    err = ProEdgedataInit(edge_id, edge_surf_ids, edge_dirs,
			  edge_uv_point_arr,
			  (!p_edge_uv_curve_new[0]&&!p_edge_uv_curve_new[1]) ?
				NULL : p_edge_uv_curve_new,
			  p_edge_xyz_curve_new,
			  p_edge_data_new );
    TEST_CALL_REPORT("ProEdgedataInit()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);

    if (p_edge_xyz_curve_new != NULL)
    {
        err = ProCurvedataMemoryFree(p_edge_xyz_curve_new);
        TEST_CALL_REPORT("ProCurvedataMemoryFree()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
    }
   
    if (p_edge_uv_curve_new[0] != NULL)
    {
        memset(p_edge_uv_curve_new[0], '\0', sizeof(ProCurvedata));
        err = ProCurvedataFree(p_edge_uv_curve_new[0]);
        TEST_CALL_REPORT("ProCurvedataFree()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
        
    }


    if (p_edge_uv_curve_new[1] != NULL)
    {
        err = ProCurvedataMemoryFree(p_edge_uv_curve_new[1]);
        TEST_CALL_REPORT("ProCurvedataMemoryFree()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);
        
    }

    err = ProEdgedataFree( *pp_edge_data);
    TEST_CALL_REPORT("ProEdgedataFree()", 
	           "ProUtilEdgedataCopy()", err, err != PRO_TK_NO_ERROR);

    *pp_edge_data = p_edge_data_new;

    return (err); 	
}


/*====================================================================*\
    FUNCTION :  ProUtilQuiltdataCopy()
    PURPOSE  :  Copy quilt data using different commands
\*====================================================================*/
ProError ProUtilQuiltdataCopy(
    ProQuiltdata **p_q_data)    /* In, out - quilt data */
{
    ProError err;
    ProQuiltdata *quilt_data;
    int quilt_id;
    ProSurfacedata **p_surf_arr, **p_new_surf_arr;

    err = ProQuiltdataAlloc( &quilt_data);
    TEST_CALL_REPORT("ProQuiltdataAlloc()", 
	           "ProUtilQuiltdataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProQuiltdataGet(*p_q_data, &quilt_id);
    TEST_CALL_REPORT("ProQuiltdataGet()", 
	           "ProUtilQuiltdataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProQuiltdataInit(quilt_id, quilt_data);
    TEST_CALL_REPORT("ProQuiltdataInit()", 
	           "ProUtilQuiltdataCopy()", err, err != PRO_TK_NO_ERROR);
    
    err = ProQuiltdataSurfArrayGet(*p_q_data, &p_surf_arr);
    TEST_CALL_REPORT("ProQuiltdataSurfArrayGet()", 
	           "ProUtilQuiltdataCopy()", err, err != PRO_TK_NO_ERROR);
    err = ProUtilArrayCopy ((ProArray)p_surf_arr, (ProArray*)&p_new_surf_arr,
	sizeof (ProSurfacedata*));
    
    err = ProQuiltdataSurfArraySet(quilt_data, p_new_surf_arr);
    TEST_CALL_REPORT("ProQuiltdataSurfArraySet()", 
	           "ProUtilQuiltdataCopy()", err, err != PRO_TK_NO_ERROR);
#if 1
memset(  *p_q_data, '\0', sizeof(ProQuiltdata));
#endif
 
    err = ProQuiltdataFree( *p_q_data);
    TEST_CALL_REPORT("ProQuiltdataFree()", 
	           "ProUtilQuiltdataCopy()", err, err != PRO_TK_NO_ERROR);
    p_q_data[0] = quilt_data; 
    return (err);
}

/*====================================================================*\
    FUNCTION :  ProUtilDatumobjectCopy()
    PURPOSE  :  Copy Datum object using different commands
\*====================================================================*/
ProError ProUtilDatumobjectCopy(
    ProType	    datum_type,
    ProDatumobject *p_object)    /* In, out - Datum object */
{
    ProDatumobject datum_object;
    ProPlanedata planedata;
    ProCsysdata csysdata;	
    ProCurvedata *p_curvedata, curvedata;
    ProError err = PRO_TK_NO_ERROR;

    memset(&datum_object, '\0', sizeof(datum_object));
    switch (datum_type)
    {
    case PRO_CURVE:
	    err = ProCurvedataAlloc(&p_curvedata);
	    TEST_CALL_REPORT("ProCurvedataAlloc()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    err = ProDatumCurvedataGet(p_object, p_curvedata);
	    TEST_CALL_REPORT("ProDatumCurvedataGet()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    memset(&curvedata, '\0', sizeof(ProCurvedata));
	    err = ProUtilCurvedataCopy(p_curvedata, &curvedata);

            err = ProCurvedataMemoryFree(p_curvedata);
	    TEST_CALL_REPORT("ProCurvedataMemoryFree()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);
	    err = ProDatumCurvedataInit(&curvedata, &datum_object);
	    TEST_CALL_REPORT("ProDatumCurvedataInit()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    p_object[0] = datum_object;
	    break;
	case PRO_CSYS:
	    err = ProDatumCsysdataGet(p_object, &csysdata);
	    TEST_CALL_REPORT("ProDatumCsysdataGet()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    err = ProDatumCsysdataInit(&csysdata, &datum_object);
	    TEST_CALL_REPORT("ProDatumCsysdataInit()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    p_object[0] = datum_object;
	    break;		   
	case PRO_DATUM_PLANE:
	    err = ProDatumPlanedataGet(p_object, &planedata);
	    TEST_CALL_REPORT("ProDatumPlanedataGet()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    err = ProDatumPlanedataInit(&planedata, &datum_object);
	    TEST_CALL_REPORT("ProDatumPlanedataInit()", 
	           "ProUtilDatumobjectCopy()", err, err != PRO_TK_NO_ERROR);

	    p_object[0] = datum_object;
	    break;		   
	default:
	    ProTKFprintf(stderr, "unsupported datum data %d\n",datum_type);
	    err = PRO_TK_GENERAL_ERROR;
	    break;
    }
    return (err);
}

/*====================================================================*\
    FUNCTION :  ProUtilDatumdataCopy()
    PURPOSE  :  Copy Datum data using different commands
\*====================================================================*/
ProError ProUtilDatumdataCopy(
    ProDatumdata **p_d_data)    /* In, out - Datum data */
{
    ProError err;
    ProDatumdata *datum_data;
    int datum_id;
    ProType datum_type;
    ProName w_name;
    ProDatumobject datum_obj;
    ProUtilCname name;

    err = ProDatumdataAlloc( &datum_data);
    TEST_CALL_REPORT("ProDatumdataAlloc()", 
	           "ProUtilDatumdataCopy()", err, err != PRO_TK_NO_ERROR);

    err = ProDatumdataGet(*p_d_data, &datum_id, &datum_type, w_name, 
	&datum_obj);
    TEST_CALL_REPORT("ProDatumdataGet()", 
	           "ProUtilDatumdataCopy()", err, err != PRO_TK_NO_ERROR);
    ProWstringToString(name,w_name);

   
    err = ProUtilDatumobjectCopy(datum_type, &datum_obj);

    if (err == PRO_TK_NO_ERROR)
    {

        err = ProDatumdataInit(datum_id, datum_type, w_name, &datum_obj,
	    datum_data);
        TEST_CALL_REPORT("ProDatumdataInit()", 
	           "ProUtilDatumdataCopy()", err, err != PRO_TK_NO_ERROR);

        err = ProDatumdataFree( *p_d_data);
        TEST_CALL_REPORT("ProDatumdataFree()", 
	           "ProUtilDatumdataCopy()", err, err != PRO_TK_NO_ERROR);

        p_d_data[0] = datum_data; 

    }
    return (err);
}