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



/*---------------------------------------------------------------------------*\
    Pro/TOOLKIT includes
\*---------------------------------------------------------------------------*/
#include "ProSelection.h"
#include "ProModelitem.h"
#include "ProColor.h"
#include "ProMessage.h"
#include "ProMenu.h"
#include "ProMdl.h"
#include "ProDrawing.h"
#include "ProGraphic.h"
#include "ProUtil.h"
#include "ProDtlsyminst.h"
#include "ProDtlsymdef.h"
#include "ProDtlnote.h"
#include "ProDtlattach.h"

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

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

/* modify options */
#define SYM_INST_COLOR   0
#define SYM_INST_LENTH   1
#define SYM_INST_ANGLE   2
#define SYM_INST_LEADER  3
#define SYM_INST_HEIGHT  4
#define SYM_INST_ATTACH  5
#define SYM_INST_VARTEXT 6

/* display options */
#define SYM_INST_DRAW   0
#define SYM_INST_REMOVE 1
#define SYM_INST_ERASE  2
#define SYM_INST_DELETE 3
  
#define DTL_SYM_INST_FILE ".inf"

ProError ProTestSymInstGet (ProDrawing , ProDtlsyminst * );
ProError ProTestAttachGet(ProDrawing, ProDtlsymdefdata, 
                          ProDtlsymdefattachType*, ProDtlattach* );

ProError ProTestDtlsymdefNameGet (ProDtlsymdef *, ProName );

/*===========================================================================*\
  Function : ProTestSymInst
  Purpose  : 
\*===========================================================================*/
int ProTestSymInst(void *app_data)
{
    ProError err;
    int menu_id;
    ProDrawing draw = (ProDrawing)app_data;
    int ProTestSumInstAdd (ProDrawing drw);
    int ProTestSymInstModify (ProDrawing drw);
    int ProTestSymInstDisplay (ProDrawing drw);
    int ProTestSymInstInfo (ProDrawing drw);
        
    err = ProMenuFileRegister((char*)"Syminst",(char*)"tksyminst.mnu", &menu_id);
    err = ProMenubuttonActionSet((char*)"Syminst",(char*)"Syminst", 
		(ProMenubuttonAction)ProMenuDelete, NULL, 0);
    err = ProMenubuttonActionSet((char*)"Syminst",(char*)"Create", 
		(ProMenubuttonAction)ProTestSumInstAdd, draw, 0);
    err = ProMenubuttonActionSet((char*)"Syminst",(char*)"Redefine", 
		(ProMenubuttonAction)ProTestSymInstModify, draw, 0);
    err = ProMenubuttonActionSet((char*)"Syminst",(char*)"Display",  
                (ProMenubuttonAction)ProTestSymInstDisplay, draw, 0);
    err = ProMenubuttonActionSet((char*)"Syminst",(char*)"Info",  
                (ProMenubuttonAction)ProTestSymInstInfo, draw, 0);
    err = ProMenuCreate(PROMENUTYPE_MAIN, (char*)"Syminst",&menu_id);
    err = ProMenuProcess((char*)"", &menu_id);
    return (0);
}

/*===========================================================================*\
  Function : ProTestSumInstAdd
  Purpose  : 
\*===========================================================================*/
int ProTestSumInstAdd(ProDrawing drw)
{
    ProError err;
    ProDtlsymdef sym_def;
    ProDtlsyminst sym_inst;
    ProDtlsymdefdata def_data;
    ProDtlsyminstdata sym_data;
    ProDtlattach attach, *p_leaders = NULL;
    ProDtlsymdefattachType def_attach_type;
    int i, n_leaders;
    ProError ProTestVarTextSet(ProDrawing drw,
                            ProDtlsymdef symbol,
                            ProDtlsyminstdata inst_data);
    ProError ProTestSymDefGet (ProDrawing drw, ProDtlsymdef *sym_def);
    ProError ProTestLeadersGet ();
        
    err = ProDtlsyminstdataAlloc (drw, &sym_data);
    TEST_CALL_REPORT("ProDtlsyminstdataAlloc()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
        
    err = ProTestSymDefGet (drw, &sym_def);
    if (err !=  PRO_TK_NO_ERROR)
        return (0);
        
    err = ProDtlsymdefDataGet (&sym_def, &def_data);
    TEST_CALL_REPORT("ProDtlsymdefDataGet()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    
    err = ProTestAttachGet (drw, def_data, &def_attach_type, &attach);
    if (err != PRO_TK_NO_ERROR)
        return (-1);
    err = ProDtlsyminstdataDefSet (sym_data, &sym_def);
    TEST_CALL_REPORT("ProDtlsyminstdataDefSet()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    
    err = ProDtlsyminstdataAttachtypeSet (sym_data, def_attach_type);
    TEST_CALL_REPORT("ProDtlsyminstdataAttachtypeSet()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    
    err = ProDtlsyminstdataAttachmentSet (sym_data, attach);
    TEST_CALL_REPORT("ProDtlsyminstdataAttachmentSet()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    
    err = ProDtlattachFree (attach);
    TEST_CALL_REPORT("ProDtlattachFree()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
       
    err = ProTestVarTextSet (drw, sym_def, sym_data);
    
    err = ProTestLeadersGet (&p_leaders);
    if (err == PRO_TK_NO_ERROR && p_leaders != NULL)
    {
        err = ProArraySizeGet ((ProArray)p_leaders, &n_leaders);
        err = ProDtlsyminstdataLeadersSet (sym_data, p_leaders);
        TEST_CALL_REPORT("ProDtlsyminstdataLeadersSet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        err = ProArraySizeGet ((ProArray)p_leaders, &n_leaders);
        for (i = 0; i < n_leaders; i++)
            err = ProDtlattachFree (p_leaders[i]);
        err = ProArrayFree ((ProArray*)&p_leaders);
    }
    err = ProDtlsyminstCreate (drw, sym_data, &sym_inst);
    TEST_CALL_REPORT("ProDtlsyminstCreate()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    err = ProDtlsyminstShow (&sym_inst);
    TEST_CALL_REPORT("ProDtlsyminstShow()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    
    err = ProDtlsyminstdataFree (sym_data);
    TEST_CALL_REPORT("ProDtlsyminstdataFree()",
        "ProTestSumInstAdd()", err, err != PRO_TK_NO_ERROR);
    return 0;
}

/*===========================================================================*\
  Function : ProTestSymDefGet
  Purpose  : 
\*===========================================================================*/
ProError ProTestSymDefGet (ProDrawing drw, ProDtlsymdef *sym_def)
{
    ProError err;
    ProDtlsymdef *p_symdefs;
    int size = 0, i, n_sel = 0;
    ProName title, name;
    wchar_t **selected, **names;
        
    err = ProDrawingDtlsymdefsCollect (drw, &p_symdefs);
    TEST_CALL_REPORT("ProDrawingDtlsymdefsCollect()",
        "ProTestSymDefGet()", err, err != PRO_TK_NO_ERROR
        && err != PRO_TK_E_NOT_FOUND);

    if (err != PRO_TK_NO_ERROR)
        return (err);
    err = ProUtilMenuStringsAlloc (&names);    
    err = ProArraySizeGet ((ProArray)p_symdefs, &size);
    TEST_CALL_REPORT("ProArraySizeGet()",
    "ProTestSymDefGet()", err, err != PRO_TK_NO_ERROR);
    for (i = 0; i < size; i++)
    {
        err = ProTestDtlsymdefNameGet (&p_symdefs[i], name);
        if (err != PRO_TK_NO_ERROR)
            ProStringToWstring (name, (char*)"ERROR");
        err = ProUtilMenuStringsWstrAdd(&names, name);
    }
    ProStringToWstring(title, (char*)"Symbol defs");
    err = ProMenuStringsSelect(title, names, 1, NULL, &selected, &n_sel);
    if (err !=  PRO_TK_NO_ERROR || n_sel != 1)
	return  (PRO_TK_E_NOT_FOUND);
    for (i = 0; i < size; i++)
        if (ProUtilWstrcmp (names[i], selected[0]) == 0)
        {
            *sym_def = p_symdefs[i];
            break; 
        }
    err = ProUtilMenuStringsFree(&names);
    err = ProArrayFree ((ProArray*)&p_symdefs);
    
    return PRO_TK_NO_ERROR;
}

/*===========================================================================*\
  Function : ProTestAttachGet
  Purpose  : 
\*===========================================================================*/
ProError  ProTestAttachGet (ProDrawing drw, 
                            ProDtlsymdefdata def_data,
                            ProDtlsymdefattachType *def_attach_type,
                            ProDtlattach *attach)
{
    ProError err;
    int size = 0,  n_sel, sheet = 0, menu_id, i;
    ProDtlsymdefattach *p_attaches;
    ProDtlsymdefattachType def_at_type;
    ProDtlattachType attach_type;
    ProMouseButton btn;
    ProSelection *sel;
    ProPoint3d sel_pnt;
    ProView over_view;
    
    err = ProDtlsymdefdataAttachGet (def_data, &p_attaches);
    TEST_CALL_REPORT("ProDtlsymdefdataAttachGet()",
        "ProTestAttachGet()", err, err != PRO_TK_NO_ERROR);
    if (err !=  PRO_TK_NO_ERROR)
        return (err); 
    err = ProMenuFileRegister((char*)"AttachType",(char*)"tkattachtype.mnu", &menu_id);
    err = ProMenubuttonActionSet((char*)"AttachType",(char*)"AttachType", 
		(ProMenubuttonAction)ProMenuDelete, NULL, 0);
    err = ProMenubuttonActionSet((char*)"AttachType",(char*)"Free", 
		(ProMenubuttonAction)ProUtilAssign, def_attach_type, 
                    PROSYMDEFATTACHTYPE_FREE);
    err = ProMenubuttonActionSet((char*)"AttachType",(char*)"Leader", 
		(ProMenubuttonAction)ProUtilAssign, def_attach_type, 
                    PROSYMDEFATTACHTYPE_LEFT_LEADER);
     err = ProMenubuttonActionSet((char*)"AttachType",(char*)"On item", 
		(ProMenubuttonAction)ProUtilAssign, def_attach_type, 
                    PROSYMDEFATTACHTYPE_ON_ITEM);
     err = ProMenubuttonActionSet((char*)"AttachType",(char*)"Normal", 
		(ProMenubuttonAction)ProUtilAssign, def_attach_type, 
                    PROSYMDEFATTACHTYPE_NORM_ITEM);
    ProMenuCreate(PROMENUTYPE_MAIN,(char*)"AttachType" ,&menu_id );
    
    err = ProMenubuttonDeactivate ((char*)"AttachType",(char*)"Free");
    err = ProMenubuttonDeactivate ((char*)"AttachType",(char*)"Leader");
    err = ProMenubuttonDeactivate ((char*)"AttachType",(char*)"On item");
    err = ProMenubuttonDeactivate ((char*)"AttachType",(char*)"Normal");
    
    /* Get type */
    err = ProArraySizeGet ((ProArray)p_attaches, &size);
    for (i = 0; i < size; i++)
    {
        err = ProDtlsymdefattachGet (p_attaches[i], &def_at_type,
            NULL, NULL, NULL);
        switch (def_at_type)
        {
        case PROSYMDEFATTACHTYPE_FREE :
            err = ProMenubuttonActivate ((char*)"AttachType",(char*)"Free");
            break;
        case PROSYMDEFATTACHTYPE_LEFT_LEADER :
            err = ProMenubuttonActivate ((char*)"AttachType",(char*)"Leader");
            break;
        case PROSYMDEFATTACHTYPE_RIGHT_LEADER :
            err = ProMenubuttonActivate ((char*)"AttachType",(char*)"Leader");
            break;
        case PROSYMDEFATTACHTYPE_RADIAL_LEADER :
            err = ProMenubuttonActivate ((char*)"AttachType",(char*)"Leader");
            break;
        case PROSYMDEFATTACHTYPE_ON_ITEM :
            err = ProMenubuttonActivate ((char*)"AttachType",(char*)"On item");
            break;
        case PROSYMDEFATTACHTYPE_NORM_ITEM :
            err = ProMenubuttonActivate ((char*)"AttachType",(char*)"Normal");
            break;
        default : break;
        }
        
    } 
    err = ProMenuProcess((char*)"AttachType", &menu_id);
    /* setup attach */
    switch (*def_attach_type)
    {
    case PROSYMDEFATTACHTYPE_FREE :
    case PROSYMDEFATTACHTYPE_LEFT_LEADER :
    case PROSYMDEFATTACHTYPE_RIGHT_LEADER :
    case PROSYMDEFATTACHTYPE_RADIAL_LEADER :
        attach_type = PRO_DTLATTACHTYPE_FREE;
        err = ProDrawingCurrentSheetGet (drw, &sheet);
        err = ProDrawingBackgroundViewGet (drw, sheet, &over_view);
       TEST_CALL_REPORT("ProDrawingBackgroundViewGet()",
            "ProTestAttachGet()", err, err != PRO_TK_NO_ERROR);
        ProUtilMsgPrint("gen", "TEST %0s", "Enter position");
        if (ProMousePickGet(PRO_ANY_BUTTON, &btn, sel_pnt) != PRO_TK_NO_ERROR)
            break;
        ProGraphicsCircleDraw (sel_pnt, 0.5);
        err = ProDtlattachAlloc (attach_type, over_view, sel_pnt, NULL, attach);
        TEST_CALL_REPORT("ProDtlattachAlloc()",
            "ProTestAttachGet()", err, err != PRO_TK_NO_ERROR);
        
        break;
    case PROSYMDEFATTACHTYPE_ON_ITEM :
    case PROSYMDEFATTACHTYPE_NORM_ITEM :
        attach_type = PRO_DTLATTACHTYPE_PARAMETRIC;
        ProUtilMsgPrint("gen", "TEST %0s", "Select attachment point");
        err = ProSelect ((char*)"edge,curve,point,axis", 1, NULL, NULL, NULL, NULL,
            &sel, &n_sel);
        if (err != PRO_TK_NO_ERROR || n_sel != 1)
            break;
        err = ProDtlattachAlloc (attach_type, NULL, NULL, sel[0], attach);
        TEST_CALL_REPORT("ProDtlattachAlloc()",
            "ProTestAttachGet()", err, err != PRO_TK_NO_ERROR);
          
        break;
    default:
        return PRO_TK_GENERAL_ERROR;   
    }
    ProArrayFree ((ProArray*)&p_attaches);
    
    return err; 
}

/*===========================================================================*\
  Function : ProTestVarTextSet
  Purpose  : 
\*===========================================================================*/
ProError ProTestVarTextSet (ProDrawing drw,
                            ProDtlsymdef symbol,
                            ProDtlsyminstdata inst_data)
{
    ProError err;
    ProDtlnote *p_notes;
    ProDtlnoteline *p_lines ;
    ProDtlnotetext *p_texts ;
    ProLine line, value;
    ProCharLine string, text;
    ProDtlnotedata note_data;
    ProDtlvartext var_text, *p_var_texts;
    int n_notes = 0, n_lines = 0, n_texts = 0, n_var_texts = 0, i, j, k;
    
    err = ProDrawingDtlnotesCollect (drw, &symbol, PRO_VALUE_UNUSED, 
        &p_notes);
    TEST_CALL_REPORT("ProDrawingDtlnotesCollect()",
        "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR 
        && err != PRO_TK_E_NOT_FOUND);
    if (err != PRO_TK_NO_ERROR)
            return (err);
            
    err = ProArrayAlloc (0, sizeof (ProDtlvartext), 1, (ProArray*)&p_var_texts);

    err = ProArraySizeGet ((ProArray)p_notes, &n_notes);
    for (i = 0; i  < n_notes; i++)
    {
        err = ProDtlnoteDataGet (&p_notes[i], &symbol, PRODISPMODE_NUMERIC,
            &note_data);
        TEST_CALL_REPORT("ProDtlnoteDataGet()",
                "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR);
        if (err != PRO_TK_NO_ERROR)
            return (err);
        err = ProDtlnotedataLinesCollect (note_data, &p_lines);
        TEST_CALL_REPORT("ProDtlnotedataLinesCollect()",
                "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR
                && err != PRO_TK_E_NOT_FOUND);
        if (err ==  PRO_TK_NO_ERROR)
        {   
            err = ProArraySizeGet ((ProArray)p_lines, &n_lines);
            for (j = 0; j < n_lines; j++)
            {
                err = ProDtlnotelineTextsCollect (p_lines[j], &p_texts);
                TEST_CALL_REPORT("ProDtlnotelineTextsCollect()",
                    "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR
                    && err != PRO_TK_E_NOT_FOUND);
                if (err ==  PRO_TK_NO_ERROR)
                {
                    err = ProArraySizeGet ((ProArray)p_texts, &n_texts);
                    for (k = 0; k < n_texts; k++)
                    {
                        err = ProDtlnotetextStringGet (p_texts[k], line);
                        TEST_CALL_REPORT("ProDtlnotetextStringGet()",
                            "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR);
                        ProWstringToString (string, line);
                        if(string[3]=='\\' && string[strlen(string)-2]=='\\')
                        {
                            ProTKSprintf (text,"Enter instance text for %s",string);
                            ProUtilMsgPrint("gen", "TEST %0s", text);
                            ProStringToWstring (line, text);
                            memset (text, '\0', sizeof (ProCharLine));
                            ProStringToWstring (line, strncpy (text,
                                &string[4], strlen(&string[4])-2));
                            if (ProMessageStringRead (PRO_LINE_SIZE, value) !=
                                PRO_TK_NO_ERROR)
                                break;
                            err = ProDtlvartextAlloc (line, value, &var_text);
                            TEST_CALL_REPORT("ProDtlvartextAlloc()",
                            "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR);
                            err = ProArrayObjectAdd( (ProArray*)&p_var_texts,
                                PRO_VALUE_UNUSED, 1, &var_text);
                        }
                    }
                    for (k = 0; k < n_texts; k++)
                    {
                         err = ProDtlnotetextFree (p_texts[k]);
                         TEST_CALL_REPORT("ProDtlnotetextFree()",
                            "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR);
                    }
                    err = ProArrayFree ((ProArray*)&p_texts);
                }
            }
            for (j = 0; j < n_lines; j++)
            {
                err = ProDtlnotelineFree (p_lines[j]);
                TEST_CALL_REPORT("ProDtlnotelineFree()",
                    "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR);
            }
            err = ProArrayFree ((ProArray*)&p_lines);
        }
    }
    
    err = ProArrayFree ((ProArray*)&p_notes);
    
    err = ProArraySizeGet ((ProArray)p_var_texts, &n_var_texts);
    if (err == PRO_TK_NO_ERROR && n_var_texts != 0)
    {
        err = ProDtlsyminstdataVartextsSet (inst_data, p_var_texts);
        TEST_CALL_REPORT("ProDtlsyminstdataVartextsSet()",
                "ProTestVarTextSet()", err, err != PRO_TK_NO_ERROR);
        err = ProArrayFree ((ProArray*)&p_var_texts);
    }
    else 
        return (PRO_TK_NO_CHANGE);
    
    return PRO_TK_NO_ERROR;
}

/*===========================================================================*\
  Function : ProTestSymInstModify
  Purpose  : 
\*===========================================================================*/
int ProTestSymInstModify (ProDrawing drw)
{
    ProError err;
    ProDtlsyminst sym_inst;
    ProDtlsyminstdata sym_data;
    ProColor color;
    int opt, n_leaders, i;
    ProCharLine line;
    ProBoolean flag;
    double param = 0.0;
    ProDtlsymdef sym_def;
    ProDtlsymdefdata def_data;
    ProDtlsymdefdataHeighttype height_type;
    ProDtlattach attach, *p_leaders = NULL;
    ProDtlsymdefattachType def_at_type;
    
    ProError ProTestLeadersGet ();
    
    static ProUtilMenuButtons inst_opt[] = { 
        {"Redefine", 0, TEST_CALL_PRO_MENU_DELETE},
        {"Color", SYM_INST_COLOR, 0},
        {"Elbow", SYM_INST_LENTH, 0},
        {"Angle", SYM_INST_ANGLE, 0},
        {"Leader", SYM_INST_LEADER, 0},
        {"Height", SYM_INST_HEIGHT, 0},
        {"Attach", SYM_INST_ATTACH, 0},
        {"VarText", SYM_INST_VARTEXT, 0},
        {"",0,0}
    };
    
    err = ProUtilMenuIntValueSelect(inst_opt, &opt);
    
    err = ProTestSymInstGet (drw, &sym_inst);
    if (err != PRO_TK_NO_ERROR)
        return (0);
        
    err = ProDtlsyminstDataGet (&sym_inst, PRODISPMODE_NUMERIC, &sym_data);
    TEST_CALL_REPORT("ProDtlsyminstDataGet()",
        "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        
    err = ProDtlsyminstdataDefGet (sym_data, &sym_def);
    TEST_CALL_REPORT("ProDtlsyminstdataDefGet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
    err = ProDtlsymdefDataGet (&sym_def, &def_data);
    TEST_CALL_REPORT("ProDtlsymdefDataGet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);

    switch (opt)
    {
    case  SYM_INST_COLOR :    
        ProTestColorGet (&color);
        err = ProDtlsyminstdataColorSet (sym_data, &color);
        TEST_CALL_REPORT("ProDtlsyminstdataColorSet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
            
        break;
    case SYM_INST_LENTH :
        ProDtlsyminstdataElbowlengthGet (sym_data, &flag, &param);
        TEST_CALL_REPORT("ProDtlsyminstdataElbowlengthGet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        if (flag == PRO_B_TRUE)
        {
            ProUtilMsgPrint("gen", "TEST %0s", "Unable modify elblow lenth.");
            return (0);
        }
        ProTKSprintf (line, "Enter elblow lenth [%6.2f]: ", param);
        ProUtilMsgPrint("gen", "TEST %0s", line);
        if (ProMessageDoubleRead (NULL, &param) != PRO_TK_NO_ERROR)
            return (0);
        err = ProDtlsyminstdataElbowlengthSet (sym_data, PRO_B_FALSE, param);
        TEST_CALL_REPORT("ProDtlsyminstdataElbowlengthSet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
            
        break;
    case SYM_INST_ANGLE :
        err = ProDtlsyminstdataAngleGet (sym_data, &param);
        TEST_CALL_REPORT("ProDtlsyminstdataAngleGet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        ProTKSprintf (line, "Enter angle [%6.2f]: ", param);
        ProUtilMsgPrint("gen", "TEST %0s", line);
        if (ProMessageDoubleRead (NULL, &param) != PRO_TK_NO_ERROR)
            return (0);
        err = ProDtlsyminstdataAngleSet (sym_data, param);
        TEST_CALL_REPORT("ProDtlsyminstdataAngleSet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
            
        break;
    case SYM_INST_HEIGHT :
        err = ProDtlsymdefdataHeighttypeGet (def_data, &height_type);
        TEST_CALL_REPORT("ProDtlsymdefdataHeighttypeGet()",
        "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        if (height_type == PRODTLSYMDEFHGHTTYPE_VARIABLE)
        {
            err = ProDtlsyminstdataScaledheightGet (sym_data, &param);
             TEST_CALL_REPORT("ProDtlsyminstdataScaledheightGet()",
                "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
            ProTKSprintf (line, "Enter height [%6.2f]: ", param);
            ProUtilMsgPrint("gen", "TEST %0s", line);
            if (ProMessageDoubleRead (NULL, &param) != PRO_TK_NO_ERROR)
                return (0);
            err = ProDtlsyminstdataScaledheightSet (sym_data, param);
            TEST_CALL_REPORT("ProDtlsyminstdataScaledheightSet()",
                "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        }
        else
            ProUtilMsgPrint("gen", "TEST %0s", "Unable modify height: ");
              
        break;
    case SYM_INST_LEADER :
        err = ProTestLeadersGet (&p_leaders);
        if (err == PRO_TK_NO_ERROR && p_leaders != NULL)
        {
            err = ProDtlsyminstdataLeadersSet (sym_data, p_leaders);
            TEST_CALL_REPORT("ProDtlsyminstdataLeadersSet()",
                "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
            err = ProArraySizeGet ((ProArray)p_leaders, &n_leaders);
            for (i = 0; i < n_leaders; i++)
                err = ProDtlattachFree (p_leaders[i]);
            err = ProArrayFree ((ProArray*)&p_leaders);
        }
        break;
    case SYM_INST_ATTACH :
        err = ProTestAttachGet (drw, def_data, &def_at_type, &attach);
        err = ProDtlsyminstdataAttachtypeSet (sym_data, def_at_type);
        TEST_CALL_REPORT("ProDtlsyminstdataAttachtypeSet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        err = ProDtlsyminstdataAttachmentSet (sym_data, attach);
        TEST_CALL_REPORT("ProDtlsyminstdataAttachmentSet()",
            "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
        err = ProDtlattachFree (attach);
        TEST_CALL_REPORT("ProDtlattachFree()",
            "ProDtlattachFree()", err, err != PRO_TK_NO_ERROR);

        break;
    case SYM_INST_VARTEXT :
        err = ProTestVarTextSet (drw, sym_def, sym_data);
        if (err !=  PRO_TK_NO_ERROR)
            ProUtilMsgPrint("gen", "TEST %0s", "Unable modify var text. ");
        
        break;
    }
    err = ProDtlsyminstErase (&sym_inst);
    TEST_CALL_REPORT("ProDtlsyminstErase()",
        "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
    err = ProDtlsyminstModify (&sym_inst, sym_data);
    TEST_CALL_REPORT("ProDtlsyminstModify()",
        "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
    err = ProDtlsyminstShow (&sym_inst);
    TEST_CALL_REPORT("ProDtlsyminstShow()",
        "ProTestSymInstModify()", err, err != PRO_TK_NO_ERROR);
    
    return (0);
}

/*===========================================================================*\
  Function : ProTestSymInstGet
  Purpose  : 
\*===========================================================================*/
ProError ProTestSymInstGet (ProDrawing drw, ProDtlsyminst *sym_inst)
{
    ProError err;
    ProSelection *p_sel;
    int n_sel;
    
    ProUtilMsgPrint("gen", "TEST %0s", "Select symbol instance");
    err = ProSelect ((char*)"dtl_symbol", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel);
    if (err != PRO_TK_NO_ERROR || n_sel < 1)
        return (PRO_TK_USER_ABORT);
        
    err = ProSelectionModelitemGet (p_sel[0], sym_inst);
    TEST_CALL_REPORT("ProSelectionModelitemGet()",
        "ProTestSymInstGet()", err, err != PRO_TK_NO_ERROR);
    
    return (PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  Function : ProTestSymInstDisplay
  Purpose  : 
\*===========================================================================*/
int ProTestSymInstDisplay (ProDrawing drw)
{
    ProError err;
    int opt = 0, size = 0, i;
    ProDtlsyminst *p_sym_inst, sym_inst;
    static ProUtilMenuButtons disp_sym_inst_opt[] = { 
        {"Display", 0, TEST_CALL_PRO_MENU_DELETE},
        {"Draw", SYM_INST_DRAW, 0},
        {"Remove", SYM_INST_REMOVE, 0},
        {"Erase", SYM_INST_ERASE, 0},
        {"Delete", SYM_INST_DELETE, 0},
        {"",0,0}
    };
    err = ProUtilMenuIntValueSelect(disp_sym_inst_opt, &opt);
    switch (opt)
    {
    case SYM_INST_DRAW :
        err = ProDrawingDtlsyminstsCollect (drw, PRO_VALUE_UNUSED, &p_sym_inst);
        TEST_CALL_REPORT("ProDrawingDtlsyminstsCollect()",
            "ProTestSymInstDisplay()", err, err != PRO_TK_NO_ERROR
            && err != PRO_TK_E_NOT_FOUND);
        if (err != PRO_TK_NO_ERROR)
            return (0);
        err = ProArraySizeGet ((ProArray)p_sym_inst, &size);
        for (i = 0; i < size; i++)
        {
            err = ProDtlsyminstDraw (&p_sym_inst[i]);
            TEST_CALL_REPORT("ProDtlsyminstDraw()",
                "ProTestSymInstDisplay()", err, err != PRO_TK_NO_ERROR);
        }
        err = ProArrayFree ((ProArray*)&p_sym_inst);
        
        break;
    case SYM_INST_REMOVE :
        err = ProTestSymInstGet (drw, &sym_inst);
        if (err != PRO_TK_NO_ERROR)
            return (0);
        err = ProDtlsyminstRemove (&sym_inst);
        TEST_CALL_REPORT("ProDtlsyminstRemove()",
            "ProTestSymInstDisplay()", err, err != PRO_TK_NO_ERROR);
        
        break;
    case SYM_INST_ERASE :
        err = ProTestSymInstGet (drw, &sym_inst);
        if (err != PRO_TK_NO_ERROR)
            return (0);
        err = ProDtlsyminstErase (&sym_inst);
        TEST_CALL_REPORT("ProDtlsyminstErase()",
            "ProTestSymInstDisplay()", err, err != PRO_TK_NO_ERROR);
        
        break;
    case SYM_INST_DELETE :
        err = ProTestSymInstGet (drw, &sym_inst);
        if (err != PRO_TK_NO_ERROR)
            return (0);
            
        err =  ProDtlsyminstErase(&sym_inst);
        TEST_CALL_REPORT("ProDtlsyminstErase()",
            "ProTestSymInstDisplay()", err, err != PRO_TK_NO_ERROR);
        err = ProDtlsyminstDelete (&sym_inst);
        TEST_CALL_REPORT("ProDtlsyminstDelete()",
            "ProTestSymInstDisplay()", err, err != PRO_TK_NO_ERROR);
        
        break;
    }
    return (0);
}

/*===========================================================================*\
  Function : ProTestSymInstInfo
  Purpose  : 
\*===========================================================================*/
int ProTestSymInstInfo (ProDrawing drw)
{
    ProDtlsyminst *p_sym_inst;
    ProError err;
    FILE *fp;
    int size = 0, i, text_size = 0, j;
    ProCharLine fname, line;
    ProDtlsyminstdata sym_data;
    ProDtlsymdefattachType def_at_type;
    double param = 0.0;
    ProBoolean  is_def = PRO_B_FALSE;
    ProDtlvartext *p_vartexts;
    ProColor color;
    ProDtlsymdef sym_def;
    ProDtlsymdefdata def_data;
    ProPath path;
    ProName inst_name;
    ProLine w_prompt, w_value;
    
    
    fp = ProUtilGenFilePtr((ProMdl)drw, (char*)DTL_SYM_INST_FILE, fname, (char*)"w");
    err = ProDrawingDtlsyminstsCollect (drw, PRO_VALUE_UNUSED, &p_sym_inst);
    TEST_CALL_REPORT("ProDrawingDtlsyminstsCollect()",
        "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR
        && err != PRO_TK_E_NOT_FOUND);
    if (err != PRO_TK_NO_ERROR)
        return (0);        
    err = ProArraySizeGet ((ProArray)p_sym_inst, &size);
    ProTKFprintf(fp, "File name : %s\n", fname);
    for (i = 0; i < size; i++)
    {
        err = ProDtlsyminstDataGet (&p_sym_inst[i], PRODISPMODE_NUMERIC,
            &sym_data);
        TEST_CALL_REPORT("ProDtlsyminstDataGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        err = ProDtlsyminstdataDefGet (sym_data, &sym_def);
        TEST_CALL_REPORT("ProDtlsyminstdataDefGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        err = ProDtlsymdefDataGet (&sym_def, &def_data);
        TEST_CALL_REPORT("ProDtlsymdefDataGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);

        err = ProTestDtlsymdefNameGet (&sym_def, inst_name);
        ProTKFprintf (fp, "\nId: %d. Name: %s. ", p_sym_inst[i].id,
            ProWstringToString (line, inst_name));
        err = ProDtlsyminstdataAttachtypeGet (sym_data, &def_at_type);
        TEST_CALL_REPORT("ProDtlsyminstdataAttachtypeGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        ProTKFprintf (fp, "Attach type: %d.\n", def_at_type);
        err = ProDtlsyminstdataElbowlengthGet (sym_data, &is_def,
            &param);
        TEST_CALL_REPORT("ProDtlsyminstdataElbowlengthGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        ProTKFprintf (fp, "Elbow length = %5.3f is def %d. ", param, is_def);
        err = ProDtlsyminstdataAngleGet (sym_data, &param);
        TEST_CALL_REPORT("ProDtlsyminstdataAngleGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        ProTKFprintf (fp, "Angle = %5.3f. ", param);
        err = ProDtlsyminstdataScaledheightGet (sym_data, &param);
        TEST_CALL_REPORT("ProDtlsyminstdataScaledheightGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        ProTKFprintf (fp, "Height = %5.3f.", param);
        err = ProDtlsyminstdataVartextsCollect (sym_data, &p_vartexts);
        TEST_CALL_REPORT("ProDtlsyminstdataVartextsCollect()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR
            && err != PRO_TK_E_NOT_FOUND);
        if (err == PRO_TK_NO_ERROR)
        {
            ProTKFprintf (fp, "\nVar text:");
            err = ProArraySizeGet ((ProArray)p_vartexts, &text_size);
            for (j = 0; j < text_size; j++)
            {
                ProDtlvartextDataGet (p_vartexts[j], w_prompt, w_value);
                ProTKFprintf (fp, "\nprompt: %s.\t", ProWstringToString (line, w_prompt));
                ProTKFprintf (fp, "value: %s", ProWstringToString (line, w_value));
            }
            for (j = 0; j < text_size; j++)
            {
                ProDtlvartextFree (p_vartexts[j]);
                TEST_CALL_REPORT("ProDtlvartextFree()",
                    "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
            }
            err = ProArrayFree ((ProArray*)&p_vartexts);
        }
        err = ProDtlsyminstdataColorGet (sym_data, &color);
        TEST_CALL_REPORT("ProDtlsyminstdataColorGet()",
            "ProTestSymInstInfo()", err, err != PRO_TK_NO_ERROR);
        ProTKFprintf (fp, "\nColor: ");
        ProTestColorPrint (fp, color);
    }
    fclose (fp);
    err = ProArrayFree ((ProArray*)&p_sym_inst);
    ProStringToWstring(path, fname);
    err = ProInfoWindowDisplay(path, NULL, NULL);
    return (0);
}
/*===========================================================================*\
  Function : ProTestDtlsymdefNameGet
  Purpose  : Temporary used, while ProDtlsymdefdataPathGet not implemented
\*===========================================================================*/
ProError ProTestDtlsymdefNameGet (
    ProDtlsymdef *p_sym_def,
    ProName name
    )
{
	ProDtlsymdefdata data;
	ProError err;

    if (p_sym_def == NULL || p_sym_def->type != PRO_SYMBOL_DEFINITION)
       return (PRO_TK_BAD_INPUTS); 

	err = ProDtlsymdefDataGet(p_sym_def, &data);

	err = ProDtlsymdefdataNameGet(data, name);

    return (PRO_TK_NO_ERROR);
}