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


/*=================================================================*\
    Pro/Toolkit includes
\*=================================================================*/
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProMdl.h>
#include <ProMenu.h>
#include <ProDimension.h>
#include <ProSelection.h>
#include <ProGtol.h>
#include <ProFeature.h>
#include <ProMessage.h>
#include <ProWindows.h>
#include <ProAnnotation.h>
#include <ProUtil.h>
#include <ProGtolAttach.h>

/*=================================================================*\
    Application includes
\*=================================================================*/
#include "TestError.h"
#include "UtilMessage.h"
#include "UtilMenu.h"
#include "UtilTypes.h"
#include "UtilString.h"
#include "UtilCollect.h"
#include "PTApplsUnicodeUtils.h"
/*=================================================================*\
    Application macros
\*=================================================================*/
#define mnLastItem  -1
#define mnFirstItem -1

#define TestGtS_Unit 0x20 
#define TestGtS_Stat 0x10
#define TestGtS_Diam 0x08
#define TestGtS_Free 0x04
#define TestGtS_All  0x02
#define TestGtS_Tan  0x01

#define YesNoStr(a) (a ? "Yes" : "No")
#define IsMenuDone(a) ((a == mnLastItem)||(a == mnFirstItem))?(PRO_B_FALSE):(PRO_B_TRUE)

/*=================================================================*\
    Application global types
\*=================================================================*/

typedef struct  test_gtol_symbol {
    ProGtolType gtType;
    int symbols;
    char sel_param[80];
}TestGtolSymbol;

/*=================================================================*\
    Application global data
\*=================================================================*/

static ProUtilMenuButtons  mnGtolType[] ={
    {"GtolType", mnFirstItem, TEST_CALL_PRO_MENU_DELETE},
    {"Straightness",    PROGTOLTYPE_STRAIGHTNESS,   0},
    {"Flatness",        PROGTOLTYPE_FLATNESS,       0},
    {"Circular",        PROGTOLTYPE_CIRCULAR,       0},
    {"Cylindrical",     PROGTOLTYPE_CYLINDRICAL,    0},
    {"Line",            PROGTOLTYPE_LINE,           0},
    {"Surface",         PROGTOLTYPE_SURFACE,        0},
    {"Angular",         PROGTOLTYPE_ANGULAR,        0},
    {"Perpendicular",   PROGTOLTYPE_PERPENDICULAR,  0},
    {"Parallel",        PROGTOLTYPE_PARALLEL,       0},
    {"Position",        PROGTOLTYPE_POSITION,       0},
    {"Concentricity",   PROGTOLTYPE_CONCENTRICITY,  0},
    {"Symmetry",        PROGTOLTYPE_SYMMETRY,       0},
    {"Circular Runout", PROGTOLTYPE_CIRCULAR_RUNOUT,0},                                
    {"Total Highway",   PROGTOLTYPE_TOTAL_RUNOUT,   0},                                
    {"",      mnLastItem,0}};

static ProUtilMenuButtons mnGtolRefItemType[] = {
    {"RefItemType", mnFirstItem, TEST_CALL_PRO_MENU_DELETE},
    {"edge",     PROGTOLRTYPE_EDGE,  0},
    {"axis",     PROGTOLRTYPE_AXIS,  0},
    {"surface",  PROGTOLRTYPE_SURF,  0},
    {"feature",  PROGTOLRTYPE_FEAT,  0},
    {"datum",    PROGTOLRTYPE_DATUM, 0},
    {"",  mnLastItem,   0}};

static ProUtilMenuButtons mnGtolAttachType[]={
    {"GtolAttach", mnFirstItem,TEST_CALL_PRO_MENU_DELETE},
    {"Datum",          PRO_GTOL_ATTACH_DATUM,      0},
    {"Annotation",     PRO_GTOL_ATTACH_ANNOTATION,  0},
    {"Annotation Elbow",PRO_GTOL_ATTACH_ANNOTATION_ELBOW,0},
    {"Free",	       PRO_GTOL_ATTACH_FREE,   0},
    {"Leaders",        PRO_GTOL_ATTACH_LEADERS,    0},
    {"", mnLastItem, 0}};

static ProUtilMenuButtons mnGtolDrwAttachType[] = {
	{ "GtolAttach", mnFirstItem,TEST_CALL_PRO_MENU_DELETE },
	{ "Offset",         PRO_GTOL_ATTACH_OFFSET,  0 },
	{ "Make Dim",       PRO_GTOL_ATTACH_MAKE_DIM, 0 },
	{ "", mnLastItem, 0 } };

static ProUtilMenuButtons mnGtolLeaderType[]={
    {"Leader Type", mnFirstItem,TEST_CALL_PRO_MENU_DELETE},
    {"Arrow head",  PROLEADERTYPE_ARROWHEAD,  0},
    {"Dot",         PROLEADERTYPE_DOT,        0},
    {"Fille dot",   PROLEADERTYPE_FILLEDDOT,  0},
    {"No arrow",    PROLEADERTYPE_NOARROW,    0},
    {"Slash",       PROLEADERTYPE_SLASH,      0},
    {"Integral",    PROLEADERTYPE_INTEGRAL,   0},
    {"Box",         PROLEADERTYPE_BOX,        0},
    {"Filled box",  PROLEADERTYPE_FILLEDBOX,  0},
    {"Double arrow",PROLEADERTYPE_DOUBLEARROW,0},
    {"", mnLastItem, 0}};
    
static ProUtilMenuButtons mnGtolMaterialCond[]={
    {"Material Cond.", mnFirstItem, TEST_CALL_PRO_MENU_DELETE},
    {"LMC",         PRO_GTOL_SYMBOL_LMC,         0},
    {"MMC",         PRO_GTOL_SYMBOL_MMC,         0},
    {"RFC",         PRO_GTOL_SYMBOL_RFS,         0},
    {"Default RFS", PRO_GTOL_SYMBOL_DEFAULT_RFS, 0},
    {"", mnLastItem, 0}};

static ProUtilMenuButtons mnGtolReferenceType[]={
    {"Reference type", mnFirstItem, TEST_CALL_PRO_MENU_DELETE},
    {"None",      PROGTOLREFTYPE_NONE,      0},
    {"Primary",   PROGTOLREFTYPE_PRIMARY,   0},
    {"Secondary", PROGTOLREFTYPE_SECONDARY, 0},
    {"Tertiary",  PROGTOLREFTYPE_TERTIARY,  0},
    {"", mnLastItem, 0}};    

static ProUtilMenuButtons mnGtolProjzone[]={
    {"Proj. zone", mnFirstItem, TEST_CALL_PRO_MENU_DELETE},
    {"None",   PROGTOLPROJZONE_NONE,       0},
    {"Below",  PROGTOLPROJZONE_BELOWGTOL,  0},
    {"Inside", PROGTOLPROJZONE_INSIDEGTOL, 0},
    {"", mnLastItem, 0}};    

    
static TestGtolSymbol TestGtolSymbolTbl[]={
    {PROGTOLTYPE_UNKNOWN,        
     TestGtS_Stat,
     ""},     
    {PROGTOLTYPE_STRAIGHTNESS,   
     TestGtS_Stat | TestGtS_Diam | TestGtS_Free | TestGtS_Unit,
     "surface,axis,edge"},     
    {PROGTOLTYPE_FLATNESS,       
     TestGtS_Stat | TestGtS_Free | TestGtS_Unit,
     "sldface"},     
    {PROGTOLTYPE_CIRCULAR,       
     TestGtS_Stat | TestGtS_Free,
     "surface"},     
    {PROGTOLTYPE_CYLINDRICAL,    
     TestGtS_Stat | TestGtS_Free,
     "surface"},     
    {PROGTOLTYPE_LINE,           
     TestGtS_Stat | TestGtS_All  | TestGtS_Tan,
     "edge"},     
    {PROGTOLTYPE_SURFACE,        
     TestGtS_Stat | TestGtS_All  | TestGtS_Tan,
     "surface"},     
    {PROGTOLTYPE_ANGULAR,        
     TestGtS_Stat | TestGtS_Diam | TestGtS_Tan,
     "datum,surface,axis"},     
    {PROGTOLTYPE_PERPENDICULAR,  
     TestGtS_Stat | TestGtS_Diam | TestGtS_Tan | TestGtS_Unit,
     "surface,axis,datum"},     
    {PROGTOLTYPE_PARALLEL ,       
     TestGtS_Stat | TestGtS_Diam | TestGtS_Tan | TestGtS_Unit,
     "surface,axis"},     
    {PROGTOLTYPE_POSITION,       
     TestGtS_Stat | TestGtS_Diam | TestGtS_Free,
     "point,axis,datum,csys,feature,edge,curve"},     
    {PROGTOLTYPE_CONCENTRICITY,  
     TestGtS_Stat | TestGtS_Diam | TestGtS_Free,
     "axis,surface"},     
    {PROGTOLTYPE_SYMMETRY,       
     TestGtS_Stat | TestGtS_Free,
     "point,axis,datum,csys,feature,edge,curve"},     
    {PROGTOLTYPE_CIRCULAR_RUNOUT,
     TestGtS_Stat,
     "surface"},      
    {PROGTOLTYPE_TOTAL_RUNOUT,   
     TestGtS_Stat,
     "surface"},
    {(ProGtolType)-1,   -1, ""}};     
           
static char *NumeralStr[]={
    "First", 
    "Second",
    "Third"
};

static char *strDatumRef[]={
    "primary",
    "secondary",
    "tertiary"
};

/*====================================================================*\
  Function : TestGtolSymInfoGet()
  Purpose  : return in
\*====================================================================*/
ProError TestGtolSymInfoGet(ProGtolType gtType, TestGtolSymbol *info)
{
    int i=0;
    
    if(info == NULL)
        return(PRO_TK_BAD_INPUTS);
        
    while(TestGtolSymbolTbl[i].gtType!=-1)
    {
        if(TestGtolSymbolTbl[i].gtType == gtType)
        {
            memcpy(info, &TestGtolSymbolTbl[i],sizeof(TestGtolSymbol));
            return(PRO_TK_NO_ERROR);
        }
        i++;
    }
    return(PRO_TK_E_NOT_FOUND);
}

/*====================================================================*\
  Function : TestGtolSymIsEnable()
  Purpose  : If specified symbol enabled for gtol then return PRO_B_TRUE.
\*====================================================================*/
ProBoolean TestGtolSymIsEnable(ProGtolType gtType, int sym)
{
    ProError error;
    TestGtolSymbol info;
    
    error = TestGtolSymInfoGet(gtType, &info);
    if(error != PRO_TK_NO_ERROR)
        return(PRO_B_FALSE);
    
    return(((info.symbols & sym)!=0)?(PRO_B_TRUE):(PRO_B_FALSE));
}

/*====================================================================*\
  Function : TestGtolSymSelParam()
  Purpose  : Return string for ProSelect function.
\*====================================================================*/
char* TestGtolSymSelParam(ProGtolType gtType)
{
    static TestGtolSymbol	info;
    ProError			error;
    
    error = TestGtolSymInfoGet(gtType, &info);
    if(error != PRO_TK_NO_ERROR)
        return(NULL);

    return(info.sel_param);
}

/*====================================================================*\
  Function : ProArrayObjectAdd()
  Purpose  : Visit action function. Add visited object to array.
\*====================================================================*/
ProError TestGtolCollectVisit(ProGtol *gtol, ProError status, ProAppData app_data)
{
    ProError error;
    
/*--------------------------------------------------------------------*\
    Add visited object to array
\*--------------------------------------------------------------------*/
    error = ProArrayObjectAdd((ProArray*)app_data,PRO_VALUE_UNUSED,1,gtol);
    TEST_CALL_REPORT ("ProArrayObjectAdd()",
            "TestGtolCollectVisit()", error, error != PRO_TK_NO_ERROR);
        
    return(error);
}

/*====================================================================*\
  Function : TestGtolCollect()
  Purpose  : Collect all gtol in the model.
\*====================================================================*/
ProError TestGtolCollect(ProMdl mdl, ProGtol **gtol)
{
    ProGtol *tmp_gtol = NULL;
    ProError error;
    
    if((gtol==NULL)||(mdl==NULL))
        return(PRO_TK_BAD_INPUTS);

/*--------------------------------------------------------------------*\
    Alloc memory for gtol array.
\*--------------------------------------------------------------------*/
    error = ProArrayAlloc(0, sizeof(ProGtol),1,(ProArray*)&tmp_gtol);
    TEST_CALL_REPORT ("ProArrayAlloc()",
            "TestGtolCollect()", error, error != PRO_TK_NO_ERROR);
    
    if(error!=PRO_TK_NO_ERROR)
        return(error);
        
/*--------------------------------------------------------------------*\
    Visit and add all gtol from the specified model.
\*--------------------------------------------------------------------*/
    error = ProMdlGtolVisit(mdl,(ProGtolVisitAction)TestGtolCollectVisit, 
       (ProGtolFilterAction)PRO_NO_FUNCTION,(ProAppData)&tmp_gtol);        
    TEST_CALL_REPORT ("ProMdlGtolVisit()",
            "TestGtolCollect()", error, (error != PRO_TK_NO_ERROR && error != PRO_TK_E_NOT_FOUND));

/*--------------------------------------------------------------------*\
    If error then free memory.
\*--------------------------------------------------------------------*/
    if(error!=PRO_TK_NO_ERROR)
    {
        if(tmp_gtol!=NULL)
        {
            error=ProArrayFree((ProArray*)&tmp_gtol);
            TEST_CALL_REPORT ("ProArrayFree()",
                "TestGtolCollect()", error, error != PRO_TK_NO_ERROR);
            tmp_gtol = NULL;
        }
        return(error);
    }
    
    *gtol = tmp_gtol;    
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolAttachPrn()
  Purpose  : Print information about gtol placement.
\*====================================================================*/
ProError TestGtolAttachPrn(FILE *fp, ProGtol* gtol)
{
	ProGtolAttach gtolAttach;
	ProGtolAttachType attachType;
	ProModelitem datum, item;
	ProAnnotation annotation;
	ProAnnotationPlane plane;
	Pro3dPnt location;
	ProGtolLeaderAttachType leaderAttachType;
	ProSelection selection;
	ProVector offset;
    ProGtolleader *leaders;
	ProDimAttachment *dimAttach;
	ProDimSense *dimSense;
	ProDimOrient orient;

    ProLeaderType lead_type;  
    int n, i; 
    ProCharLine cname; 
    ProDimension dimension;
    ProError error;

/*--------------------------------------------------------------------*\
    Get gtol placement information
\*--------------------------------------------------------------------*/
	error = ProGtolAttachGet(gtol, &gtolAttach);
    TEST_CALL_REPORT ("ProGtolAttachGet()",
        "TestGtolAttachPrn()", error, (error != PRO_TK_NO_ERROR && error != PRO_TK_GENERAL_ERROR));
        
    if(error!=PRO_TK_NO_ERROR)    
        return(error);
        
	error = ProGtolAttachTypeGet(gtolAttach, &attachType);
	TEST_CALL_REPORT("ProGtolAttachTypeGet()",
		"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);
	ProTKFprintf(fp, (char*)"Attach type : %d\n", attachType);

	if (attachType == PRO_GTOL_ATTACH_DATUM) {
		error = ProGtolAttachOnDatumGet(gtolAttach, &datum);
		TEST_CALL_REPORT("ProGtolAttachOnDatumGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);
		ProTKFprintf(fp, (char*)"Attach datum id : %d \t type : %d\n", datum.id, datum.type);
	}
	if (attachType == PRO_GTOL_ATTACH_ANNOTATION || attachType == PRO_GTOL_ATTACH_ANNOTATION_ELBOW) {
		error = ProGtolAttachOnAnnotationGet(gtolAttach, &annotation);
		TEST_CALL_REPORT("ProGtolAttachOnAnnotationGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);
		ProTKFprintf(fp, (char*)"Attach annotation id : %d \t type : %d\n", annotation.id, annotation.type);
	}
	if (attachType == PRO_GTOL_ATTACH_FREE) {
		error = ProGtolAttachFreeGet(gtolAttach, &plane, location);
		TEST_CALL_REPORT("ProGtolAttachFreeGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

		ProTKFprintf(fp, (char*)"Attach annotation plane id : %d \t type : %d\n", plane.id, plane.type);
		ProTKFprintf(fp, (char*)"Free text point : {%lf,  %lf  %lf}\n", location[0], location[1], location[2]);
	}
	if (attachType == PRO_GTOL_ATTACH_LEADERS) {
		int nSize;
		ProSelection attachment;
		ProModelitem selItem;
		ProLeaderType leaderType;
		Pro3dPnt pnt;

		error = ProGtolAttachLeadersGet(gtolAttach, &plane, &leaderAttachType, &leaders, location);
		TEST_CALL_REPORT("ProGtolAttachLeadersGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

		error = ProArraySizeGet(leaders, &nSize);
		if (leaderAttachType == PRO_GTOL_NORMAL_LEADER)
			ProTKFprintf(fp, (char*)" GTOL_NORMAL_LEADER info :  \n");
		else if (leaderAttachType == PRO_GTOL_TANGENT_LEADER)
			ProTKFprintf(fp, (char*)" TANGENT_LEADER info :  \n");
		else if (leaderAttachType == PRO_GTOL_LEADER)
			ProTKFprintf(fp, (char*)" GTOL_LEADER info :  \n");

		for (int ii = 0; ii < nSize; ii++) {
			error = ProGtolleaderGet(leaders[ii], &leaderType, &attachment);
			TEST_CALL_REPORT("ProGtolleaderGet()",
				"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

			error = ProSelectionModelitemGet(attachment, &selItem);
			TEST_CALL_REPORT("ProSelectionModelitemGet()",
				"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

			error = ProSelectionPoint3dGet(attachment, pnt);
			TEST_CALL_REPORT("ProSelectionPoint3dGet()",
				"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

			ProTKFprintf(fp, (char*)"Leader [%d] Item id : %d  type : %d\n", ii, selItem.id, leaderType);
			ProTKFprintf(fp, (char*)"Leader [%d] Point : {%lf,  %lf  %lf}\n",ii, pnt[0], pnt[1], pnt[2]);
		}

	}
	if (attachType == PRO_GTOL_ATTACH_OFFSET) {
		error = ProGtolAttachOffsetItemGet(gtolAttach, &selection, offset);
		TEST_CALL_REPORT("ProGtolAttachOffsetItemGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

		error = ProSelectionModelitemGet(offset, &item);
		TEST_CALL_REPORT("ProSelectionModelitemGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

		ProTKFprintf(fp, (char*)"Offset item id : %d \n", item.id);
		ProTKFprintf(fp, (char*)"Free text point : {%lf,  %lf  %lf}\n", offset[0], offset[1], offset[2]);
	}
	if (attachType == PRO_GTOL_ATTACH_MAKE_DIM) {

		int attSize;
		ProModelitem attachItem;
		error = ProGtolAttachMakeDimGet(gtolAttach, &plane, &dimAttach, &dimSense, &orient, location);
		TEST_CALL_REPORT("ProGtolAttachMakeDimGet()",
			"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

		error = ProArraySizeGet(dimAttach, &attSize);
		for (int ii = 0; ii < attSize; ii++) {
			error = ProSelectionModelitemGet(dimAttach[ii][0], &attachItem);
			TEST_CALL_REPORT("ProSelectionModelitemGet()",
				"TestGtolAttachPrn()", error, error != PRO_TK_NO_ERROR);

			ProTKFprintf(fp, (char*)"Make Dim Gtol Attach [%d] item id : %d \n", ii, attachItem.id);
			ProTKFprintf(fp, (char*)"Sense [%d] type : %d sense : %d\n", ii, dimSense[ii].type, dimSense[ii].sense);
		}
		ProTKFprintf(fp, (char*)"Orient hint : %d\n", orient);
		ProTKFprintf(fp, (char*)"Location : {%lf,  %lf  %lf}\n", location[0], location[1], location[2]);
	}
    return(PRO_TK_NO_ERROR);
}

ProError TestGtolSymbolFontGet(ProGtol *gtol, ProSymbolFont *fontType)
{
	ProLine fontString;
	ProError error = PRO_TK_NO_ERROR;
	int match = 0;

	error = ProMdlDetailOptionGet(gtol->owner, L"symbol_font", fontString);
	TEST_CALL_REPORT("ProMdlDetailOptionGet()",
		"TestGtolSymbolFontGet()", error, error != PRO_TK_NO_ERROR);

	ProWstringCompare(fontString, L"LEGACY", -1, &match);
	if (match == 0)
		*fontType = PRO_FONT_LEGACY;
	else
	{
		ProWstringCompare(fontString, L"ASME", -1, &match);
		if (match == 0)
			*fontType = PRO_FONT_ASME;

		else// ISO is default choice
			*fontType = PRO_FONT_ISO;
	}

	return (error);
}
void TestWStringSubstitute(wchar_t* str, wchar_t* patten, wchar_t* replace, wchar_t** retStr)
{
	int strLen = 0;
	int patLen = 0;
	wchar_t* retStrVal = NULL;
	int replaceLen;
	int foundAt[20], count = 0;
	int offset = 0, ln = 0, i = 0, strLenCnt = 0, countCnt = 0;

	if (str == NULL || patten == NULL || replace == NULL || retStr == NULL)
		return;

	ProWstringLengthGet(str, &strLen);
	ProWstringLengthGet(patten, &patLen);
	ProWstringLengthGet(replace, &replaceLen);

	if (strLen == 0 || patLen == 0)
	{
		*retStr = str;
		return;
	}

	/* Find number of matches and indices of at which pattern starts */
	foundAt[0] = -1;
	for (i = 0; i <= strLen - patLen; i++)
	{
		int j;
		for (j = 0; j < patLen; j++)
			if (str[i + j] != patten[j])
				break;

		if (j == patLen)
		{
			foundAt[count] = i;
			foundAt[count + 1] = -1;
			count++;
		}
	}

	/* If no match found return same string */
	if (count == 0)
	{
		*retStr = str;
		return;
	}

	/* Allocate new string */
	offset = (replaceLen - patLen);
	ln = strLen + count * offset;

	retStrVal = (wchar_t*)malloc(sizeof(wchar_t) * (ln + 1));

	/* Populate new string by replacing pattern with replace string */
	for (i = 0, strLenCnt = 0, countCnt = 0; i < ln;)
	{
		if (i == foundAt[countCnt] + offset * countCnt)
		{
			for (int j = 0; j < replaceLen; j++, i++)
				retStrVal[i] = replace[j];

			strLenCnt = strLenCnt + patLen;
			countCnt++;
		}
		else
		{
			retStrVal[i] = str[strLenCnt];
			strLenCnt++;
			i++;
		}
	}

	retStrVal[ln] = '\0';
	*retStr = retStrVal;

	return;
}
void TestWStringSubstituteArray(wchar_t* str, wchar_t** patten, wchar_t** replace, wchar_t** retStr)
{
	int nSize = 0, ln = 0, ii = 0;
	wchar_t* subStr = NULL;
	wchar_t* copyInput = NULL;

	if (str == NULL || patten == NULL || replace == NULL || retStr == NULL)
		return;

	ProWstringLengthGet(str, &ln);
	subStr = (wchar_t*)malloc(sizeof(wchar_t) * (ln + 1));
	ProWstringCopy(str, subStr, -1);

	ProArraySizeGet(patten, &nSize);

	for (ii = 0; ii < nSize; ii++)
	{
		if (subStr != copyInput)
		{
			ProWstringLengthGet(subStr, &ln);
			copyInput = (wchar_t*)realloc(copyInput, sizeof(wchar_t) * (ln + 1));
			ProWstringCopy(subStr, copyInput, -1);
			free(subStr);
		}
		TestWStringSubstitute(copyInput, patten[ii], replace[ii], &subStr);
	}
	*retStr = subStr;
}

void TestGtolSymbolToString(wchar_t* str, ProSymbolFont font, wchar_t** finalStr)
{
	wchar_t** patterns = NULL;
	wchar_t** replace = NULL;
	wchar_t* symVal = NULL;
	wchar_t* ctrlChars = NULL;
	wchar_t* symb = NULL;
	ProError error;


	ProArrayAlloc(0, sizeof(wchar_t*), 1, (ProArray*)&patterns);
	ProArrayAlloc(0, sizeof(wchar_t*), 1, (ProArray*)&replace);


	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_DIAMETER, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);

	symb = L"<SYMBOL_DIAMTER>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_FREE_STATE, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_FREE_STATE>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_LMC_R, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_LMC_R>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_LMC, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_STAT_LMC>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_MMC_R, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_MMC_R>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_MMC, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_MMC>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_RFS, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_RFS>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_STAT_TOL, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_STAT_TOL>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_TANGENT_PLANE, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_TANGENT_PLANE>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_TRANSLATION, font, &symVal);
	TEST_CALL_REPORT("ProGtolSymbolStringGet()",
		"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
	error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
	symb = L"<SYMBOL_TRANSLATION>";
	error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

	if (font != PRO_FONT_LEGACY)
	{
		error = ProGtolSymbolStringGet(PRO_INDICATOR_SYMBOL_ANGULARITY, font, &symVal);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
		error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
		symb = L"<INDICATOR_ANGULARITY>";
		error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

		error = ProGtolSymbolStringGet(PRO_INDICATOR_SYMBOL_PARALLELISM, font, &symVal);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
		error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
		symb = L"<INDICATOR_PARALLEL>";
		error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

		error = ProGtolSymbolStringGet(PRO_INDICATOR_SYMBOL_PERPENDICULARITY, font, &symVal);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
		error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
		symb = L"<INDICATOR_PERPENDICULAR>";
		error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);

		error = ProGtolSymbolStringGet(PRO_INDICATOR_SYMBOL_SYMMETRY, font, &symVal);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolSymbolToString()", error, error != PRO_TK_NO_ERROR);
		error = ProWstringArrayObjectAdd(&patterns, -1, 1, &symVal);
		symb = L"<PRO_INDICATOR_SYMBOL_SYMMETRY>";
		error = ProWstringArrayObjectAdd(&replace, -1, 1, &symb);
	}

	TestWStringSubstituteArray(str, patterns, replace, finalStr);

	ProWstringproarrayFree(patterns);
	ProArrayFree((ProArray*)&replace);

}

/*====================================================================*\
  Function : TestGtolDatumRefInfo()
  Purpose  : Print information about gtol references.
\*====================================================================*/
ProError TestGtolDatumRefInfo(FILE *fp, ProGtol* gtol)
{
	wchar_t* primary = NULL;
	wchar_t* secondary = NULL;
	wchar_t* tertiary = NULL ;
	wchar_t* primSymb = NULL;
	wchar_t* secSymb = NULL;
	wchar_t* terSymb = NULL;
	ProSymbolFont fontType;
	ProError error;

/*--------------------------------------------------------------------*\
    Get the datum references for a gtol.
\*--------------------------------------------------------------------*/
	error = ProGtolDatumReferencesGet(gtol, &primary, &secondary, &tertiary);
    TEST_CALL_REPORT ("ProGtolDatumReferencesGet()",
        "TestGtolDatumRefInfo()", error, error != PRO_TK_NO_ERROR);
        
    if(error!=PRO_TK_NO_ERROR)
        return(error);
      
	error = TestGtolSymbolFontGet(gtol, &fontType);

    if(primary != NULL)
	    TestGtolSymbolToString(primary, fontType, &primSymb);
    if (secondary != NULL)
        TestGtolSymbolToString(secondary, fontType, &secSymb);
    if (tertiary != NULL)
	    TestGtolSymbolToString(tertiary, fontType, &terSymb);

    return(PRO_TK_NO_ERROR);        
}

/*====================================================================*\
  Function : TestGtolReferenceInfo()
  Purpose  : Print information about gtol references.
\*====================================================================*/
ProError TestGtolReferenceInfo(FILE *fp, ProGtol* gtolRef)
{   
	ProAnnotationReference *refs = NULL;
    ProCharLine cname;
    ProSelection ref;
    ProType type; 
    ProModelitem mdl_item;     
    ProError error;
	int i, size = 0, id;

/*--------------------------------------------------------------------*\
    Gets the item which the gtol refers to.
\*--------------------------------------------------------------------*/
	error = ProGtolReferencesGet(gtolRef, &refs);
    TEST_CALL_REPORT ("ProGtolReferencesGet()",
            "TestGtolReferenceInfo()", error, (error != PRO_TK_NO_ERROR && error != PRO_TK_BAD_INPUTS));
    
	if (error == PRO_TK_NO_ERROR && refs != NULL)
	{
		error = ProArraySizeGet((ProArray)refs, &size);
		TEST_CALL_REPORT("ProArraySizeGet()",
			"TestGtolReferenceInfo()", error, error != PRO_TK_NO_ERROR);
		for (i = 0; i < size; i++)
		{
			error = ProReferenceTypeGet(refs[i].object.reference, &type);
			TEST_CALL_REPORT("ProReferenceTypeGet()",
				"TestGtolReferenceInfo()", error, error != PRO_TK_NO_ERROR);

			ProTKFprintf(fp, (char*)"Reference type: %d\n", type);

			error = ProReferenceIdGet(refs[i].object.reference, &id);
			TEST_CALL_REPORT("ProReferenceTypeGet()",
				"TestGtolReferenceInfo()", error, error != PRO_TK_NO_ERROR);

			ProTKFprintf(fp, (char*)"Reference id: %d\n", id);
		}

	}
    return(error);
}

/*====================================================================*\
  Function : TestGtolPrintInfo()
  Purpose  : Print gtol information.
\*====================================================================*/
ProError TestGtolPrintInfo(FILE* fp, ProGtol* gtol)
{   
	ProGtolType type;
	wchar_t** values = NULL;
	wchar_t** primary = NULL;
	wchar_t** secondary = NULL;
	wchar_t** tertiary = NULL;
	wchar_t* value = NULL;
	wchar_t* finalStr = NULL;
	int nSize, ii, nGtolLine = 0;
	ProSymbolFont fontType = PRO_FONT_ASME;

    ProCharLine cname, ctype;
    ProError error;
    ProMdl mdl, owner;
    ProBoolean is_composite, overall_tol, perunit_tol,
               stat_tol, diam, free_stat, specify_height,
               all_around, tangent_plane, outside, boundary, unilateral;               
    ProGtolProfBoundIndex profile_idx;
    double val, overall_value, val_per_unit, zone_height, unit_len;
    ProGtolReferenceType r_type;
    ProName name;
    ProGtolMaterialCond matcond;   
    ProGtolProjzone projected_zone; 
    ProMdldata mdl_data;
	ProMdlName modelName;
	ProMdlExtension modelExtension;


	char printLine[PRO_LINE_SIZE];
    TestGtolSymbolFontGet(gtol, &fontType);

/*--------------------------------------------------------------------*\
    Gets gtol type
\*--------------------------------------------------------------------*/
	error = ProGtolTypeGet(gtol, &type);
    TEST_CALL_REPORT ("ProGtolTypeGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);
    
    if(error == PRO_TK_NO_ERROR)
    {
        ProUtilGtolTypeStr(type, cname);
        ProTKFprintf(fp,(char*)"Type: %s\n", cname );
    }
    
/*--------------------------------------------------------------------*\
    Gets gtol owner
\*--------------------------------------------------------------------*/
	error = ProGtolTopModelGet(gtol, &owner);
    TEST_CALL_REPORT ("ProGtolTopModelGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);
    
    error = ProMdlMdlnameGet(owner, modelName);         
    TEST_CALL_REPORT ("ProMdlMdlnameGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

    error = ProMdlExtensionGet(owner, modelExtension);         
    TEST_CALL_REPORT ("ProMdlExtensionGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

    ProWstringToString(ctype, modelExtension);
    ProWstringToString(cname, modelName);
    
    ProTKFprintf(fp, (char*)"Owner type: %s; name: %s\n", ctype, cname);
/*--------------------------------------------------------------------*\
    Gets reference, placement and datom reference info.
\*--------------------------------------------------------------------*/
	error = TestGtolReferenceInfo(fp, gtol);
    
    TestGtolAttachPrn(fp, gtol);
    
    if(!((type == PROGTOLTYPE_STRAIGHTNESS)||(type == PROGTOLTYPE_FLATNESS)||
         (type == PROGTOLTYPE_CIRCULAR)    ||(type == PROGTOLTYPE_CYLINDRICAL)))
        TestGtolDatumRefInfo(fp, gtol);

/*--------------------------------------------------------------------*\
    Check if gtol is composite then print information about composite.
\*--------------------------------------------------------------------*/
	if ((type == PROGTOLTYPE_SURFACE) || (type == PROGTOLTYPE_POSITION))
	{
		error = ProGtolCompositeGet(gtol, &values, &primary, &secondary, &tertiary);
		TEST_CALL_REPORT("ProGtolCompositeGet()",
			"TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

		if (error == PRO_TK_NO_ERROR)
		{
			ProTKFprintf(fp, (char*)"Composite Values \n");
            if (values != NULL)
                error = ProArraySizeGet(values, &nSize);
            else
                nSize = 0;
			nGtolLine = nSize;
			for (ii = 0; ii < nSize; ii++)
			{
				//if (values[ii] == NULL)
				//	continue;

				TestGtolSymbolToString(values[ii], fontType, &finalStr);
				ProWstringToString(printLine, finalStr);
				ProTKFprintf(fp, (char*)"Values [%d] : %s\n", ii, printLine);
				free(finalStr);
			}
            if (primary != NULL)
                error = ProArraySizeGet(primary, &nSize);
            else
                nSize = 0;
			if (nSize > nGtolLine)
				nGtolLine = nSize;
			if (nSize > 0)
			{
				for (ii = 0; ii < nSize; ii++)
				{
					if (primary[ii] == NULL)
						continue;

					TestGtolSymbolToString(primary[ii], fontType, &finalStr);
					ProWstringToString(printLine, finalStr);
					ProTKFprintf(fp, (char*)"Primary [%d] = \"%s\"\n", ii, printLine);
					free(finalStr);
				}
			}

            if (secondary != NULL)
                error = ProArraySizeGet(secondary, &nSize);
            else
                nSize = 0;
			if (nSize > nGtolLine)
				nGtolLine = nSize;
			if (nSize > 0)
			{
				for (ii = 0; ii < nSize; ii++)
				{
					if (secondary[ii] == NULL)
						continue;

					TestGtolSymbolToString(secondary[ii], fontType, &finalStr);
					ProWstringToString(printLine, finalStr);
					ProTKFprintf(fp, (char*)"Secondary [%d] = \"%s\"\n", ii, printLine);
					free(finalStr);
				}
			}

            if (tertiary != NULL)
                error = ProArraySizeGet(tertiary, &nSize);
            else
                nSize = 0;
			if (nSize > nGtolLine)
				nGtolLine = nSize;
			if (nSize > 0)
			{
				for (ii = 0; ii < nSize; ii++)
				{
					if (tertiary[ii] == NULL)
						continue;

					TestGtolSymbolToString(tertiary[ii], fontType, &finalStr);
					ProWstringToString(printLine, finalStr);
					ProTKFprintf(fp, (char*)"Tertiary [%d] = \"%s\"\n", ii, printLine);
					free(finalStr);
				}
			}
		}
		else {
			is_composite = PRO_B_FALSE;
			ProTKFprintf(fp, (char*)"Gtol is not composite.\n");
		}
	}
/*--------------------------------------------------------------------*\
    Gets the value of a gtol.
\*--------------------------------------------------------------------*/
	error = ProGtolValueStringGet(gtol, &value);
    TEST_CALL_REPORT ("ProGtolValueStringGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);
     
	error = TestGtolSymbolFontGet(gtol, &fontType);
	TEST_CALL_REPORT("TestGtolSymbolFontGet()",
		"TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);
    
    if (value != NULL)
    {
        TestGtolSymbolToString(value, fontType, &finalStr);
        ProWstringToString(printLine, finalStr);
        ProTKFprintf(fp, (char*)"Value String = %s\n\n", printLine);
    }

	error = ProGtolAllAroundGet(gtol, &all_around);
	TEST_CALL_REPORT("ProGtolAllAroundGet()",
		"TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

	if (error == PRO_TK_NO_ERROR)
	ProTKFprintf(fp, (char*)"All around: %s\n", YesNoStr(all_around));

	if ((type == PROGTOLTYPE_LINE) || (type == PROGTOLTYPE_SURFACE))
	{
		error = ProGtolBoundaryDisplayGet(gtol, &boundary);
		TEST_CALL_REPORT("ProGtoldataProfBoundaryGet()",
			"TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

		if (error == PRO_TK_NO_ERROR)
			ProTKFprintf(fp, (char*)"Boundary: %s\n", YesNoStr(boundary));
	}

	if ((type == PROGTOLTYPE_LINE) || (type == PROGTOLTYPE_SURFACE))
	{
		error = ProGtolUnilateralGet(gtol, &unilateral, &outside);
		TEST_CALL_REPORT("ProGtoldataProfBoundaryGet()",
			"TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

		if (error == PRO_TK_NO_ERROR)
			ProTKFprintf(fp, (char*)"Unilateral: %s   Outside : %s\n", YesNoStr(unilateral), YesNoStr(outside));
	}
    return(PRO_TK_NO_ERROR);        
}

/*====================================================================*\
  Function : TestMdlGtolShow()
  Purpose  : Show all gtol in the specified model .
\*====================================================================*/
ProError TestMdlGtolShow(ProMdl mdl)
{
    ProFeature *features = NULL;
    ProError error;
    int n, i;
    ProSelection sel;

/*--------------------------------------------------------------------*\
    Collect all features in the specified model.
\*--------------------------------------------------------------------*/
    error = ProUtilCollectSolidFeaturesWithFilter((ProSolid)mdl, (ProFeatureFilterAction)PRO_TK_NO_ERROR, &features);
    if((error!=PRO_TK_NO_ERROR)||(features == NULL))
        return(PRO_TK_E_NOT_FOUND);
    
    error= ProArraySizeGet((ProArray)features, &n);
    TEST_CALL_REPORT ("ProArraySizeGet()",
            "TestMdlGtolShow()", error, error != PRO_TK_NO_ERROR);
    
    if((error!=PRO_TK_NO_ERROR)||(n<=0))
        return(PRO_TK_E_NOT_FOUND);
        
/*--------------------------------------------------------------------*\
    Show gtol for each feature.
\*--------------------------------------------------------------------*/
    for(i=0; i<n; i++)
    {
        error = ProSelectionAlloc(NULL,(ProModelitem*)&features[i], &sel);
        TEST_CALL_REPORT ("ProSelectionAlloc()",
            "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);
        
        error = ProFeatureParamsDisplay(sel, PRO_GTOL_PARAM);  
        TEST_CALL_REPORT ("ProFeatureParamsDisplay()",
            "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);
    
        error = ProSelectionFree(&sel);
        TEST_CALL_REPORT ("ProSelectionFree()",
            "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);
    }    

/*--------------------------------------------------------------------*\
    Free allocated memory.
\*--------------------------------------------------------------------*/
    error = ProArrayFree((ProArray*)&features);
    TEST_CALL_REPORT ("ProArrayFree()",
        "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);
    
    return(PRO_TK_NO_ERROR);    
}

/*====================================================================*\
  Function : TestGtolInfoSel()
  Purpose  : Show information for selected gtol.
\*====================================================================*/
ProError TestGtolInfoSel(ProMdl model)
{
    ProError error;
    ProGtol gtol;
    int n_sel;
    ProGtoldata data;
    char file_name[]="Gtol.info";
    FILE *fp;      
    ProName wstr;
    ProSelection *sel;

/*--------------------------------------------------------------------*\
    Show all gtols in the specified model
\*--------------------------------------------------------------------*/
    error = TestMdlGtolShow(model);        
    if(error!=PRO_TK_NO_ERROR)
        return(error);
            
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select gtol.");

/*--------------------------------------------------------------------*\
    Select gtol get information about it, and show this information.
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"gtol", 1,NULL, NULL, NULL, NULL, &sel, &n_sel); 
    TEST_CALL_REPORT ("ProSelect()",
            "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);
    
    if((error!=PRO_TK_NO_ERROR)||(n_sel<0))
        return(PRO_TK_E_NOT_FOUND);    
        
    error = ProSelectionModelitemGet(sel[0],(ProModelitem*)&gtol);
    TEST_CALL_REPORT ("ProSelectionModelitemGet()",
            "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);

    if ((fp = PTApplsUnicodeFopen(file_name, "w")) == NULL)
    {
	ProTKPrintf((char*)"Cannot open output file\n");
	return ((ProError)-1);
    }         
    
    ProTKFprintf(fp,(char*)"\t\tGeometric Tolerance\n");
    TestGtolPrintInfo(fp,&gtol);
    fclose(fp);

    error = ProInfoWindowDisplay(ProStringToWstring(wstr, file_name), NULL, NULL);    
    TEST_CALL_REPORT ("ProInfoWindowDisplay()",
        "TestGtolInfoSel()", error, error != PRO_TK_NO_ERROR);

    return(error);
}

/*====================================================================*\
  Function : TestGtolInfoAll()
  Purpose  : Show information about all gtols in the model.
\*====================================================================*/
ProError TestGtolInfoAll(ProMdl model)
{
  ProError error;
  ProGtoldata data;
  ProGtol *gtol=NULL;
  int i, n=0;
  char file_name[]="GtolAll.info";
  FILE *fp;  
  ProName wstr;
  ProMdldata mdl_data;
  ProCharLine cname, ctype;
  ProMdlName modelName;
  ProMdlExtension modelExtension;

  if(model == NULL)
    {
      error = ProMdlCurrentGet(&model);
      TEST_CALL_REPORT ("ProMdlCurrentGet()",
			"TestGtolInfoAll()", error, error != PRO_TK_NO_ERROR);
            
      if(error!=PRO_TK_NO_ERROR)
	return(error);    
    }       
     
    error = ProMdlMdlnameGet(model, modelName);         
    TEST_CALL_REPORT ("ProMdlMdlnameGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

    error = ProMdlExtensionGet(model, modelExtension);         
    TEST_CALL_REPORT ("ProMdlExtensionGet()",
            "TestGtolPrintInfo()", error, error != PRO_TK_NO_ERROR);

    ProWstringToString(ctype, modelExtension);
    ProWstringToString(cname, modelName);

/*--------------------------------------------------------------------*\
    Collect all gtols from the current model.
\*--------------------------------------------------------------------*/
  error = TestGtolCollect(model, &gtol);
  if(error!=PRO_TK_NO_ERROR)
    return(error);

/*--------------------------------------------------------------------*\
    Get gtols count.
\*--------------------------------------------------------------------*/
  if (gtol != NULL)
  {
      error = ProArraySizeGet((ProArray)gtol, &n);
      TEST_CALL_REPORT("ProArraySizeGet()",
          "TestGtolInfoAll()", error, (error != PRO_TK_NO_ERROR && error != PRO_TK_BAD_INPUTS));
  }
    
  if((error!=PRO_TK_NO_ERROR)||(n<=0))
    return(error);
        
  if ((fp = PTApplsUnicodeFopen(file_name, "w")) == NULL)
    {
      ProTKPrintf((char*)"Cannot open output file\n");
      return ((ProError)-1);
    }
    
  ProTKFprintf(fp, (char*)"Model Name: %s; Type: %s\n", cname, ctype);	  
        
/*--------------------------------------------------------------------*\
    Print information about each gtol.
\*--------------------------------------------------------------------*/
  for(i=0; i<n; i++)
    {
      ProTKFprintf(fp,(char*)"%d Geometric Tolerance\n",i);
	  TestGtolPrintInfo(fp, &gtol[i]);
      ProTKFprintf(fp,(char*)"\n");
    }

/*--------------------------------------------------------------------*\
    Close output file, free memory and show information.
\*--------------------------------------------------------------------*/
  fclose(fp);

  error = ProArrayFree((ProArray*)&gtol);
  TEST_CALL_REPORT ("ProArrayFree()",
		    "TestGtolInfoAll()", error, error != PRO_TK_NO_ERROR);

  error = ProInfoWindowDisplay(ProStringToWstring(wstr, file_name), NULL, NULL);    
  TEST_CALL_REPORT ("ProInfoWindowDisplay()",
		    "TestGtolInfoAll()", error, error != PRO_TK_NO_ERROR);

  return(error);
}

/*====================================================================*\
  Function : TestGtolDeleteAll()
  Purpose  : Delete all gtol from the model.
\*====================================================================*/
ProError TestGtolDeleteAll(ProMdl model)
{
    ProError error;
    ProGtol *gtol;
    int i, n;
    
/*--------------------------------------------------------------------*\
    Collect all gtol in the specified model.
\*--------------------------------------------------------------------*/
    error = TestGtolCollect(model, &gtol);
    if(error!=PRO_TK_NO_ERROR)
        return(error);
        
    error = ProArraySizeGet((ProArray)gtol, &n);
    TEST_CALL_REPORT ("ProArraySizeGet()",
            "TestGtolGet()", error, error != PRO_TK_NO_ERROR);
    
    if((error!=PRO_TK_NO_ERROR)||(n<=0))
        return(error);

/*--------------------------------------------------------------------*\
    Delete gtols.
\*--------------------------------------------------------------------*/
    for(i=0; i<n; i++)
    {
        error = ProGtolDelete(&gtol[i]);
        TEST_CALL_REPORT ("ProGtolDelete()",
            "TestGtolDeleteAll()", error, error != PRO_TK_NO_ERROR);
    }

    if(gtol!=NULL)
    {
        error = ProArrayFree((ProArray*)&gtol);
        TEST_CALL_REPORT ("ProArrayFree()",
            "TestGtolDeleteAll()", error, error != PRO_TK_NO_ERROR);
    }            

    error = ProWindowRepaint(PRO_VALUE_UNUSED);
    TEST_CALL_REPORT ("ProWindowRepaint()",
        "TestGtolDeleteAll()", error, error != PRO_TK_NO_ERROR);
        
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolModify()
  Purpose  : Change gtol value in all gtols.
\*====================================================================*/
ProError TestGtolModify(ProMdl model)
{
    ProError error;
    ProGtol *gtol;
    int i, n, ch;
	double value;
	wchar_t* valueStr = NULL;
    ProBoolean tolerance;
    ProName  wname; 
	char cValue[PRO_LINE_SIZE];
	ProPath path;

/*--------------------------------------------------------------------*\
    Collect all gtols in the specified model.
\*--------------------------------------------------------------------*/
    error = TestGtolCollect(model, &gtol);
    if(error!=PRO_TK_NO_ERROR)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Gtol is not found.");
        return(error);
    }
        
    error = ProArraySizeGet((ProArray)gtol, &n);
    TEST_CALL_REPORT ("ProArraySizeGet()",
            "TestGtolGet()", error, error != PRO_TK_NO_ERROR);
    if(n<=0)
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"The current model have't any gtol.");
    
    if((error!=PRO_TK_NO_ERROR)||(n<=0))
        return(error);

/*--------------------------------------------------------------------*\
    Prompt user to input new gtol value.
\*--------------------------------------------------------------------*/
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input new gtol value:");    
    if(ProMessageDoubleRead(NULL, &value)!=PRO_TK_NO_ERROR)
    {
		error = ProArrayFree((ProArray*)&gtol);
        TEST_CALL_REPORT ("ProGtoldataFree()",
            "TestGtolModify()", error, error != PRO_TK_NO_ERROR);
    
        return(PRO_TK_BAD_INPUTS);
    }  
	sprintf(cValue, "%lf", value);
	ProStringToWstring(path, cValue);
   
/*--------------------------------------------------------------------*\
    Change value in the each gtol
\*--------------------------------------------------------------------*/
    for(i=0; i<n; i++)
    {
        error = ProGtolValueStringSet(&gtol[i], path);
        TEST_CALL_REPORT ("ProGtolValueStringSet()",
            "TestGtolModify()", error, error != PRO_TK_NO_ERROR);    
    }          
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolSelType()
  Purpose  : Menu for select gtol type.
\*====================================================================*/
int TestGtolSelType()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please select gtol type.");    
    error = ProUtilMenuIntValueSelect(mnGtolType, &n);

    return((error == PRO_TK_NO_ERROR)?(n):error);
}

/*====================================================================*\
  Function : TestGtolSelRefItemType()
  Purpose  : Menu for select gtol type reference type.
\*====================================================================*/
int TestGtolSelRefItemType()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose refernce type.");    
    error = ProUtilMenuIntValueSelect(mnGtolRefItemType, &n);

    return((error == PRO_TK_NO_ERROR)?(n):error);
}

/*====================================================================*\
  Function : TestGtolSelAttachType()
  Purpose  : Menu for select gtol type Attach type.
\*====================================================================*/
int TestGtolSelAttachType()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose Attach type.");    
    error = ProUtilMenuIntValueSelect(mnGtolAttachType, &n);

    return((error == PRO_TK_NO_ERROR)?(n):-1);
}

/*====================================================================*\
Function : TestGtolDrwSelAttachType()
Purpose  : Menu for select gtol type Attach type.
\*====================================================================*/
int TestGtolDrwSelAttachType()
{
	int n;
	ProError error;

	ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose Attach type.");
	error = ProUtilMenuIntValueSelect(mnGtolDrwAttachType, &n);

	return((error == PRO_TK_NO_ERROR) ? (n) : -1);
}
/*====================================================================*\
  Function : TestGtolSelLeaderType()
  Purpose  : Menu for select gtol type Leader type.
\*====================================================================*/
int TestGtolSelLeaderType()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose leader type.");    
    error = ProUtilMenuIntValueSelect(mnGtolLeaderType, &n);

    return((error == PRO_TK_NO_ERROR)?(n):error);
}

/*====================================================================*\
  Function : TestGtolSelMaterialCond()
  Purpose  : Menu for select material condition.
\*====================================================================*/
int TestGtolSelMaterialCond()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose material condition.");    
    error = ProUtilMenuIntValueSelect(mnGtolMaterialCond, &n);

    return((error == PRO_TK_NO_ERROR)?(n):error);
}

/*====================================================================*\
  Function : TestGtolSelReferenceType()
  Purpose  : Menu for select reference type.
\*====================================================================*/
int TestGtolSelReferenceType()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose reference type.");    
    error = ProUtilMenuIntValueSelect(mnGtolReferenceType, &n);

    return((error == PRO_TK_NO_ERROR)?(n):error);
}

/*====================================================================*\
  Function : TestGtolSelProjzone()
  Purpose  : Menu for select projected zone type.
\*====================================================================*/
int TestGtolSelProjzone()
{
    int n;
    ProError error;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please choose projected zone type");
    error = ProUtilMenuIntValueSelect(mnGtolProjzone, &n);

    return((error == PRO_TK_NO_ERROR)?(n):error);
}

/*====================================================================*\
  Function : TestGtolAttachSet()
  Purpose  : Set gtol placement.
\*====================================================================*/
ProError TestGtolAttachSet(ProMdl mdl, ProGtolAttach* attach)
{
    ProGtol *gtol = NULL;
	ProMdlType mdlType;
	ProGtolAttachType attachtype = PRO_GTOL_ATTACH_DATUM;
    ProLeaderType ldr_type;
    ProPoint3d location;
    ProGtolleader *leaders = NULL;    
    ProSelection *sel;
    ProDimension dimension;   
    ProMouseButton btn;    
    int i, n_sel, n_leader, n_gtol, n, range[2];
    ProBoolean IsComplete = PRO_B_FALSE;
    ProError error;
    ProGtolRefItemType type;
    ProSelection reference;

	ProAnnotationReference *refs = NULL;
	ProSelection *planeSels = 0;
	int numSels = 0;
	ProVector planeVec = { 1.00,1.00,1.00 };
	ProAnnotationPlane annotPlane;
/*--------------------------------------------------------------------*\
    Select gtol placement type.
\*--------------------------------------------------------------------*/
	error = ProMdlTypeGet(mdl, &mdlType);

	if(mdlType == PRO_MDL_PART || mdlType == PRO_MDL_ASSEMBLY)
		attachtype = (ProGtolAttachType)TestGtolSelAttachType();
	else if (mdlType == PRO_MDL_DRAWING)
		attachtype = (ProGtolAttachType)TestGtolDrwSelAttachType();

    if(attachtype == -1)
        return(PRO_TK_BAD_INPUTS);

    if(IsMenuDone(attachtype) == PRO_B_FALSE)
        return(PRO_TK_BAD_INPUTS);
  
	if (attachtype == PROGTOLPTYPE_FREENOTE || attachtype == PRO_GTOL_ATTACH_LEADERS || attachtype == PRO_GTOL_ATTACH_MAKE_DIM)
	{
		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please select annotation plane");

		error = ProSelect((char*)"datum", 1, NULL, NULL, NULL, NULL, &planeSels, &numSels);
		TEST_CALL_REPORT("ProSelect()", "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);

		if (error != PRO_TK_NO_ERROR)
			return error;

		error = ProAnnotationplaneCreate(planeSels[0], planeVec, &annotPlane);
		TEST_CALL_REPORT("ProAnnotationplaneCreate()", "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);
	}
//--------------------------------------------------------------------
//   Select the dimension to attach to gtol
//--------------------------------------------------------------------
        if((attachtype == PRO_GTOL_ATTACH_ANNOTATION) ||
           (attachtype == PRO_GTOL_ATTACH_ANNOTATION_ELBOW))
        {
            error = ProSelect((char*)"dimension",1, NULL, NULL, NULL, NULL, &sel, &n_sel);
            TEST_CALL_REPORT ("ProSelect()",
                "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR); 
            
            if((error!=PRO_TK_NO_ERROR)||(n_sel<=0))
                return(PRO_TK_E_NOT_FOUND);
                
            error = ProSelectionModelitemGet(sel[0],(ProModelitem*)&dimension);    
            TEST_CALL_REPORT ("ProSelectionModelitemGet()",
                "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR); 

			error = ProGtolAttachOnAnnotationSet(*attach, (ProAnnotation *)&dimension, PRO_B_FALSE);
			TEST_CALL_REPORT("ProGtolAttachOnAnnotationSet()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);
        }
		/*--------------------------------------------------------------------*\
		Setup location of the gtol label. (for valid placement types)
		\*--------------------------------------------------------------------*/
		if ((attachtype == PRO_GTOL_ATTACH_FREE) ||
			(attachtype == PRO_GTOL_ATTACH_LEADERS) ||
			(attachtype == PRO_GTOL_ATTACH_OFFSET) ||
			(attachtype == PRO_GTOL_ATTACH_MAKE_DIM))
		{
			ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please select place location");

			error = ProMousePickGet(PRO_LEFT_BUTTON, &btn, location);

			TEST_CALL_REPORT("ProMousePickGet()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);

			if (error != PRO_TK_NO_ERROR)
				return(error);

			if (attachtype == PRO_GTOL_ATTACH_FREE) {
				error = ProGtolAttachFreeSet(*attach, &annotPlane, location);
				TEST_CALL_REPORT("ProGtolAttachFreeSet()",
					"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);
			}
		}
/*--------------------------------------------------------------------*\
    Create ProArray of leader structures. Contains only a single
    leader if the type is PROGTOLPTYPE_TANLEADER or PROGTOLPTYPE_NORMLEADER
\*--------------------------------------------------------------------*/
        if(attachtype == PRO_GTOL_ATTACH_LEADERS)
        {
            ldr_type = (ProLeaderType)TestGtolSelLeaderType();
            
            if(IsMenuDone(ldr_type) == PRO_B_FALSE)
                return(PRO_TK_BAD_INPUTS);
                
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please select items for attach");
            
            error = ProSelect((char*)"surface,axis,datum,csys,edge", 
              (attachtype == PRO_GTOL_ATTACH_LEADERS)?(PRO_VALUE_UNUSED):(1),
              NULL, NULL, NULL, NULL, &sel, &n_leader);  
            TEST_CALL_REPORT ("ProSelect()",
                "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR); 
            
            if((error != PRO_TK_NO_ERROR)||(n_leader<=0))
                return(PRO_TK_E_NOT_FOUND);
                
            error = ProArrayAlloc(n_leader, sizeof(ProGtolleader),1, (ProArray*)&leaders);
            TEST_CALL_REPORT ("ProArrayAlloc()",
                "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR); 
            
            if(error != PRO_TK_NO_ERROR)
                return(error);
                
            for(i=0; i<n_leader; i++)
            {         
                error = ProGtolleaderAlloc(ldr_type, sel[i], &leaders[i]);
                TEST_CALL_REPORT ("ProGtolleaderAlloc()",
                    "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR); 
            }
			error = ProGtolAttachLeadersSet(*attach, &annotPlane, PRO_GTOL_NORMAL_LEADER, leaders, location);
			TEST_CALL_REPORT("ProGtolAttachLeadersSet()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);
        }      
/*--------------------------------------------------------------------*\
    Select gtol to attach to offset.
\*--------------------------------------------------------------------*/
		if (attachtype == PRO_GTOL_ATTACH_OFFSET)
		{
			ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please select ref for attach");

			error = ProSelect((char*)"dimension, note",1,
				NULL, NULL, NULL, NULL, &sel, &n_leader);
			TEST_CALL_REPORT("ProSelect()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);

			if ((error != PRO_TK_NO_ERROR) || (n_leader <= 0))
				return(PRO_TK_E_NOT_FOUND);

			error = ProGtolAttachOffsetItemSet(*attach, sel[0], location);
			TEST_CALL_REPORT("ProGtolAttachOffsetItemSet()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);
		}

		if (attachtype == PRO_GTOL_ATTACH_MAKE_DIM)
		{
			ProDimAttachment *dimAttachs = NULL;
			ProDimSense *sense = NULL;

			error = ProArrayAlloc(1, sizeof(ProDimAttachment), 1, (ProArray*)&dimAttachs);
			error = ProArrayAlloc(1, sizeof(ProDimSense), 1, (ProArray*)&sense);
			sense[0].type = PRO_DIM_SNS_TYP_NONE;


			if (IsMenuDone(ldr_type) == PRO_B_FALSE)
				return(PRO_TK_BAD_INPUTS);

			ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Please select edge for make Dim");

			error = ProSelect((char*)"edge", 1,
				NULL, NULL, NULL, NULL, &sel, &n_leader);
			TEST_CALL_REPORT("ProSelect()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);

			dimAttachs[0][0] = sel[0];
			dimAttachs[0][1] = NULL;

			if ((error != PRO_TK_NO_ERROR) || (n_leader <= 0))
				return(PRO_TK_E_NOT_FOUND);

			error = ProGtolAttachMakeDimSet(*attach, &annotPlane, dimAttachs, sense, PRO_DIM_ORNT_HORIZ, location);
			TEST_CALL_REPORT("ProGtolAttachOffsetItemSet()",
				"TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);
		}	  
/*--------------------------------------------------------------------*\
    Free memory
\*--------------------------------------------------------------------*/
       
        if(leaders != NULL){
            for(i=0; i<n_leader; i++)
            { 
                error = ProGtolleaderFree(&leaders[i]);
                TEST_CALL_REPORT ("ProGtolleaderFree()",
                    "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);    
            }
            error = ProArrayFree((ProArray*)&leaders);
            TEST_CALL_REPORT ("ProArrayFree()",
                    "TestGtolAttachSet()", error, error != PRO_TK_NO_ERROR);    
        }        
    return(error);    
}

/*====================================================================*\
  Function : TestGtoldatumrefSet()
  Purpose  : Setup datum references for specified gtol.
\*====================================================================*/
ProError TestGtoldatumrefSet(ProGtol*  gtol)
{
    ProError error;
    ProBoolean IsComplete = PRO_B_FALSE;
	ProGtolSymbol symbol;
	ProSymbolFont fontType;
	wchar_t* primary;
	wchar_t* secondary;
	wchar_t* tertiary;
	wchar_t* symStr = NULL;
	ProGtolType type;

	double value = 0;
	char cValue[PRO_LINE_SIZE];
	ProPath path;

	error = ProGtolTypeGet(gtol, &type);
	TEST_CALL_REPORT("ProGtolTypeGet()",
		"TestGtolPerUnitSet()", error, error != PRO_TK_NO_ERROR);

	if (error != PRO_TK_NO_ERROR)
		return(error);

	if ((type == PROGTOLTYPE_STRAIGHTNESS) || (type == PROGTOLTYPE_FLATNESS) ||
		(type == PROGTOLTYPE_CIRCULAR) || (type == PROGTOLTYPE_CYLINDRICAL))
		return(PRO_TK_NO_ERROR);
/*--------------------------------------------------------------------*\
    Setup basic datum
\*--------------------------------------------------------------------*/
		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Choise material condition");
		symbol = (ProGtolSymbol)TestGtolSelMaterialCond();

		error = TestGtolSymbolFontGet(gtol, &fontType);

		error = ProGtolSymbolStringGet(symbol, fontType, &symStr);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtoldatumrefSet()", error, error != PRO_TK_NO_ERROR);

		error = ProGtolDatumReferencesGet(gtol, &primary, &secondary, &tertiary);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtoldatumrefSet()", error, error != PRO_TK_NO_ERROR);

		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Set primary datum reference ?(y/n):");

		if (ProUtilYesnoGet((char*)"Yes") == 1)
		{
			ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input primary datum reference value:");
			ProMessageDoubleRead(NULL, &value);
			sprintf(cValue, "%lf", value);

			ProStringToWstring(path, cValue);
			ProWstringConcatenate(path, primary, PRO_VALUE_UNUSED);
			ProWstringConcatenate(symStr, primary, PRO_VALUE_UNUSED);
		}

		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Set secondary datum reference ?(y/n):");

		if (ProUtilYesnoGet((char*)"Yes") == 1)
		{
			ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input secondary datum reference value:");
			ProMessageDoubleRead(NULL, &value);
			sprintf(cValue, "%lf", value);

			ProStringToWstring(path, cValue);
			ProWstringConcatenate(path, secondary, PRO_VALUE_UNUSED);
			ProWstringConcatenate(symStr, secondary, PRO_VALUE_UNUSED);
		}

		ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Set tertiary datum reference ?(y/n):");

		if (ProUtilYesnoGet((char*)"Yes") == 1)
		{
			ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input tertiary datum reference value:");
			ProMessageDoubleRead(NULL, &value);
			sprintf(cValue, "%lf", value);

			ProStringToWstring(path, cValue);
			ProWstringConcatenate(path, tertiary, PRO_VALUE_UNUSED);
			ProWstringConcatenate(symStr, tertiary, PRO_VALUE_UNUSED);
		}
	error = ProGtolDatumReferencesSet(gtol, primary, secondary, tertiary);
    TEST_CALL_REPORT ("ProGtolDatumReferencesSet()",
        "TestGtoldatumrefSet()", error, error != PRO_TK_NO_ERROR);    
    
    IsComplete = ((error == PRO_TK_NO_ERROR)||(PRO_TK_CANT_MODIFY == error))?
            (PRO_B_TRUE):(PRO_B_FALSE);

   return((IsComplete == PRO_B_TRUE)?(PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR));
}

/*====================================================================*\
  Function : TestGtolCompositeSet()
  Purpose  : Setup gtol composite property.
\*====================================================================*/
ProError TestGtolCompositeSet(ProGtol* gtol)
{
    ProGtolReferenceType type;
    ProError error;
    ProBoolean is_composite = PRO_B_FALSE;  
    ProGtolType gtype;
	double value = 0;
	char cValue[PRO_LINE_SIZE];
	ProPath path;

	error = ProGtolTypeGet(gtol, &gtype);
	TEST_CALL_REPORT("ProGtolTypeGet()",
		"TestGtolPerUnitSet()", error, error != PRO_TK_NO_ERROR);

	if (error != PRO_TK_NO_ERROR)
		return(error);

	if (!((gtype == PROGTOLTYPE_SURFACE) || (gtype == PROGTOLTYPE_POSITION)))
		return(PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Prompt user for setup gtol composite property.    
\*--------------------------------------------------------------------*/
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Composite tolerance ?(y/n):");    

    if (ProUtilYesnoGet((char*)"Yes") == 1)
    {
        is_composite = PRO_B_TRUE;
        type = (ProGtolReferenceType)TestGtolSelReferenceType();
        if (IsMenuDone(type) == PRO_B_FALSE)
            return(PRO_TK_BAD_INPUTS);
        
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input composite tolerance value:");    
		ProMessageDoubleRead(NULL, &value);
		sprintf(cValue, "%lf", value);

		ProStringToWstring(path, cValue);
	error = ProGtolCompositeSet(gtol, PRO_VALUE_UNUSED, path, NULL, NULL, NULL);
        TEST_CALL_REPORT("ProGtolCompositeSet()",
        "TestGtolCompositeSet()", error, error != PRO_TK_NO_ERROR);    
        
        if (error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
    }           	    
        
    return(error);
}

/*====================================================================*\
  Function : TestGtolValueSet()
  Purpose  : Setup gtol value.
\*====================================================================*/
ProError TestGtolValueSet(ProGtol* gtol)
{
	double value = 0;
	char cValue[PRO_LINE_SIZE];
	ProPath path; 
    ProError error; 

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input overall tolerance value:");    
	ProMessageDoubleRead(NULL, &value);
	sprintf(cValue, "%lf", value);

	ProStringToWstring(path, cValue);
/*--------------------------------------------------------------------*\
    Call Pro/Toolkit function for setup gtol value.
\*--------------------------------------------------------------------*/
	error = ProGtolValueStringSet(gtol, path);
    TEST_CALL_REPORT ("ProGtolValueStringSet()",
        "TestGtolValueSet()", error, error != PRO_TK_NO_ERROR);    
        
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
    
    return(error);
}

/*====================================================================*\
  Function : TestGtolPerUnitSet()
  Purpose  : Set the per unit tolerance of a gtol.
\*====================================================================*/
ProError TestGtolPerUnitSet(ProGtol* gtol)
{
    ProError  error;
    ProBoolean  perunit_tolerance = PRO_B_FALSE;
	double value;
    ProPath value_per_unit, unit_area_or_length;
	char cValue[PRO_LINE_SIZE], aValue[PRO_LINE_SIZE];
	ProPath path; 

    perunit_tolerance = PRO_B_TRUE;
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input per unit tolerance value:");  
	ProMessageDoubleRead(NULL, &value);
	sprintf(cValue, "%lf", value);

	ProStringToWstring(value_per_unit, cValue);
	        
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Input unit area, or length:");    
	ProMessageDoubleRead(NULL, &value);
	sprintf(aValue, "%lf", value);

	ProStringToWstring(unit_area_or_length, aValue);

	ProWstringConcatenate(value_per_unit, path, PRO_VALUE_UNUSED);
	ProWstringConcatenate(L"/", path, PRO_VALUE_UNUSED);
	ProWstringConcatenate(unit_area_or_length, path, PRO_VALUE_UNUSED);

    error = ProGtolCompositeSet(gtol, PRO_VALUE_UNUSED, path, NULL, NULL, NULL);
	TEST_CALL_REPORT ("ProGtolCompositeSet()",
	    "TestGtolPerUnitSet()", error, error != PRO_TK_NO_ERROR); 

    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          

    return(error);
}

/*====================================================================*\
  Function : TestGtolStatTolSet()
  Purpose  : Set whether a gtol shows the statistical tolerance symbol.
\*====================================================================*/
ProError TestGtolStatTolSet(ProGtol* gtol)
{
    ProBoolean statistic_tolerance;
    ProError error = PRO_TK_GENERAL_ERROR;
	wchar_t* valString = NULL;
	ProSymbolFont symbFont;
	wchar_t* symbolStr = NULL;
    
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Show the statistical tolerance symbol ? (y/n):");    

    statistic_tolerance = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);

    if (!statistic_tolerance)
        return PRO_TK_NO_ERROR;

	if (statistic_tolerance)
	{
		error = ProGtolValueStringGet(gtol, &valString);
		TEST_CALL_REPORT("ProGtolValueStringGet()",
			"TestGtolStatTolSet()", error, error != PRO_TK_NO_ERROR);

		error = TestGtolSymbolFontGet(gtol, &symbFont);

		error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_STAT_TOL, symbFont, &symbolStr);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolStatTolSet()", error, error != PRO_TK_NO_ERROR);

		ProWstringConcatenate(symbolStr, valString, PRO_VALUE_UNUSED);

		error = ProGtolValueStringSet(gtol, valString);
		TEST_CALL_REPORT("ProGtolValueStringSet()",
			"TestGtolStatTolSet()", error, error != PRO_TK_NO_ERROR);
	}
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
        
    return(error);
}

/*====================================================================*\
  Function : TestGtolDiameterSet()
  Purpose  : Set whether a gtol shows the diameter tolerance symbol.
\*====================================================================*/
ProError TestGtolDiameterSet(ProGtol* gtol)
{
    ProError error = PRO_TK_GENERAL_ERROR;
    ProBoolean diameter;
	wchar_t* valString = NULL;
	ProSymbolFont symbFont;
	wchar_t* symbolStr = NULL;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Show the diameter tolerance symbol ? (y/n):");    
    diameter = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);
    
	if (diameter)
	{
		error = ProGtolValueStringGet(gtol, &valString);
		TEST_CALL_REPORT("ProGtolValueStringGet()",
			"TestGtolDiameterSet()", error, error != PRO_TK_NO_ERROR);

		error = TestGtolSymbolFontGet(gtol, &symbFont);

		error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_DIAMETER, symbFont, &symbolStr);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolDiameterSet()", error, error != PRO_TK_NO_ERROR);

		ProWstringConcatenate(symbolStr, valString, PRO_VALUE_UNUSED);

		error = ProGtolValueStringSet(gtol, valString);
		TEST_CALL_REPORT("ProGtolValueStringSet()",
			"TestGtolDiameterSet()", error, error != PRO_TK_NO_ERROR);
	}
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
   
    return(error);
}

/*====================================================================*\
  Function : TestGtolFreeStateSet()
  Purpose  : Set whether a gtol shows the free state symbol.
\*====================================================================*/
ProError TestGtolFreeStateSet(ProGtol* gtol)
{
    ProError error = PRO_TK_GENERAL_ERROR;
    ProBoolean free_state;
    wchar_t* valString = NULL;
	ProSymbolFont symbFont;
	wchar_t* symbolStr = NULL;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Show free state symbol ? (y/n):");    
    free_state = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);

    if (!free_state)
        return PRO_TK_NO_ERROR;

	if (free_state) 
	{
		error = ProGtolValueStringGet(gtol, &valString);
		TEST_CALL_REPORT("ProGtolValueStringGet()",
			"TestGtolFreeStateSet()", error, error != PRO_TK_NO_ERROR);

		error = TestGtolSymbolFontGet(gtol, &symbFont);

		error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_FREE_STATE, symbFont, &symbolStr);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolFreeStateSet()", error, error != PRO_TK_NO_ERROR);

		ProWstringConcatenate(symbolStr, valString, PRO_VALUE_UNUSED);

		error = ProGtolValueStringSet(gtol, valString);
		TEST_CALL_REPORT("ProGtolValueStringSet()",
			"TestGtolFreeStateSet()", error, error != PRO_TK_NO_ERROR);
	}
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
   
    return(error);
}

/*====================================================================*\
  Function : TestGtolAllAroundSet()
  Purpose  : Sets whether a gtol shows the all around symbol.
\*====================================================================*/
ProError TestGtolAllAroundSet(ProGtol* gtol)
{
    ProError error = PRO_TK_GENERAL_ERROR;
    ProBoolean all_around;
        
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Show the all around symbol ? (y/n):");    
    all_around = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);
    
    error = ProGtolAllAroundSet(gtol, all_around);
    TEST_CALL_REPORT ("ProGtolAllAroundSet()",
        "TestGtolAllAroundSet()", error, error != PRO_TK_NO_ERROR);    
        
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
   
    return(error);
}

/*====================================================================*\
  Function : TestGtolTangentPlaneSet()
  Purpose  : Sets whether a gtol shows the tangent plane symbol.
\*====================================================================*/
ProError TestGtolTangentPlaneSet(ProGtol* gtol)
{
    ProError error = PRO_TK_GENERAL_ERROR;
    ProBoolean tangent_plane;
    wchar_t* valString = NULL;
	ProSymbolFont symbFont;
	wchar_t* symbolStr = NULL;
	ProGtolType type;
     
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Show the tangent plane symbol ? (y/n):");    
    tangent_plane = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);

    if (!tangent_plane)
        return PRO_TK_NO_ERROR;

	if (tangent_plane)
	{
		error = ProGtolValueStringGet(gtol, &valString);
		TEST_CALL_REPORT("ProGtolValueStringGet()",
			"TestGtolTangentPlaneSet()", error, error != PRO_TK_NO_ERROR);

		error = TestGtolSymbolFontGet(gtol, &symbFont);

		error = ProGtolSymbolStringGet(PRO_GTOL_SYMBOL_TANGENT_PLANE, symbFont, &symbolStr);
		TEST_CALL_REPORT("ProGtolSymbolStringGet()",
			"TestGtolTangentPlaneSet()", error, error != PRO_TK_NO_ERROR);

		ProWstringConcatenate(symbolStr, valString, PRO_VALUE_UNUSED);

		error = ProGtolValueStringSet(gtol, valString);
		TEST_CALL_REPORT("ProGtolValueStringSet()",
			"TestGtolTangentPlaneSet()", error, error != PRO_TK_NO_ERROR);
	}
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
   
    return(error);
}
/*====================================================================*\
  Function : TestGtolProjZoneSet()
  Purpose  : Sets the projected tolerance zone for a gtol.
\*====================================================================*/
ProError TestGtolProjZoneSet(ProGtol* gtol)  
{
    ProError error = PRO_TK_GENERAL_ERROR;
    ProGtolType type;
	wchar_t font[3];
	wchar_t* valString = NULL;
	ProSymbolFont symbFont;
	wchar_t* symbolStr = NULL;

    error = ProGtolTypeGet(gtol, &type);
    TEST_CALL_REPORT ("ProGtolTypeGet()",
        "TestGtolProjZoneSet()", error, error != PRO_TK_NO_ERROR);    
    
    if(error != PRO_TK_NO_ERROR)
        return(error);
    
    if (!((type == PROGTOLTYPE_ANGULAR)||
          (type == PROGTOLTYPE_PERPENDICULAR) ||
          (type == PROGTOLTYPE_PARALLEL) ||
          (type == PROGTOLTYPE_POSITION)))
          return(PRO_TK_NO_ERROR);

	error = ProGtolValueStringGet(gtol, &valString);
	TEST_CALL_REPORT("ProGtolValueStringGet()",
		"TestGtolProjZoneSet()", error, error != PRO_TK_NO_ERROR);

	error = TestGtolSymbolFontGet(gtol, &symbFont);

	if (symbFont == PRO_FONT_ISO || symbFont == PRO_FONT_ASME) {
		font[0] = 9413;
		ProWstringConcatenate(font, valString, PRO_VALUE_UNUSED);
	}
	else if (symbFont == PRO_FONT_LEGACY) {
		font[0] = 112;
		ProWstringConcatenate(font, valString, PRO_VALUE_UNUSED);
	}
	error = ProGtolValueStringSet(gtol, valString);
	TEST_CALL_REPORT("ProGtolValueStringSet()",
		"TestGtolProjZoneSet()", error, error != PRO_TK_NO_ERROR);   
        
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
   
    return(error);    
}

/*====================================================================*\
  Function : TestGtolProfBoundarySet()
  Purpose  : Sets the profile boundary for a gtol.
\*====================================================================*/

ProError TestGtolProfBoundarySet(ProGtol* gtol)
{
    ProError error;
    ProBoolean unilateral = PRO_B_FALSE;
    ProBoolean outside = PRO_B_FALSE;
    ProGtolType type;
    
    error = ProGtolTypeGet(gtol, &type);
    TEST_CALL_REPORT ("ProGtolTypeGet()",
        "TestGtolProfBoundarySet()", error, error != PRO_TK_NO_ERROR);    
    
    if(error != PRO_TK_NO_ERROR)
        return(error);
    
    if (!(type == PROGTOLTYPE_POSITION))
          return(PRO_TK_NO_ERROR);

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Profile boundary is unilateral ? (y/n):");    
	unilateral = (ProUtilYesnoGet((char*)"Yes") == 1) ? (PRO_B_TRUE) :(PRO_B_FALSE);

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"tolerance refers to the outside of the profile ? (y/n):");    
    outside = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);
    
	error = ProGtolUnilateralSet(gtol, unilateral, outside);
    TEST_CALL_REPORT ("ProGtolUnilateralSet()",
        "TestGtolProfBoundarySet()", error, (error != PRO_TK_NO_ERROR && error != PRO_TK_CANT_MODIFY));    

    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
        
    return(error);
}

/*====================================================================*\
  Function : TestGtoldataReferenceSet()
  Purpose  : Sets the item which the gtol refers to.
\*====================================================================*/
ProError TestGtolReferenceSet(ProGtol* gtol)
{
    int n_sel;
    ProSelection *sel;
	ProAnnotationReference *annotRefs = NULL;
	ProReference ref;
    ProError error;  

    ProCharLine cline;
    ProGtolType type;    
    ProModelitem mdl_item;
    
	error = ProGtolTypeGet(gtol, &type);
    TEST_CALL_REPORT ("ProGtolTypeGet()",
        "TestGtolReferenceSet()", error, error != PRO_TK_NO_ERROR);    

/*--------------------------------------------------------------------*\
    Select reference item.
\*--------------------------------------------------------------------*/
    ProUtilMsgPrint( (char*)"gen", (char*)"TEST %0s", (char*)"Please select reference item" );    
    
    ProTKSprintf(cline,(char*)"%s",TestGtolSymSelParam(type));
    error = ProSelect("surface, edge", 1, NULL, NULL, NULL, NULL, &sel, &n_sel); 
    TEST_CALL_REPORT ("ProSelect()",
        "TestGtolReferenceSet()", error, error != PRO_TK_NO_ERROR); 
               
ProTKPrintf( (char*)"--------------------------_> %d\n", error );
ProTKPrintf( (char*)"--------------------------_> %s\n", cline );

    if((error!=PRO_TK_NO_ERROR)||(n_sel<0))     
            return(PRO_TK_BAD_INPUTS);
    
	error = ProArrayAlloc(1, sizeof(ProAnnotationReference), 1, (ProArray*)&annotRefs);

	annotRefs[0].type = PRO_ANNOT_REF_SINGLE;
	annotRefs[0].object.reference = NULL;

	error = ProSelectionToReference(sel[0], &(annotRefs[0].object.reference));
	TEST_CALL_REPORT("ProSelectionToReference()",
		"TestGtolReferenceSet()", error, error != PRO_TK_NO_ERROR);

	error = ProGtolReferencesAdd(gtol, annotRefs);
    TEST_CALL_REPORT ("ProGtolReferencesAdd()",
        "TestGtolReferenceSet()", error, error != PRO_TK_NO_ERROR);    
        
    if(error == PRO_TK_CANT_MODIFY)
    {
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't modify this parameter.");    
        return(PRO_TK_NO_ERROR);            
    }          
    
    return(error);        
}

/*====================================================================*\
  Function : TestGtolCreate()
  Purpose  : Create new gtol in the specified model.
\*====================================================================*/
ProError TestGtolCreate(ProMdl mdl)
{
    ProGtol createdGtol;
    ProGtolType type;
	ProGtolAttach gtolAttach;
	wchar_t* valueStr = L"\0";
	ProBoolean IsComplete = PRO_B_FALSE, is_overall, is_PerUnit;
    ProError error;  
    
    while(1==1)
    {
/*--------------------------------------------------------------------*\
    Choice  gtol type.
\*--------------------------------------------------------------------*/
        type = (ProGtolType)TestGtolSelType();

        if(type<0)
            break;
    
		error = ProGtolAttachAlloc(mdl, &gtolAttach);
		TEST_CALL_REPORT("ProGtolAttachAlloc()",
			"TestGtolCreate()", error, error != PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
Sets gtol Attachment.
\*--------------------------------------------------------------------*/
		error = TestGtolAttachSet(mdl, (ProGtolAttach*)&gtolAttach);
		if (error != PRO_TK_NO_ERROR)
			break;

		error = ProMdlGtolCreate(mdl, type, gtolAttach, valueStr, &createdGtol);
		TEST_CALL_REPORT("ProMdlGtolCreate()",
			"TestGtolCreate()", error, error != PRO_TK_NO_ERROR);

		if (error == PRO_TK_NO_ERROR)
			IsComplete = PRO_B_TRUE;     
/*--------------------------------------------------------------------*\
    Sets references.
\*--------------------------------------------------------------------*/
        error = TestGtolReferenceSet(&createdGtol);
        if(error!=PRO_TK_NO_ERROR)
            break;
            
/*--------------------------------------------------------------------*\
    Sets gtol datum references.
\*--------------------------------------------------------------------*/
        error = TestGtoldatumrefSet(&createdGtol);
        if(error!=PRO_TK_NO_ERROR)
            break;

/*--------------------------------------------------------------------*\
    Sets gtol value.
\*--------------------------------------------------------------------*/
        is_overall = (TestGtolSymIsEnable(type, TestGtS_Unit) == PRO_B_TRUE)?
            (PRO_B_FALSE):(PRO_B_TRUE);
            
        if(is_overall == PRO_B_FALSE)
        {    
            ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Overall tolerance ?(y/n):");    
            is_overall = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE);
        }    

        if (is_overall == PRO_B_TRUE)
        {
            error = TestGtolValueSet(&createdGtol);
            if(error!=PRO_TK_NO_ERROR)
                break;
        }                

/*--------------------------------------------------------------------*\
    Set the per unit tolerance of a gtol.
\*--------------------------------------------------------------------*/
        if(TestGtolSymIsEnable(type, TestGtS_Unit) == PRO_B_TRUE)
        {
            is_PerUnit = (is_overall == PRO_B_FALSE)?(PRO_B_TRUE):(PRO_B_FALSE);

            if(is_PerUnit == PRO_B_FALSE)
            {    
                ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Per unit tolerance? (y/n):");    
                is_PerUnit = (ProUtilYesnoGet((char*)"Yes") == 1)?(PRO_B_TRUE):(PRO_B_FALSE); 
            }    
            if (is_PerUnit == PRO_B_TRUE)
            {        
                error = TestGtolPerUnitSet(&createdGtol);
                if(error!=PRO_TK_NO_ERROR)
                    break;
            }        
        }        
/*--------------------------------------------------------------------*\
    Set whether a gtol shows the statistical tolerance symbol.
\*--------------------------------------------------------------------*/
        if(TestGtolSymIsEnable(type, TestGtS_Stat) == PRO_B_TRUE)
        {
            error = TestGtolStatTolSet(&createdGtol);
            if(error!=PRO_TK_NO_ERROR)
                break;
        }
            
/*--------------------------------------------------------------------*\
    Set whether a gtol shows the diameter tolerance symbol.
\*--------------------------------------------------------------------*/
        if (TestGtolSymIsEnable(type, TestGtS_Diam) == PRO_B_TRUE)
        {
            error = TestGtolDiameterSet(&createdGtol);
            if(error!=PRO_TK_NO_ERROR)
                break;
        }        
            
/*--------------------------------------------------------------------*\
    Set whether a gtol shows the free state symbol.
\*--------------------------------------------------------------------*/
        if (TestGtolSymIsEnable(type, TestGtS_Free) == PRO_B_TRUE)
        {
            error = TestGtolFreeStateSet(&createdGtol);
            if(error!=PRO_TK_NO_ERROR)
                break;
        }                
            
/*--------------------------------------------------------------------*\
    Sets whether a gtol shows the all around symbol.
\*--------------------------------------------------------------------*/
        if (TestGtolSymIsEnable(type, TestGtS_All) == PRO_B_TRUE)
        {
            error = TestGtolAllAroundSet(&createdGtol);
            if(error!=PRO_TK_NO_ERROR)
                break;
        }                

/*--------------------------------------------------------------------*\
    Sets whether a gtol shows the tangent plane symbol.
\*--------------------------------------------------------------------*/
        if (TestGtolSymIsEnable(type, TestGtS_Tan) == PRO_B_TRUE)
        {
            error = TestGtolTangentPlaneSet(&createdGtol);
            if(error!=PRO_TK_NO_ERROR)
                break;
        }       
            
/*--------------------------------------------------------------------*\
    Sets the projected tolerance zone for a gtol.
\*--------------------------------------------------------------------*/
        error = TestGtolProjZoneSet(&createdGtol);
        if(error!=PRO_TK_NO_ERROR)
            break;

/*--------------------------------------------------------------------*\
    Sets the profile boundary for a gtol.
\*--------------------------------------------------------------------*/
        error = TestGtolProfBoundarySet(&createdGtol);
        if(error!=PRO_TK_NO_ERROR)
            break;

/*--------------------------------------------------------------------*\
   Sets gtol composite property.
\*--------------------------------------------------------------------*/
		error = TestGtolCompositeSet(&createdGtol);
		if (error != PRO_TK_NO_ERROR)
			break;

        break;
    }
    
    if(IsComplete == PRO_B_TRUE)
	{
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Gtol normal created");    

		error = ProAnnotationShow((ProAnnotation*)&createdGtol,NULL,NULL);
		TEST_CALL_REPORT ("ProAnnotationShow()","TestGtolCreate()", error, error != PRO_TK_NO_ERROR);    

	}
    else
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Can't create gtol.");    
           
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolRefSet()
  Purpose  : Sets a datum plane or axis to be a gtol reference.
\*====================================================================*/
ProError TestGtolRefSet(ProMdl mdl)
{
    ProError error;
    ProGeomitem geomitem;
    ProSelection *sel;
    int n_sel;
    ProBoolean is_in_dim;
    ProDimension in_dim; 

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select axis or datum");    

/*--------------------------------------------------------------------*\
    Select datum or axis.
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"datum,axis", 1,NULL, NULL, NULL, NULL, &sel, &n_sel); 
    TEST_CALL_REPORT ("ProSelect()",
        "TestGtolRefSet()", error, error != PRO_TK_NO_ERROR);    
    
    if((error!=PRO_TK_NO_ERROR)||(n_sel<0))
        return(PRO_TK_E_NOT_FOUND);    

    error = ProSelectionModelitemGet(sel[0],(ProModelitem*)&geomitem);
    TEST_CALL_REPORT ("ProSelectionModelitemGet()",
        "TestGtolRefSet()", error, error != PRO_TK_NO_ERROR);    

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"In dim tolerance ?(y/n):");    
    
    if(ProUtilYesnoGet((char*)"Yes") == 1)
    { 
/*--------------------------------------------------------------------*\
    if "In dim tolerance" then select dimension.
\*--------------------------------------------------------------------*/
        is_in_dim = PRO_B_FALSE;
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select dimension");    
    
        error = ProSelect((char*)"dimension,ref_dim", 1,NULL, NULL, NULL, NULL, &sel, &n_sel); 
        TEST_CALL_REPORT ("ProSelect()",
            "TestGtolRefSet()", error, error != PRO_TK_NO_ERROR);    
    
        if((error!=PRO_TK_NO_ERROR)||(n_sel<0))
            return(PRO_TK_E_NOT_FOUND);    
            
        error = ProSelectionModelitemGet(sel[0],(ProModelitem*)&in_dim);
        TEST_CALL_REPORT ("ProSelectionModelitemGet()",
            "TestGtolRefSet()", error, error != PRO_TK_NO_ERROR);       
         
    } else
    {
        is_in_dim = PRO_B_TRUE;
        ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Gtol is FREE.");    
    }   

    error = ProGeomitemSetdatumSet(&geomitem, NULL);
    TEST_CALL_REPORT ("ProGeomitemSetdatumSet()",
        "TestGtolRefSet()", error, error != PRO_TK_NO_ERROR);    
    
    return(error);
}

/*====================================================================*\
  Function : TestGtolRefClear()
  Purpose  : Clears a datum plane or axis so it is no 
             longer a gtol reference.
\*====================================================================*/
ProError TestGtolRefClear(ProMdl mdl)
{
    ProError error;
    ProGeomitem geomitem;
    ProSelection *sel;
    int n_sel;

    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select axis or datum");    

/*--------------------------------------------------------------------*\
    Select target (datum or axis).
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"datum,axis", 1,NULL, NULL, NULL, NULL, &sel, &n_sel); 
    TEST_CALL_REPORT ("ProSelect()",
        "TestGtolRefClear()", error, error != PRO_TK_NO_ERROR);    
    
    if((error!=PRO_TK_NO_ERROR)||(n_sel<0))
        return(PRO_TK_E_NOT_FOUND);    

    error = ProSelectionModelitemGet(sel[0],(ProModelitem*)&geomitem);
    TEST_CALL_REPORT ("ProSelectionModelitemGet()",
        "TestGtolRefClear()", error, error != PRO_TK_NO_ERROR);    

    error = ProGeomitemSetdatumClear(&geomitem);
    TEST_CALL_REPORT ("ProGeomitemSetdatumClear()",
        "TestGtolRefClear()", error, error != PRO_TK_NO_ERROR);    
    
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolRefInfo()
  Purpose  : Shows whether a datum plane or axis is a gtol reference 
\*====================================================================*/
ProError TestGtolRefInfo(ProMdl mdl)
{
    ProError error;
    ProGeomitem geomitem;
    ProSelection *sel;
    int n_sel;
    ProBoolean ref_datum;
    ProCharLine cline; 
    ProGtolsetdatumValue value;
    
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Select axis or datum");    

/*--------------------------------------------------------------------*\
    Select target (datum or axis).
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"datum,axis", 1,NULL, NULL, NULL, NULL, &sel, &n_sel); 
    TEST_CALL_REPORT ("ProSelect()",
        "TestGtolRefInfo()", error, error != PRO_TK_NO_ERROR);    
    
    if((error!=PRO_TK_NO_ERROR)||(n_sel<0))
        return(PRO_TK_E_NOT_FOUND);    

    error = ProSelectionModelitemGet(sel[0],(ProModelitem*)&geomitem);
    TEST_CALL_REPORT ("ProSelectionModelitemGet()",
        "TestGtolRefInfo()", error, error != PRO_TK_NO_ERROR);    

    error = ProGeomitemSetdatumGet(&geomitem, &ref_datum, &value);
    TEST_CALL_REPORT ("ProGeomitemIsGtolref()",
        "TestGtolRefInfo()", error, error != PRO_TK_NO_ERROR);

    if(error != PRO_TK_NO_ERROR)
      return(error);

    ProTKSprintf(cline, (char*)"Gtol reference: %s; %s", YesNoStr(ref_datum),        			(value.type == PRO_GTOLREF_IN_GEOM)?("Set Datum"):("Free"));        
    ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", cline);   
    
    if(value.type == PRO_GTOLREF_IN_GEOM) 
    { 
      error = ProSelectionFree((ProSelection*)&value);
      TEST_CALL_REPORT ("ProSelectionFree()", 
          "TestGtolRefInfo()", error, error!= PRO_TK_NO_ERROR);
    }
          
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolInfo()
  Purpose  : Create menu for choice mode of get information about gtol. 
\*====================================================================*/
ProError TestGtolInfo(ProMdl mdl)
{
    int menu_id;

/*=================================================================*\
    Setup menu actions
\*=================================================================*/
    ProMenuFileRegister((char*)"TkGtolInfo",(char*)"tkgtolinfo.mnu",&menu_id);
    ProMenubuttonActionSet((char*)"TkGtolInfo",(char*)"-Selected",
        (ProMenubuttonAction)TestGtolInfoSel, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtolInfo",(char*)"-All",
        (ProMenubuttonAction)TestGtolInfoAll, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtolInfo",(char*)"TkGtolInfo",
        (ProMenubuttonAction)ProMenuDelete, mdl,  0);
        
/*=================================================================*\
    Create new menu
\*=================================================================*/
    ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkGtolInfo", NULL);
    ProMenuProcess((char*)"", &menu_id);

    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolRefMenu()
  Purpose  : Create menu for change datupm plane or axis property.
\*====================================================================*/
ProError TestGtolRefMenu(ProMdl mdl)
{
    int menu_id;
    ProError error;
    
/*=================================================================*\
    Setup menu actions
\*=================================================================*/
    ProMenuFileRegister((char*)"TkGtolRef",(char*)"tkgtolref.mnu",&menu_id);
    ProMenubuttonActionSet((char*)"TkGtolRef",(char*)"-Set",
        (ProMenubuttonAction)TestGtolRefSet, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtolRef",(char*)"-Clear",
        (ProMenubuttonAction)TestGtolRefClear, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtolRef",(char*)"-Info",
        (ProMenubuttonAction)TestGtolRefInfo, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtolRef",(char*)"TkGtolRef",
        (ProMenubuttonAction)ProMenuDelete, mdl,  0);
        
/*=================================================================*\
    Create new menu
\*=================================================================*/
    ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkGtolRef", NULL);
    ProMenuProcess((char*)"", &menu_id);

    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
  Function : TestGtolMainMenu()
  Purpose  : Create main menu for gtol test and demo.
\*====================================================================*/
ProError TestGtolMainMenu()
{
    int menu_id;
    ProMdl mdl;
    ProError error;

    error = ProMdlCurrentGet(&mdl);
    TEST_CALL_REPORT ("ProMdlCurrentGet()",
            "TestGtolMainMenu()", error, error != PRO_TK_NO_ERROR);

/*=================================================================*\
    Setup menu actions
\*=================================================================*/
    ProMenuFileRegister((char*)"TkGtol",(char*)"tkgtol.mnu",&menu_id);
    ProMenubuttonActionSet((char*)"TkGtol",(char*)"-Add",
        (ProMenubuttonAction)TestGtolCreate, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtol",(char*)"-Modify",
        (ProMenubuttonAction)TestGtolModify, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtol",(char*)"-Delete all",
        (ProMenubuttonAction)TestGtolDeleteAll, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtol",(char*)"-Show all",
        (ProMenubuttonAction)TestMdlGtolShow, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtol",(char*)"-Info",
        (ProMenubuttonAction)TestGtolInfo, mdl,  0);
        
    ProMenubuttonActionSet((char*)"TkGtol",(char*)"-Reference",
        (ProMenubuttonAction)TestGtolRefMenu, mdl,  0);

    ProMenubuttonActionSet((char*)"TkGtol",(char*)"TkGtol",
	(ProMenubuttonAction)ProMenuDelete, NULL,  0);

/*=================================================================*\
    Create new menu
\*=================================================================*/
    ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkGtol", NULL);
    ProMenuProcess((char*)"", &menu_id);
    
    return(PRO_TK_NO_ERROR);
}