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




/*--------------------------------------------------------------------*\
    Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include "ProToolkit.h"
#include "ProWindows.h"
#include "ProMdl.h"
#include "ProModelitem.h"
#include "ProDisplist.h"
#include "ProMenu.h"
#include "ProMessage.h"
#include "ProColor.h"
#include "ProUtil.h"
#include "ProArray.h"
#include "ProCurve.h"


/*--------------------------------------------------------------------*\
    Pro/DEVELOP includes
\*--------------------------------------------------------------------*/


/*--------------------------------------------------------------------*\
    C System includes
\*--------------------------------------------------------------------*/


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

/*--------------------------------------------------------------------*\
    Macros
\*--------------------------------------------------------------------*/
#define GRAPHICS_COLOR	    0	/* The color of the graphics */
#define TEXT_COLOR	    1	/* The color of the text */


/*--------------------------------------------------------------------*\
    Data types
\*--------------------------------------------------------------------*/


/*--------------------------------------------------------------------*\
    Application global/external data
\*--------------------------------------------------------------------*/


/*---------------------------------------------------------------------*\
    Functions declaration
\*---------------------------------------------------------------------*/
int	    ProTestEntityDrawMenu( void*, int );
int	    ProTestColorSet( void*, int );
int	    ProTestAssignColor( ProColor*, ProColortype );
int	    ProTestColormap( void*, int );
int	    ProTestGraphicsFreehandDraw( void* p_dummy, int int_dummy );
int	    ProTestRay (void*, int);
int     ProTestCurveColor(void*, int);
int     ProTestCurveLinestyle(void*, int);

/*===========================================================================*\
  Function : user_entity_menu
  Purpose  : To set up the entity menu
\*===========================================================================*/
/*---------------------------------------------------------------------*\
    Function:	ProTestGraphics()
    Purpose:	Top-level function. Create and run TkGraph menu to test
		ProGraphics functions.
    Returns:	0 - success; -1 - error. Now ignored.
\*---------------------------------------------------------------------*/
int ProTestGraphics( void* p_dummy, int int_dummy )
{
    ProError    status;
    int			menu_id;    /* The identifier of the created menu */
    int			action;


    /*-----------------------------*\
	Create new menu TkGraphics
    \*-----------------------------*/

    /* Load base menu from file */
    status = ProMenuFileRegister( (char*)"TkGraphics", (char*)"tkgraph.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestGraphics()", 
			status, status != PRO_TK_NO_ERROR );

    /* Define menu buttons */
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Draw", 
        (ProMenubuttonAction)ProTestEntityDrawMenu, NULL, 0 );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Display List 2D", 
        (ProMenubuttonAction)ProTest2dDisplistMenu, NULL, 0 );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Display List 3D", 
        (ProMenubuttonAction)ProTest3dDisplistMenu, NULL, 0 );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Ray demo", 
        (ProMenubuttonAction)ProTestRay, NULL, 0  );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Curve color", 
	    (ProMenubuttonAction)ProTestCurveColor, NULL, 0 );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Curve linestyle", 
	    (ProMenubuttonAction)ProTestCurveLinestyle, NULL, 0 );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "Done", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0 );
    status = ProMenubuttonActionSet((char*) "TkGraphics",(char*) "TkGraphics", 
	    (ProMenubuttonAction)ProMenuDelete, NULL, 0 );


    /*-----------------------*\
	Run menu TkGraphics
    \*-----------------------*/
    status = ProMenuCreate( PROMENUTYPE_MAIN, (char*)"TkGraphics", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestGraphics()", 
			status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess((char*) "TkGraphics", &action );
	TEST_CALL_REPORT((char*) "ProMenuProcess()", "ProTestGraphics()", 
			    status, status != PRO_TK_NO_ERROR );
    }


    return 0;
}



/*===========================================================================*\
  Function : ProTestGrMenuDelete
  Purpose  : Deletes menus
\*===========================================================================*/
int ProTestGrMenuDelete (void *data, int dummy)
{
    ProMenuDelete();
    ProMenuDelete();
    return (0);
}

/*---------------------------------------------------------------------*\
    Function:	ProTestEntityDrawMenu()
    Purpose:	On-button function. Set up the entity draw menu.
    Returns:	0 - success; Now ignored.
\*---------------------------------------------------------------------*/
int ProTestEntityDrawMenu( void* p_dummy, int int_dummy )
{
    ProError		status;
    int			menu_id;    /* The identifier of the created menu */
    int			action;
    static ProColor	old_color, drawing_color;
    static ProColor	old_text_color;
    ProDrawMode		old_mode;
    int			dummy;
    static char *cmpnd_menu[] = {"Gr Draw","Gr Set",""};

    int ProTestGraphicsMultiPolylinesDraw( void* p_dummy, int int_dummy );


    /* Set the graphics mode to complement */
    status = ProGraphicsModeSet( PRO_DRAW_SET_MODE, &old_mode );
    TEST_CALL_REPORT( "ProGraphicsModeSet()", "ProTestEntityDrawMenu()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );

    /* Set the color PRO_COLOR_DRAWING */
	drawing_color.method = PRO_COLOR_METHOD_TYPE;
	drawing_color.value.type = PRO_COLOR_DRAWING;
	
    status = ProGraphicsColorModify( &drawing_color, &old_color );
    TEST_CALL_REPORT( "ProGraphicsColorModify()", "ProTestEntityDrawMenu()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );

    status = ProTextColorModify( &drawing_color, &old_text_color );
    TEST_CALL_REPORT( "ProTextColorModify()", "ProTestEntityDrawMenu()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );

    /*-----------------------------*\
	Create new menu Gr Draw
    \*-----------------------------*/

    /* Load menu from file */
    status = ProMenuFileRegister((char*) "Gr Draw",(char*) "tkgrdraw.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestEntityDrawMenu()", 
			status, status != PRO_TK_NO_ERROR );

    /* Define menu buttons */
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Arc", 
	(ProMenubuttonAction)ProTestGraphicsArcDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Text", 
	(ProMenubuttonAction)ProTestGraphicsTextDisplay, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Circle", 
	(ProMenubuttonAction)ProTestGraphicsCircleDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Line", 
	(ProMenubuttonAction)ProTestGraphicsLineDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "PolyLine", 
	(ProMenubuttonAction)ProTestGraphicsPolylineDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "MultiPolyLine",
        (ProMenubuttonAction)ProTestGraphicsMultiPolylinesDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Box", 
	(ProMenubuttonAction)ProTestGraphicsPolygonDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Freehand", 
	(ProMenubuttonAction)ProTestGraphicsFreehandDraw, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Draw",(char*) "Gr Draw", 
	(ProMenubuttonAction)ProMenuHold, NULL, 0 );

    status = ProMenuFileRegister((char*) "Gr Set",(char*) "tkgrset.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestEntityDrawMenu()", 
			status, status != PRO_TK_NO_ERROR );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Set Text", 
        (ProMenubuttonAction)ProTestText, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Set Line", 
        (ProMenubuttonAction)ProTestLineSetMenu, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Color Map", 
        (ProMenubuttonAction)ProTestColormap, NULL, 0  );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Color", 
	(ProMenubuttonAction)ProTestColorSet, NULL, GRAPHICS_COLOR );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Text Color", 
	(ProMenubuttonAction)ProTestColorSet, NULL, TEXT_COLOR );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Done", 
	(ProMenubuttonAction)ProTestGrMenuDelete, NULL, 0 );
    ProMenubuttonActionSet((char*) "Gr Set",(char*) "Gr Set", 
	(ProMenubuttonAction)ProMenuHold, NULL, 0 );

    /*----------------------*\
	Run menu Gr Draw
    \*----------------------*/
    status = ProCompoundmenuCreate(cmpnd_menu, &menu_id);
    TEST_CALL_REPORT("ProCompoundmenuCreate()", 
        "ProTestEntityDrawMenu()",
	status , status != PRO_TK_NO_ERROR);   
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess((char*) "Gr Draw", &action );
	TEST_CALL_REPORT((char*) "ProMenuProcess()", "ProTestEntityDrawMenu()", 
			    status, status != PRO_TK_NO_ERROR );
    }


    /* Restore old colors */
    status = ProGraphicsColorModify( &old_color, NULL );
    TEST_CALL_REPORT( "ProGraphicsColorModify()", "ProTestEntityDrawMenu()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );

    status = ProTextColorModify( &old_text_color, NULL );
    TEST_CALL_REPORT( "ProTextColorModify()", "ProTestEntityDrawMenu()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );

    status = ProGraphicsModeSet( old_mode, (ProDrawMode *)&dummy );
    TEST_CALL_REPORT( "ProGraphicsModeSet()", "ProTestEntityDrawMenu()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );


    return PRO_TK_NO_ERROR;
}



/*===========================================================================*\
  Function : user_entity_color
  Purpose  : To set up the color menu
\*===========================================================================*/
/*---------------------------------------------------------------------*\
    Function:	ProTestColorSet()
    Purpose:	On-button function. Run menu to select color, then set
		selected color as current.
    Returns:	PRO_TK_NO_ERROR - success; Otherwise - error. 
		Now ignored.
\*---------------------------------------------------------------------*/
int ProTestColorSet( 
    void* p_dummy, 
    int type )	    /* (In)	TEXT_COLOR or GRAPHICS_COLOR */
{
    ProError		status;
    int			menu_id;    /* The identifier of the created menu */
    int			action;
    ProColor	new_color ;
    ProColor	old_color;


    /*-----------------------------*\
	Create new menu Color
    \*-----------------------------*/

    /* Load base menu from file */
    status = ProMenuFileRegister((char*) "Color",(char*) "tkgrcolor.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestColorSet()", 
			status, status != PRO_TK_NO_ERROR );
			
	new_color.method = PRO_COLOR_METHOD_TYPE;
	new_color.value.type = PRO_COLOR_DRAWING;		

    /* Define menu buttons */
    ProMenubuttonActionSet((char*) "Color",(char*) "Letter", 
	(ProMenubuttonAction)ProTestAssignColor, 
	&new_color, PRO_COLOR_LETTER );
    ProMenubuttonActionSet((char*) "Color",(char*) "Highlight", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_HIGHLITE );
    ProMenubuttonActionSet((char*) "Color",(char*) "Drawing", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_DRAWING );
    ProMenubuttonActionSet((char*) "Color",(char*) "Background", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_BACKGROUND );
    ProMenubuttonActionSet((char*) "Color",(char*) "Half Tone", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_HALF_TONE );
    ProMenubuttonActionSet((char*) "Color",(char*) "Edge Highlt",
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_EDGE_HIGHLIGHT );
    ProMenubuttonActionSet((char*) "Color",(char*) "Dimmed", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_DIMMED );
    ProMenubuttonActionSet((char*) "Color",(char*) "Error", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_ERROR );
    ProMenubuttonActionSet((char*) "Color",(char*) "Warning", 
	(ProMenubuttonAction)ProTestAssignColor,
	&new_color, PRO_COLOR_WARNING );
    ProMenubuttonActionSet((char*) "Color",(char*) "Color", 
	(ProMenubuttonAction)ProMenuDelete, NULL, 0 );


    /*-------------------*\
	Run menu Color
    \*-------------------*/
    status = ProMenuCreate( PROMENUTYPE_MAIN,(char*) "Color", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestColorSet()", 
			status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess((char*) "Color", &action );
	TEST_CALL_REPORT((char*) "ProMenuProcess()", "ProTestColorSet()", 
			    status, status != PRO_TK_NO_ERROR );
    }

    /* Set selected color as current */
    if( type == TEXT_COLOR )
    {
        status = ProTextColorModify( &new_color, &old_color );
	TEST_CALL_REPORT( "ProTextColorModify()", "ProTestColorSet()", 
			status, 
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );
    }
    else
    {
        status = ProGraphicsColorModify( &new_color, &old_color );
	TEST_CALL_REPORT( "ProGraphicsColorModify()", "ProTestColorSet()", 
			status,
			(status!=PRO_TK_NO_ERROR) && (status!=PRO_TK_NO_CHANGE) );
    }


    return status;
}



/*===========================================================================*\
  Function : user_assign_color
  Purpose  :
\*===========================================================================*/
/*---------------------------------------------------------------------*\
    Function:	ProTestAssignColor()
    Purpose:	On-button function. Run menu to select color, then set
		selected color as current.
    Returns:	0 - success; Now ignored.
\*---------------------------------------------------------------------*/
int ProTestAssignColor( 
    ProColor* p_color,  /* (Out)	Variable to assign color to */
    ProColortype col_type)	    /* (In)	Color to assign */
{
    ProError	    status;

	(*p_color).method = PRO_COLOR_METHOD_TYPE;
	(*p_color).value.type = col_type;
    
    status = ProMenuDelete();
    TEST_CALL_REPORT( "ProMenuDelete()", "ProTestAssignColor()", 
			status, status!=PRO_TK_NO_ERROR );


    return 0;
}



/*===========================================================================*\
  Function : user__color
  Purpose  : ucolor.c
\*===========================================================================*/
/*---------------------------------------------------------------------*\
    Function:	ProTestColormap()
    Purpose:	On-button. Test of the color map functions
    Returns:	0 - success; -1 - error. Now ignored.
\*---------------------------------------------------------------------*/
int ProTestColormap( void* p_dummy, int int_dummy )
{
    ProError	    status;
    int		    menu_id;    /* The identifier of the created menu */
    int		    action;
    ProColortype    c_type = PRO_COLOR_DRAWING;
	ProColor color;
    ProColormap	    color_map;
    double	    range[ 2 ] = {0.0, 1.0};
    char	    buffer[ PRO_LINE_SIZE ];


    /* Load base menu from file */
    status = ProMenuFileRegister((char*) "Color",(char*) "tkgrcolor.mnu", &menu_id );
    TEST_CALL_REPORT( "ProMenuFileRegister()", "ProTestColormap()", 
			status, status != PRO_TK_NO_ERROR );

    /* Define menu buttons */
    ProMenubuttonActionSet((char*) "Color",(char*) "Letter", 
	(ProMenubuttonAction)ProTestAssignColor, 
	&color, PRO_COLOR_LETTER );
    ProMenubuttonActionSet((char*) "Color",(char*) "Highlight", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_HIGHLITE );
    ProMenubuttonActionSet((char*) "Color",(char*) "Drawing", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_DRAWING );
    ProMenubuttonActionSet((char*) "Color",(char*) "Background", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_BACKGROUND );
    ProMenubuttonActionSet((char*) "Color",(char*) "Half Tone", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_HALF_TONE );
    ProMenubuttonActionSet((char*) "Color",(char*) "Edge Highlt",
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_EDGE_HIGHLIGHT );
    ProMenubuttonActionSet((char*) "Color",(char*) "Dimmed", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_DIMMED );
    ProMenubuttonActionSet((char*) "Color",(char*) "Error", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_ERROR );
    ProMenubuttonActionSet((char*) "Color",(char*) "Warning", 
	(ProMenubuttonAction)ProTestAssignColor,
	&color, PRO_COLOR_WARNING );
    ProMenubuttonActionSet((char*) "Color",(char*) "Color", 
	(ProMenubuttonAction)ProMenuDelete, NULL, 0 );


    /*-------------------*\
	Run menu Color
    \*-------------------*/
    status = ProMenuCreate( PROMENUTYPE_MAIN,(char*) "Color", &menu_id );
    TEST_CALL_REPORT( "ProMenuCreate()", "ProTestColormap()", 
			status, status != PRO_TK_NO_ERROR );
    if( status == PRO_TK_NO_ERROR )
    {
	status = ProMenuProcess((char*) "Color", &action );
	TEST_CALL_REPORT((char*) "ProMenuProcess()", "ProTestColormap()", 
			    status, status != PRO_TK_NO_ERROR );
    }

    /*  First get the color values  */
    status = ProColormapGet( c_type, &color_map );
    TEST_CALL_REPORT( "ProColormapGet()", "ProTestColormap()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return -1;

    ProTKSprintf( buffer, "Current color map: red %f gree %f blue %f", 
		color_map.red, color_map.green, color_map.blue ); 
    ProUtilMsgPrint( "gen", "TEST %0s", buffer );
    ProMessageClear();
    TEST_CALL_REPORT( "ProMessageClear()", "ProTestOptionOrderedVerify()", 
			(ProError)0, 0 );

    /*  Ask the user for new values  */
    ProUtilMsgPrint( "gen", "TEST %0s", "Red Value: " );
    if( !ProUtilDoubleGet( range, NULL, &(color_map.red) ) )
	return -1;

    ProUtilMsgPrint( "gen", "TEST %0s", "Green Value: " );
    if( !ProUtilDoubleGet( range, NULL, &(color_map.green) ) )
	return -1;

    ProUtilMsgPrint( "gen", "TEST %0s", "Blue Value: " );
    if( !ProUtilDoubleGet( range, NULL, &(color_map.blue) ) )
	return -1;


    /*  Now set the color values  */
    status = ProColormapSet( c_type, &color_map );
    TEST_CALL_REPORT( "ProColormapSet()", "ProTestColormap()", 
			status, status != PRO_TK_NO_ERROR );


    return 0;
}



/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsArcDraw()
    Purpose:	On-button function. Test arc drawing.
		Ask user to pick 3 points. Use this points to draw the arc.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsArcDraw( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point1;
    ProPoint3d		point2;
    ProPoint3d		point3;
    ProPoint3d		center;
    double		radius;

    
    /* Declare functions from UtilArcEndPoints.c */
    int ProUtilArc3Points( double pnt1[3], double pnt2[3], double pnt3[3], 
			    double* p_rad, double center[3] );
    int ProUtilArcEndPoints( double, double, double, double, double, double, 
			    double, double, double, double, double, double, 
			    double end1[3], double end2[3] );

    /*--------------------------*\
	Pick 3 points by mouse
    \*--------------------------*/
    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the first point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point1 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsArcDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the second point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point2 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsArcDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the third point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point3 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsArcDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;



    /* Create an arc from 3 points */
    ProUtilArc3Points( point1, point2, point3, &radius, center );

    /* Arc is drawn CCW,  from end1 to end2 */
    ProUtilArcEndPoints( point1[0], point1[1], point1[2], 
			    point2[0], point2[1], point2[2],
			    point3[0], point3[1], point3[2], 
			    center[0], center[1], center[2], 
			    point1, point2 );

    /* Draw the arc */
    status = ProGraphicsArcDraw( center, radius, point1, point2 );
    TEST_CALL_REPORT( "ProGraphicsArcDraw()", "ProTestGraphicsArcDraw()", 
			status, status != PRO_TK_NO_ERROR );
    

    return (status == PRO_TK_NO_ERROR) ? 1 : 0;
}



/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsCircleDraw()
    Purpose:	On-button function. Test circle drawing.
		Ask user to pick 2 points. Use this points to draw 
		the circle.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsCircleDraw( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point1;
    ProPoint3d		point2;
    double		radius;
    ProMatrix		view_matrix;
    ProMatrix		trf_matrix;


    /* Obtain the view matrix  */
    status = ProViewMatrixGet( NULL, NULL, view_matrix );
    TEST_CALL_REPORT( "ProViewMatrixGet()", "ProTestGraphicsCircleDraw()", 
			status, status != PRO_TK_NO_ERROR );
    ProUtilMatrixInvert( view_matrix, trf_matrix );


    /* Pick 2 points by mouse */
    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the first point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point1 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsCircleDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the second point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point2 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsCircleDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    /* Transform points by matrix */
    ProUtilPointTrans( trf_matrix, point1, point1 );
    ProUtilPointTrans( trf_matrix, point2, point2 );

    /* Calculate the radius */
    radius = ProUtilPointsDist( point1, point2 );

    /* Draw the circle */
    ProGraphicsCircleDraw( point1, radius );
    TEST_CALL_REPORT( "ProGraphicsCircleDraw()", "ProTestGraphicsCircleDraw()", 
			(ProError)0, 0 );


    return 1;
}



/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsTextDisplay()
    Purpose:	On-button function. Test text displaying.
		Ask user to pick the text location and enter the text to
		display.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsTextDisplay( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point1;
    wchar_t		w_string[ 80 ];


    /* Pick the point by mouse */
    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the first point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point1 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsTextDisplay()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    /* Get a text to display */
    ProUtilMsgPrint( "gen", "TEST %0s", "Enter the text: " );
    status = ProMessageStringRead( 80, w_string );
    TEST_CALL_REPORT( "ProMessageStringRead()", "ProTestGraphicsTextDisplay()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    /* Display the text */
    status = ProGraphicsTextDisplay( point1, w_string );
    TEST_CALL_REPORT( "ProGraphicsTextDisplay()", 
			"ProTestGraphicsTextDisplay()", 
			status, status != PRO_TK_NO_ERROR );


    return 1;
}


/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsLineDraw()
    Purpose:	On-button function. Test line drawing.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsLineDraw( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point1;
    ProPoint3d		point2;
    ProMatrix		view_matrix;
    ProMatrix		trf_matrix;


    /* Obtain the view matrix  */
    status = ProViewMatrixGet( NULL, NULL, view_matrix );
    TEST_CALL_REPORT( "ProViewMatrixGet()", "ProTestGraphicsLineDraw()", 
			status, status != PRO_TK_NO_ERROR );
    ProUtilMatrixInvert( view_matrix, trf_matrix );

   /* Pick 2 points by mouse */
    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the first point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point1 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsLineDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the second point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point2 );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsLineDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    /* Transform points by matrix */
    ProUtilPointTrans( trf_matrix, point1, point1 );
    ProUtilPointTrans( trf_matrix, point2, point2 );

    /* Draw the line */
    ProGraphicsPenPosition( point1 );
    TEST_CALL_REPORT( "ProGraphicsPenPosition()", "ProTestGraphicsLineDraw()", 
			(ProError)0, 0 );
    ProGraphicsLineDraw( point2 );
    TEST_CALL_REPORT( "ProGraphicsLineDraw()", "ProTestGraphicsLineDraw()", 
			(ProError)0, 0 );


    return 1;
}

/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsPolylineDraw()
    Purpose:	On-button function. Test polyline drawing.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsPolylineDraw( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point1;
    ProPoint3d*		p_point_arr;
    int			n_points;
    int			i;
    ProMatrix		view_matrix;
    ProMatrix		trf_matrix;


    /* Obtain the view matrix  */
    status = ProViewMatrixGet( NULL, NULL, view_matrix );
    TEST_CALL_REPORT( "ProViewMatrixGet()", "ProTestGraphicsPolylineDraw()", 
			status, status != PRO_TK_NO_ERROR );
    ProUtilMatrixInvert( view_matrix, trf_matrix );

    /* Init the points array */
    status = ProArrayAlloc( 0, sizeof(ProPoint3d), 1, (ProArray*)&p_point_arr );
    TEST_CALL_REPORT( "ProArrayAlloc()", "ProTestGraphicsPolylineDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    ProUtilMsgPrint( "gen", "TEST %0s", "Pick 'n+1' points" );
    for( i=0; i<200; i++ )
    {
	 /* Pick the next point by mouse */
	status = ProMousePickGet( PRO_ANY_BUTTON, &button, point1 );
	TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsPolylineDraw()", 
			    status, status != PRO_TK_NO_ERROR );
	if( (status != PRO_TK_NO_ERROR) || (button != PRO_LEFT_BUTTON) )
	    break;  /* Leave the loop */

	/* Transform point by matrix */
	ProUtilPointTrans( trf_matrix, point1, point1 );

	/* Add the point to the array */
	status = ProArrayObjectAdd( (ProArray*)&p_point_arr, PRO_VALUE_UNUSED, 1, point1 );
	TEST_CALL_REPORT( "ProArrayObjectAdd()", 
			    "ProTestGraphicsPolylineDraw()", 
			    status, status != PRO_TK_NO_ERROR );

	/* Draw the small circle to mark the point */
	ProGraphicsCircleDraw( point1, 0.05 );
	TEST_CALL_REPORT( "ProGraphicsCircleDraw()", 
			    "ProTestGraphicsPolylineDraw()", (ProError)0, 0 );
    }

    /* Get the number of points */
    status = ProArraySizeGet( p_point_arr, &n_points );
    TEST_CALL_REPORT( "ProArraySizeGet()", "ProTestGraphicsPolylineDraw()", 
			status, status != PRO_TK_NO_ERROR );

    if( n_points > 1 )
    {
	/* Draw a series of connected line segments */
	ProGraphicsPolylineDraw( p_point_arr, n_points );
	TEST_CALL_REPORT( "ProGraphicsPolylineDraw()", 
			    "ProTestGraphicsPolylineDraw()", (ProError)0, 0 );
    }

    /* Free the pre-allocated array */
    status = ProArrayFree( (ProArray*)&p_point_arr );
    TEST_CALL_REPORT( "ProArrayFree()", "ProTestGraphicsPolylineDraw()", 
			status, status != PRO_TK_NO_ERROR );


    return 1;
}
/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsPolygonDraw()
    Purpose:	On-button function. Test the polygon drawing.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsPolygonDraw( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProOutline		outline;
    ProPoint3d		points[ 4 ];
    ProPoint3d		start_point;
    ProPoint2d		rect[ 5 ];
    int			i;


    /* Select rectangle by mouse */
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, start_point );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsPolygonDraw()", 
			status, status != PRO_TK_NO_ERROR );

    status = ProMouseBoxInput( start_point, outline );
    TEST_CALL_REPORT( "ProMouseBoxInput()", "ProTestGraphicsPolygonDraw()", 
			status, status != PRO_TK_NO_ERROR );

    /* Init rectangle vertices */
    ProUtilVectorCopy( outline[0], points[0] );
    ProUtilVectorCopy( outline[1], points[2] );
    ProUtilVectorCopy( points[0], points[1] );
    ProUtilVectorCopy( points[2], points[3] );
    points[1][1] = points[2][1];
    points[3][1] = points[0][1];

    /* Copy the array of 3d points to the array of 2d points */
    rect[4][0] = points[0][0];
    rect[4][1] = points[0][1];
    for( i=0; i<4; i++ )
    {
	rect[i][0] = points[i][0];
	rect[i][1] = points[i][1];
    }

    /* Draw the filled polygon */
    status = ProGraphicsPolygonDraw( rect, 5, PRO_COLOR_ERROR );
    TEST_CALL_REPORT( "ProGraphicsPolygonDraw()", 
			"ProTestGraphicsPolygonDraw()", 
			status, status != PRO_TK_NO_ERROR );


    return 1;
}



int ProTestGraphicsFreehandDraw( void* p_dummy, int int_dummy )

{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point;
    ProMatrix		view_matrix;
    ProMatrix		trf_matrix;


    /* Obtain the view matrix  */
    status = ProViewMatrixGet( NULL, NULL, view_matrix );
    TEST_CALL_REPORT( "ProViewMatrixGet()", "ProTestGraphicsFreehandDraw()", 
			status, status != PRO_TK_NO_ERROR );
    ProUtilMatrixInvert( view_matrix, trf_matrix );

    ProUtilMsgPrint( "gen", "TEST %0s", "Pick the point" );
    status = ProMousePickGet( PRO_LEFT_BUTTON, &button, point );
    TEST_CALL_REPORT( "ProMousePickGet()", "ProTestGraphicsFreehandDraw()", 
			status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    /* Transform points by matrix */
    ProUtilPointTrans( trf_matrix, point, point );

    ProGraphicsPenPosition( point );
    TEST_CALL_REPORT( "ProGraphicsPenPosition()", "ProTestGraphicsFreehandDraw()", 
			(ProError)0, 0 );

    button = PRO_NO_BUTTON;
    while( button != PRO_LEFT_BUTTON )
    {
	status = ProMouseTrack( PRO_B_FALSE, &button, point );
	TEST_CALL_REPORT( "ProMouseTrack()", "ProTestGraphicsFreehandDraw()", 
			    status, status != PRO_TK_NO_ERROR );
 
	/* Transform points by matrix */
	ProUtilPointTrans( trf_matrix, point, point );

	ProGraphicsLineDraw( point );
	TEST_CALL_REPORT( "ProGraphicsLineDraw()", "ProTestGraphicsFreehandDraw()", 
			    (ProError)0, 0 );
   }
    
    
    return 1;
}



/*---------------------------------------------------------------------*\
    Function:	ProTestGraphicsMultiPolylinesDraw()
    Purpose:	On-button function. Test multipolylines drawing.
    Returns:	1 - success; 0 - error.
\*---------------------------------------------------------------------*/
int ProTestGraphicsMultiPolylinesDraw( void* p_dummy, int int_dummy )
{
    ProError		status;
    ProMouseButton	button;
    ProPoint3d		point1;
    ProPoint3d*		p_point_arr;
    int*         	p_span_arr;
    int			n_points;
    ProMatrix		view_matrix;
    ProMatrix		trf_matrix;
    int			done = 1;


    /* Obtain the view matrix  */
    status = ProViewMatrixGet( NULL, NULL, view_matrix );
    TEST_CALL_REPORT( "ProViewMatrixGet()", 
	"ProTestGraphicsMultiPolylineDraw()", 
	status, status != PRO_TK_NO_ERROR );
    ProUtilMatrixInvert( view_matrix, trf_matrix );

    /* Init the points array */
    status = ProArrayAlloc( 0, sizeof(ProPoint3d), 1, (ProArray*)&p_point_arr );
    TEST_CALL_REPORT( "ProArrayAlloc()", "ProTestGraphicsMultiPolylineDraw()", 
	status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
	return 0;

    /* Init the polylines size array */
    status = ProArrayAlloc( 0, sizeof(int), 1, (ProArray*)&p_span_arr );
    TEST_CALL_REPORT( "ProArrayAlloc()", "ProTestGraphicsMultiPolylineDraw()",
        status, status != PRO_TK_NO_ERROR );
    if( status != PRO_TK_NO_ERROR )
        return 0;

    while( done )
    {
	n_points = 0;
	while( done )
	{
    	    button = PRO_NO_BUTTON;
	    
	    /* Pick the next point by mouse */
	    status = ProMousePickGet( PRO_ANY_BUTTON, &button, point1 );
	    TEST_CALL_REPORT( "ProMousePickGet()", 
		"ProTestGraphicsMultiPolylineDraw()", 
	    	status, status != PRO_TK_NO_ERROR );
	    if( (status != PRO_TK_NO_ERROR) || (button != PRO_LEFT_BUTTON) )
	    	break;  /* Leave the loop */

	    /* Transform point by matrix */
	    ProUtilPointTrans( trf_matrix, point1, point1 );

	    /* Add the point to the array */
	    status = ProArrayObjectAdd( (ProArray*)&p_point_arr, 
		PRO_VALUE_UNUSED, 
		1, point1 );
	    TEST_CALL_REPORT( "ProArrayObjectAdd()", 
    		"ProTestGraphicsMultiPolylineDraw()", 
		status, status != PRO_TK_NO_ERROR );

	    /* Draw the small circle to mark the point */
	    ProGraphicsCircleDraw( point1, 0.05 );
	    TEST_CALL_REPORT( "ProGraphicsCircleDraw()", 
	    	"ProTestGraphicsMultiPolylineDraw()", (ProError)0, 0 );

	    n_points++;
	}

        if( status != PRO_TK_NO_ERROR )
            break;  /* Leave the loop */

	if( n_points > 0 )
	{
            /* Add the point counter to the array */
            status = ProArrayObjectAdd( (ProArray*)&p_span_arr,
            	PRO_VALUE_UNUSED, 1, &n_points );
            TEST_CALL_REPORT( "ProArrayObjectAdd()",
            	"ProTestGraphicsMultiPolylineDraw()",
            	status, status != PRO_TK_NO_ERROR );
	}

        if( button == PRO_RIGHT_BUTTON )
            break;  /* Leave the loop */
    }

    /* Get the number of points */
    status = ProArraySizeGet( p_span_arr, &n_points );
    TEST_CALL_REPORT( "ProArraySizeGet()", 
	"ProTestGraphicsMultiPolylineDraw()", 
	status, status != PRO_TK_NO_ERROR );

    if( n_points > 1 )
    {
	/* Draw a series of connected line segments */
	ProGraphicsMultiPolylinesDraw( p_point_arr, p_span_arr, n_points );
	TEST_CALL_REPORT( "ProGraphicsMultiPolylinesDraw()", 
	    "ProTestGraphicsMultiPolylineDraw()", (ProError)0, 0 );
    }

    /* Free the pre-allocated array */
    status = ProArrayFree( (ProArray*)&p_point_arr );
    TEST_CALL_REPORT( "ProArrayFree()", "ProTestGraphicsMultiPolylineDraw()", 
	status, status != PRO_TK_NO_ERROR );

    /* Free the pre-allocated array */
    status = ProArrayFree( (ProArray*)&p_span_arr );
    TEST_CALL_REPORT( "ProArrayFree()", "ProTestGraphicsMultiPolylineDraw()",
        status, status != PRO_TK_NO_ERROR );


    return 1;
}

/*============================================================================*\
  Function : ProTestCurveColor
  Purpose  : Test ProCurveColor functions
\*============================================================================*/
int ProTestCurveColor( void* p_dummy, int int_dummy )
{
    ProError status;
    ProMdl owner;
    ProModelitem modelitem;
    ProCurve curve;
    ProSelection *p_sel;
    int n_sel, opt = 0;
    ProColortype old_color;
    static ProUtilMenuButtons color_type[] = { 
        {"-Color", 0, TEST_CALL_PRO_MENU_DELETE},
        {"Yellow", PRO_COLOR_LETTER, 0},
        {"Red",PRO_COLOR_HIGHLITE, 0},
        {"White", PRO_COLOR_DRAWING, 0},
        {"Background", PRO_COLOR_BACKGROUND, 0},
        {"Grey", PRO_COLOR_HALF_TONE , 0},
        {"Blue", PRO_COLOR_EDGE_HIGHLIGHT,0},
        {"Grey", PRO_COLOR_DIMMED, 0},
        {"Magenta", PRO_COLOR_ERROR , 0},
        {"Cyan", PRO_COLOR_WARNING , 0},
        {"Green", PRO_COLOR_SHEETMETAL, 0},
        {"Brown", PRO_COLOR_CURVE, 0},
        {"MAX", PRO_COLOR_MAX, 0},
        {"",0,0}
    };
    
    status = ProUtilMenuIntValueSelect(color_type, &opt);
    TEST_CALL_REPORT ("ProUtilMenuIntValueSelect()", "ProTestCurveColor()",
       status, status!= PRO_TK_NO_ERROR);

    ProUtilMsgPrint("gen", "TEST %0s", "Select curve");
    status = ProSelect ((char*)"curve", 1, NULL, NULL, NULL, NULL, &p_sel,
        &n_sel);
    if (status != PRO_TK_NO_ERROR || n_sel != 1)
        return (0);

    status = ProSelectionModelitemGet (p_sel[0], &modelitem);
    TEST_CALL_REPORT ("ProSelectionModelitemGet()", "ProTestCurveColor()",
        status, status != PRO_TK_NO_ERROR);

    status = ProModelitemMdlGet (&modelitem, &owner);
    TEST_CALL_REPORT ("ProModelitemMdlGet()", "ProTestCurveColor()",
        status, status != PRO_TK_NO_ERROR);

    status = ProCurveInit ((ProSolid)owner, modelitem.id, &curve);
    TEST_CALL_REPORT ("ProCurveInit()", "ProTestCurveColor()",
        status, status != PRO_TK_NO_ERROR);
        
    status = ProCurvePersistentColorGet (curve, &old_color);
    TEST_CALL_REPORT ("ProCurvePersistentColorGet()", "ProTestCurveColor()",
        status, status != PRO_TK_NO_ERROR);
    if(opt == old_color)
    {
        ProUtilMsgPrint("gen", "TEST %0s", "This color has been already set");
        return(0);    
    }
    status = ProCurvePersistentColorSet ((ProSolid)owner, curve, (ProColortype)opt);
    TEST_CALL_REPORT ("ProCurvePersistentColorSet()", "ProTestCurveColor()",
        status, status != PRO_TK_NO_ERROR);

    return(0);

}

/*============================================================================*\
  Function : ProTestCurveLinestyle
  Purpose  : Test ProCurveLinestyle functions
\*============================================================================*/
int ProTestCurveLinestyle (void* p_dummy, int int_dummy )
{
    ProError        status;
    ProMdl          owner;
    ProModelitem    modelitem;
    ProCurve        curve;
    ProSelection    *p_sel;
    ProLinestyle    old_style;
    
    int             n_sel, opt = 0;

    static ProUtilMenuButtons style_type[] = { 
        {"-LineStyle",  0,                          TEST_CALL_PRO_MENU_DELETE},
        {"Solid",       PRO_LINESTYLE_SOLID,        0},
        {"Dot",         PRO_LINESTYLE_DOT,          0},
        {"Centerline",  PRO_LINESTYLE_CENTERLINE,   0},
        {"Phantom",     PRO_LINESTYLE_PHANTOM,      0},
        {"",            0,                          0}
    };
    
    status = ProUtilMenuIntValueSelect (style_type, &opt);
    TEST_CALL_REPORT ("ProUtilMenuIntValueSelect()", "ProTestCurveLinestyle()",
       status, status!= PRO_TK_NO_ERROR);

    ProUtilMsgPrint("gen", "TEST %0s", "Select curve");
    status = ProSelect ((char*)"curve", 1, NULL, NULL, NULL, NULL, &p_sel,
        &n_sel);
    if (status != PRO_TK_NO_ERROR || n_sel != 1)
        return (0);

    status = ProSelectionModelitemGet (p_sel[0], &modelitem);
    TEST_CALL_REPORT ("ProSelectionModelitemGet()", "ProTestCurveLinestyle()",
        status, status != PRO_TK_NO_ERROR);

    status = ProModelitemMdlGet (&modelitem, &owner);
    TEST_CALL_REPORT ("ProModelitemMdlGet()", "ProTestCurveLinestyle()",
        status, status != PRO_TK_NO_ERROR);

    status = ProCurveInit ((ProSolid)owner, modelitem.id, &curve);
    TEST_CALL_REPORT ("ProCurveInit()", "ProTestCurveLinestyle()",
        status, status != PRO_TK_NO_ERROR);
        
    status = ProCurvePersistentLinestyleGet (curve, &old_style);
    TEST_CALL_REPORT ("ProCurvePersistentLinestyleGet()", "ProTestCurveLinestyle()",
        status, status != PRO_TK_NO_ERROR);
    if(opt == old_style)
    {
        ProUtilMsgPrint("gen", "TEST %0s", 
            "This linestyle has been already set.");
        return(0);    
    }
    status = ProCurvePersistentLinestyleSet ((ProSolid)owner, curve, (ProLinestyle)opt);
    TEST_CALL_REPORT ("ProCurvePersistentLinestyleSet()", "ProTestCurveLinestyle()",
        status, status != PRO_TK_NO_ERROR);

    return(0);

}