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

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

/*--------------------------------------------------------------------*\
    ProToolkit includes
\*--------------------------------------------------------------------*/
#include <ProArray.h>
#include <ProAsmcomppath.h>
#include <ProAssembly.h>
#include <ProAsmcomp.h>
#include <ProDwgtable.h>
#include <ProDtlitem.h>
#include <ProToolkit.h>
#include <ProObjects.h>
#include <ProGraphic.h>
#include <ProSelection.h>
#include <ProMenu.h>
#include <ProMessage.h>
#include <ProModelitem.h>
#include <ProMdl.h>
#include <ProDrawing.h>
#include <ProWindows.h>
#include <ProSolid.h>
#include <ProUtil.h>
#include <ProWstring.h>

/*--------------------------------------------------------------------*\
    Application includes
\*--------------------------------------------------------------------*/
#include <TestError.h>
#include <UtilCollect.h>
#include <UtilFiles.h>
#include <UtilMessage.h>
#include <UtilString.h>
#include <UtilNames.h>
#include <UtilMenu.h>
#include <PTApplsUnicodeUtils.h>

/*--------------------------------------------------------------------*\
    Application macros
\*--------------------------------------------------------------------*/
#define TBL_INFO_NAME           "dwg_table.info"
#define TBL_CREATE_DESCENDING   1
#define TBL_CREATE_ASCENDING    2
#define TBL_CREATE_RIGHTWARD    3
#define TBL_CREATE_LEFTWARD     4
#define TBL_CREATE_NUM_CHARS    5
#define TBL_CREATE_LENGTH       6
#define TBL_DESASC_TO_STRING(x) ((x==TBL_CREATE_DESCENDING)?"down":"upper")   
#define TBL_LR_TO_STRING(x)     ((x==TBL_CREATE_LEFTWARD)?"left":"right")

/*--------------------------------------------------------------------*\
    Constants for application menu
\*--------------------------------------------------------------------*/
#define TBL_TEST_MN_CREATE             1
#define TBL_TEST_MN_DELETE             2
#define TBL_TEST_MN_UPDATE             3
#define TBL_TEST_MN_MODIFY             4
#define TBL_TEST_MN_INFO               5
#define TBL_TEST_MN_RETRIVE            6
#define TBL_TEST_MN_MOD_TABLE          7
#define TBL_TEST_MN_MOD_ROW_COL        8
#define TBL_TEST_MN_MOD_TBL_MERGE      9
#define TBL_TEST_MN_MOD_TBL_REMESH    10
#define TBL_TEST_MN_MOD_TBL_ROTATE    11
#define TBL_TEST_MN_MOD_TBL_MERGE_ROW 12
#define TBL_TEST_MN_MOD_TBL_MERGE_COL 13
#define TBL_TEST_MN_MOD_TBL_MERGE_RC  14
#define TBL_TEST_MN_MOD_TBL_INSERT    15
#define TBL_TEST_MN_MOD_TBL_REMOVE    16
#define TBL_TEST_MN_PICK_POINT        17  
#define TBL_TEST_MN_PICK_VERTEX       18
#define TBL_TEST_MN_PICK_ENTITY       19
#define TBL_TEST_MN_PICK_REL_COORDS   20 
#define TBL_TEST_MN_PICK_ABS_COORDS   21 
#define TBL_TEST_MN_MOD_TBL_ROW       22
#define TBL_TEST_MN_MOD_TBL_COL       23
#define TBL_TEST_MN_LEFT_RIGHT        24
#define TBL_TEST_MN_NUM_LEN           25
#define TBL_TEST_MN_DES_AS            26
#define TBL_TEST_MN_DONE              27


/*===========================================================================*\
  FUNCTION: ProTestTableRemesh
  PURPOSE:  merge/remesh table cells
\*===========================================================================*/
int ProTestTableRemesh(ProDrawing drawing, int opt)   
{
    ProDwgtable table;
    ProError error;
    ProSelection *sel;
    int tseg[2];
    int table_id[2];
    int i,j,n;
    int row[2], col[2];


    ProUtilMsgPrint("gen", "TEST %0s", 
	    "Pick pair of table cells");

/*--------------------------------------------------------------------*\
    Select two table cells
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"table_cell", 2, NULL, NULL, NULL, NULL, &sel, &n);
    TEST_CALL_REPORT("ProSelect()", "ProTestTableRemesh()",
	error, error!=PRO_TK_NO_ERROR);

    if ((error!=PRO_TK_NO_ERROR)||(n<2))
        return(error);

    for(j=0;j<n;j++)
    {
      error = ProSelectionUnhighlight(sel[j]);
    }

/*--------------------------------------------------------------------*\
    Get cell position
\*--------------------------------------------------------------------*/
    for (i=0; i<2; i++)    
    {
       error = ProSelectionDwgtableGet(sel[i],&table);
       TEST_CALL_REPORT("ProSelectionDwgtableGet()", "ProTestTableRemesh()",
		   error, error!=PRO_TK_NO_ERROR);

        error = ProSelectionDwgtblcellGet(sel[i], &tseg[i], &row[i], &col[i]);
        TEST_CALL_REPORT("ProSelectionDwgtblcellGet()", "ProTestTableRemesh()",
	    error, error!=PRO_TK_NO_ERROR);
        row[i]++;
        col[i]++;    
        table_id[i] = table.id;
    }
/*--------------------------------------------------------------------*\
    Both cells must be in the some table
\*--------------------------------------------------------------------*/
    if (table_id[0]!=table_id[1])
    {
        ProUtilMsgPrint("gen", "TEST %0s", 
		"Both points must be in the some table");
	return (PRO_TK_GENERAL_ERROR);
    }
    
/*--------------------------------------------------------------------*\
    Initialize table handle
\*--------------------------------------------------------------------*/
    error = ProModelitemInit((ProMdl)drawing, table_id[0], PRO_DRAW_TABLE,
	    (ProModelitem*)&table);
    TEST_CALL_REPORT("ProModelitemInit()", 
            "ProTestTableRemesh", error, error != PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Sorting the row and colums
\*--------------------------------------------------------------------*/
    if(row[1]<row[0])
    {
        i=row[0];
        row[0]=row[1];
        row[1]=i;
    }    
    if(col[1]<col[0])
    {
        i=col[0];
        col[0]=col[1];
        col[1]=i;
    }    
    switch(opt)
    {
/*--------------------------------------------------------------------*\
    Merge rows
\*--------------------------------------------------------------------*/
        case TBL_TEST_MN_MOD_TBL_MERGE_ROW:
            for (i=col[0]; i<=col[1]; i++)
            {
	        error = ProDwgtableCellsMerge(&table, i, row[0], i, row[1], 1);
		TEST_CALL_REPORT("ProDwgtableCellsMerge()", 
			    "ProTestTableRemesh", error, error != PRO_TK_NO_ERROR);
	    }
	    break;
/*--------------------------------------------------------------------*\
    Merge colums
\*--------------------------------------------------------------------*/
        case TBL_TEST_MN_MOD_TBL_MERGE_COL:
            for (i=row[0]; i<=row[1]; i++)
	    {
                error = ProDwgtableCellsMerge(&table, col[0], i, col[1], i, 1);
		TEST_CALL_REPORT("ProDwgtableCellsMerge()", 
		    "ProTestTableRemesh", error, error != PRO_TK_NO_ERROR);
	    }
            break;
/*--------------------------------------------------------------------*\
    Merge row and colums
\*--------------------------------------------------------------------*/
        case TBL_TEST_MN_MOD_TBL_MERGE_RC :
                error = ProDwgtableCellsMerge(&table, col[0], row[0], col[1], row[1], 1);
		TEST_CALL_REPORT("ProDwgtableCellsMerge()", 
			    "ProTestTableRemesh", error, error != PRO_TK_NO_ERROR);
            break;
/*--------------------------------------------------------------------*\
    Remesh table
\*--------------------------------------------------------------------*/
        case TBL_TEST_MN_MOD_TBL_REMESH:    
	    error = ProDwgtableCellsRemesh(&table, col[0], row[0], col[1], row[1], 1);
	    TEST_CALL_REPORT("ProDwgtableCellsRemesh()", 
		    "ProTestTableRemesh", error, error != PRO_TK_NO_ERROR);

            error = ProDwgtableDisplay(&table);
            TEST_CALL_REPORT ("ProDwgtableDisplay()",
                    "ProTestTableRemesh", error, error != PRO_TK_NO_ERROR);
            break;        
	default:
            ProUtilMsgPrint("gen", "TEST %0s", "Error!");
            break;
    }            

    return (PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableRotate
  PURPOSE:  Rotate selected table
\*===========================================================================*/
int ProTestTableRotate(ProDrawing drawing)
{
    ProDwgtable table;
    ProError error;
    ProSelection *sel;
    int n,j;

/*--------------------------------------------------------------------*\
    Select table for rotate
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"dwg_table", 1, NULL, NULL, NULL, NULL, &sel, &n);
    TEST_CALL_REPORT("ProSelect()", "ProTestTableRotate()",
	error, error!=PRO_TK_NO_ERROR);

    for(j=0;j<n;j++)
    {
    error = ProSelectionUnhighlight(sel[j]);
    }
    
    if((error == PRO_TK_NO_ERROR)&&(n>0))
    {
        error = ProSelectionModelitemGet(sel[0], (ProModelitem*)&table);
        TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestTableRotate()",
	        error, error!=PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Rotate table
\*--------------------------------------------------------------------*/
	error = ProDwgtableRotate(&table, 1);
	TEST_CALL_REPORT("ProDwgtableRotate()","ProTestTableRotate", 
                error, error != PRO_TK_NO_ERROR);

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

/*=================================================================*\
    FUNCTION : ProTestTableModTabMerge()
    PURPOSE  : Create "TblMerge" menu 
\*=================================================================*/
int ProTestTableModTabMerge(ProDrawing drawing)
{
    int n;
    ProError error;
    static ProUtilMenuButtons  TMenu[] ={
		{"TblMerge",  -1, TEST_CALL_PRO_MENU_DELETE},
		{"-Rows",     TBL_TEST_MN_MOD_TBL_MERGE_ROW, 0},
		{"-Columns",  TBL_TEST_MN_MOD_TBL_MERGE_COL, 0},
		{"-Row&Cols", TBL_TEST_MN_MOD_TBL_MERGE_RC,  0},
		{"-Done/Return",-1,  TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};

/*--------------------------------------------------------------------*\
    Create "TblMerge" select  "-Done/Return"  for exit from menu
\*--------------------------------------------------------------------*/
    do
    {    
        error = ProUtilMenuIntValueSelect(TMenu, &n);

        if((error!=PRO_TK_NO_ERROR)||(n<0))
            return(PRO_TK_USER_ABORT);
    
        error = (ProError)ProTestTableRemesh(drawing, n);    
        if((error!=PRO_TK_NO_ERROR) && (error != PRO_TK_USER_ABORT))
            return error;
	
    }while (error!=PRO_TK_USER_ABORT);
    
    return(PRO_TK_NO_ERROR);
}

/*=================================================================*\
    FUNCTION : ProTestTableModTabMenu()
    PURPOSE  : Create "TblModify" menu 
\*=================================================================*/
int ProTestTableModTabMenu(ProDrawing drawing)
{
    int n ;
    ProError error;
    static ProUtilMenuButtons  TMenu[] ={
		{"TblModify",  -1, TEST_CALL_PRO_MENU_DELETE},
		{"-Merge",    TBL_TEST_MN_MOD_TBL_MERGE,    0},
		{"-Remesh",   TBL_TEST_MN_MOD_TBL_REMESH,  0},
		{"-Rotate",   TBL_TEST_MN_MOD_TBL_ROTATE,  0},
		{"-Done/Return",-1,  TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};
/*--------------------------------------------------------------------*\
    Create "TblModify" select  "-Done/Return"  for exit from menu
\*--------------------------------------------------------------------*/
    do
    {
        error = ProUtilMenuIntValueSelect(TMenu, &n);
    
        if((error!=PRO_TK_NO_ERROR)||(n<0))
            return(PRO_TK_USER_ABORT);
            
        switch(n)
        {        
            case TBL_TEST_MN_MOD_TBL_REMESH:
                error = (ProError)ProTestTableRemesh(drawing, TBL_TEST_MN_MOD_TBL_REMESH);
                break;
            case TBL_TEST_MN_MOD_TBL_MERGE:
                ProTestTableModTabMerge(drawing);
                break;
            case TBL_TEST_MN_MOD_TBL_ROTATE:
                ProTestTableRotate(drawing);
                break;
        }            
        
    }while ((error == PRO_TK_NO_ERROR)&&(n>0));
    
    return(PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableInsertRemove
  PURPOSE:  insert/remove  row/col into(from) a table
\*===========================================================================*/
ProError ProTestTableInsertRemove(ProDrawing drawing, int action, int opt)
{
    ProError error;
    ProDwgtable table;
    ProSelection *sel;
    int tseg;
    int table_id;
    int row,col, n,j;
    double d, range[2]={1, 20};
    ProCharLine cstr;

    ProTKSprintf(cstr, "Pick location in the table to %s %s",
        (action == TBL_TEST_MN_MOD_TBL_INSERT) ? "insert":"remove",
        (opt == TBL_TEST_MN_MOD_TBL_ROW) ? "row" : "column");

    ProUtilMsgPrint("gen", "TEST %0s", cstr);
/*--------------------------------------------------------------------*\
    Select place in the table for insert or remove row or columns 
\*--------------------------------------------------------------------*/

    error = ProSelect((char*)"table_cell", 1, NULL, NULL, NULL, NULL, &sel, &n);
    TEST_CALL_REPORT("ProSelect()", "ProTestTableInsertRemove()",
	    error, error!=PRO_TK_NO_ERROR);

    if ((error!=PRO_TK_NO_ERROR)||(n<1))
            return(PRO_TK_USER_ABORT);

    for(j=0;j<n;j++)
    {
    error = ProSelectionUnhighlight(sel[j]);
    }
            
/*--------------------------------------------------------------------*\
    Get cell position
\*--------------------------------------------------------------------*/

    error = ProSelectionDwgtableGet(sel[0],&table);
    TEST_CALL_REPORT("ProSelectionDwgtableGet()", "ProTestTableInsertRemove()",
             error, error!=PRO_TK_NO_ERROR);

    error = ProSelectionDwgtblcellGet(sel[0], &tseg, &row, &col);
    TEST_CALL_REPORT("ProSelectionDwgtblcellGet()", "ProTestTableInsertRemove()",
	    error, error!=PRO_TK_NO_ERROR);
    row++;
    col++;
    table_id = table.id;         

    error = ProModelitemInit((ProMdl)drawing,
        table_id, PRO_DRAW_TABLE, (ProModelitem*)&table);
    TEST_CALL_REPORT("ProModelitemInit()", "ProTestTableInsertRemove()",
	    error, error!=PRO_TK_NO_ERROR);

    if (action == TBL_TEST_MN_MOD_TBL_INSERT)
    {
        if(opt == TBL_TEST_MN_MOD_TBL_ROW)
        {
/*--------------------------------------------------------------------*\
    Insert row into the table
\*--------------------------------------------------------------------*/
            ProUtilMsgPrint("gen", "TEST %0s", "Enter row height in chars");
	    if (ProMessageDoubleRead(range, &d)!=PRO_TK_NO_ERROR)
                return (PRO_TK_USER_ABORT);

            error = ProDwgtableRowAdd(&table, row, 1, d);
	    TEST_CALL_REPORT("ProDwgtableRowAdd()", 
                "ProTestTableInsertRemove()", error, error != PRO_TK_NO_ERROR);
        }
        else
        {
/*--------------------------------------------------------------------*\
    Insert col into the table
\*--------------------------------------------------------------------*/
            ProUtilMsgPrint("gen", "TEST %0s", "Enter cell width in chars");
	    if (ProMessageDoubleRead(range, &d)!=PRO_TK_NO_ERROR)
                return (PRO_TK_NO_ERROR);

            error = ProDwgtableColumnAdd(&table, col, 1,d);
	    TEST_CALL_REPORT("ProDwgtableColumnAdd()", 
                "ProTestTableInsertRemove()", error, error != PRO_TK_NO_ERROR);
        }
    }
    else
    {
        ProTKSprintf(cstr, "Do you really want to remove the %0s? [N]:", 
            (opt == TBL_TEST_MN_MOD_TBL_ROW) ? "row" : "column");
	ProUtilMsgPrint("gen", "TEST %0s", cstr);

	if (ProUtilYesnoGet((char*)"yes")==0)
            return (PRO_TK_USER_ABORT);
            
	if (opt == TBL_TEST_MN_MOD_TBL_ROW)
	{
/*--------------------------------------------------------------------*\
    Remove row from the table
\*--------------------------------------------------------------------*/
		error = ProDwgtableRowDelete(&table, row, 1);
		TEST_CALL_REPORT("ProDwgtableRowDelete()", 
		    "ProTestTableInsertRemove()", error, error != PRO_TK_NO_ERROR);
	} 
	else
	{
/*--------------------------------------------------------------------*\
    Remove column from the table
\*--------------------------------------------------------------------*/
		error = ProDwgtableColumnDelete(&table, col, 1);
		TEST_CALL_REPORT("ProDwgtableColumnDelete()", 
		    "ProTestTableInsertRemove()", error, error != PRO_TK_NO_ERROR);
	}
    }
    
    return (PRO_TK_NO_ERROR);
}

/*=================================================================*\
    FUNCTION : ProTestTableInsertRemoveMenu()
    PURPOSE  : Create "TblInsRm" menu 
\*=================================================================*/
ProError ProTestTableInsertRemoveMenu(ProDrawing drawing)
{
    int n1, n2;
    ProError error;
    static ProUtilMenuButtons  TMenu1[] ={
		{"TblInsRm",  -1, TEST_CALL_PRO_MENU_DELETE},
		{"-Insert",  TBL_TEST_MN_MOD_TBL_INSERT, 0},
		{"-Remove",  TBL_TEST_MN_MOD_TBL_REMOVE, 0},
		{"-Done/Return",-1,  TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};

    static ProUtilMenuButtons  TMenu2[] ={
		{"TblRowCol",  -1, TEST_CALL_PRO_MENU_DELETE},
		{"-Row",  TBL_TEST_MN_MOD_TBL_ROW, 0},
		{"-Col",  TBL_TEST_MN_MOD_TBL_COL, 0},
		{"-Done/Return",-1,  TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};
/*--------------------------------------------------------------------*\
    Show "Insert/Remove" menu  
\*--------------------------------------------------------------------*/
    do
    {
        error = ProUtilMenuIntValueSelect(TMenu1, &n1);

        if((error!=PRO_TK_NO_ERROR)||(n1<0))
            return(PRO_TK_NO_ERROR);
        
        do
        {        
            error = ProUtilMenuIntValueSelect(TMenu2, &n2);
            
            if((error!=PRO_TK_NO_ERROR)||(n2<0))
                break;
            
            error = ProTestTableInsertRemove(drawing, n1, n2);
            
        } while((error==PRO_TK_NO_ERROR));
        
    }while(1);
    return (error);      
}

/*=================================================================*\
    FUNCTION : ProTestTableModifyMenu()
    PURPOSE  : Create "TkModify" menu 
\*=================================================================*/
int ProTestTableModifyMenu(ProDrawing drawing)
{
    int n;
    ProError error;
    static ProUtilMenuButtons  TMenu[] ={
		{"TkModify",     -1, TEST_CALL_PRO_MENU_DELETE},
		{"-Table",      TBL_TEST_MN_MOD_TABLE,    0},
		{"-Row/Cols",   TBL_TEST_MN_MOD_ROW_COL,  0},
		{"-Done/Return",-1,  TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};

/*--------------------------------------------------------------------*\
    Show "TkModify" menu  
\*--------------------------------------------------------------------*/
    error = ProUtilMenuIntValueSelect(TMenu, &n);

    if((error!=PRO_TK_NO_ERROR)||(n<0))
        return(PRO_TK_NO_ERROR);
        
    switch(n)
    {        
        case TBL_TEST_MN_MOD_TABLE:
            ProTestTableModTabMenu(drawing);
            break;
        case TBL_TEST_MN_MOD_ROW_COL:
            ProTestTableInsertRemoveMenu(drawing);
            break;
    }            
    return(PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableDelete
  PURPOSE:  delete the table from drawing
\*===========================================================================*/
int ProTestTableDelete(ProDrawing drawing)
{
    ProError error;
    ProDwgtable table;
    ProSelection *sel;
    int n,j;

    ProUtilMsgPrint("gen", "TEST %0s", "Pick the table to be deleted.");
    
/*--------------------------------------------------------------------*\
    Select table for delete
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"dwg_table", 1, NULL, NULL, NULL, NULL, &sel, &n);
    TEST_CALL_REPORT("ProSelect()", "ProTestTableDelete()",
	error, error!=PRO_TK_NO_ERROR);
    
    for(j=0;j<n;j++)
    {
    error = ProSelectionUnhighlight(sel[j]);
    }

    if((error == PRO_TK_NO_ERROR)&&(n>0))
    {
	ProUtilMsgPrint("gen", "TEST %0s", "Do you really want to delete the table [N]:");
	if (ProUtilYesnoGet((char*)"yes")==1)
        {
            error = ProSelectionModelitemGet(sel[0], (ProModelitem*)&table);
            TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestTableDelete()",
	        error, error!=PRO_TK_NO_ERROR);

/*--------------------------------------------------------------------*\
    Delete selected table
\*--------------------------------------------------------------------*/
            error = ProDwgtableDelete(&table, 1);
            TEST_CALL_REPORT("ProDwgtableDelete()", "ProTestTableDelete()",
	        error, error!=PRO_TK_NO_ERROR);
        }    
    }
        
    return (PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableInfo
  PURPOSE:  list parameters of table
\*===========================================================================*/
int ProTestTableInfo (ProDrawing drawing)
{
    ProPath  f_name;
    ProCharLine cstr;    
    int  i, j, cur_sheet, n, ncols, nrows,k;
    FILE *fp;
    ProDwgtableInfo table_info;
    ProDwgtable table;	
    ProBoolean  from_format, is_comment;
    ProAsmcomppath component;
    ProError error;
    ProMdldata mdl_data;
    ProMdl     mdl;
    ProSelection *sel;
    double sw, sl;
	ProMdlName modelName;
    
/*--------------------------------------------------------------------*\
    Get current sheet number
\*--------------------------------------------------------------------*/
    error = ProDrawingCurrentSheetGet(drawing, &cur_sheet);
    TEST_CALL_REPORT ("ProDrawingCurrentSheetGet()",
        "ProTestTableInfo()", error, error!=PRO_TK_NO_ERROR);

    ProUtilMsgPrint("gen", "TEST %0s", "Select a drawing table to parameters listing");

/*--------------------------------------------------------------------*\
    Select table from the current drawing
\*--------------------------------------------------------------------*/
    error = ProSelect((char*)"dwg_table", 1, NULL, NULL, NULL, NULL, &sel, &n);
    TEST_CALL_REPORT("ProSelect()", "ProTestTableInfo()",
	    error, error!=PRO_TK_NO_ERROR);
            
    if((error!=PRO_TK_NO_ERROR)||(n<1))
        return (PRO_TK_GENERAL_ERROR);

    for(k=0;k<n;k++)
    {
    error = ProSelectionUnhighlight(sel[k]);
    }

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

/*--------------------------------------------------------------------*\
    Open file for output information about selected table
\*--------------------------------------------------------------------*/
    fp = PTApplsUnicodeFopen(TBL_INFO_NAME, "w");
    if (fp == NULL)
       return (PRO_TK_GENERAL_ERROR);

/*--------------------------------------------------------------------*\
    Get parameters of table.
\*--------------------------------------------------------------------*/
    ProTKFprintf (fp, "Table %d.\n", table.id);
            
    error = ProDwgtableRowsCount (&table, &nrows);
    TEST_CALL_REPORT("ProDwgtableRowsCount()", "ProTestTableInfo()",
        error, error!=PRO_TK_NO_ERROR);
    ProTKFprintf (fp, "Number of row %d. ", nrows);

    error = ProDwgtableColumnsCount (&table, &ncols);
    TEST_CALL_REPORT("ProDwgtableColumnsCount()", "ProTestTableInfo()",
        error, error!=PRO_TK_NO_ERROR);
    ProTKFprintf (fp, "Number of column %d\n", ncols);

/*--------------------------------------------------------------------*\
    Calculate table size
\*--------------------------------------------------------------------*/
    for(i=0, sw=0; i<nrows; i++) 
    {
        error = ProDwgtableRowSizeGet(&table, 0, i, &sw);
        TEST_CALL_REPORT("ProDwgtableRowSizeGet()", "ProTestTableInfo()",
            error, error!=PRO_TK_NO_ERROR);
        sw+=sw;
    }

    for(i=0, sl=0; i<ncols; i++) 
    {
        error = ProDwgtableColumnSizeGet(&table, 0, i, &sl);
        TEST_CALL_REPORT("ProDwgtableColumnSizeGet()", "ProTestTableInfo()",
            error, error!=PRO_TK_NO_ERROR);
        sl+=sl;
    }

    ProTKFprintf(fp,"Table size: %3.3f X %3.3f\n",sw,sl);
    
    error = ProDwgtableInfoGet(&table, 0, &table_info);
    TEST_CALL_REPORT("ProDwgtableColumnsCount()", "ProTestTableInfo()",
        error, error!=PRO_TK_NO_ERROR);
        
    ProTKFprintf (fp, "Seg origin %f, %f, %f\n", table_info.seg_origin[0],
            table_info.seg_origin[1], table_info.seg_origin[2]);
    ProTKFprintf (fp, "Height of char in table %f, in segment %f. ",
            table_info.table_char_height, table_info.seg_char_height);
    ProTKFprintf (fp, "Width of char %f.\n", table_info.char_width);
    ProTKFprintf (fp, "Rotation of the table  %d.\n", table_info.rotation);
/*--------------------------------------------------------------------*\
    Get associating of table and format on current sheet.
\*--------------------------------------------------------------------*/

    error = ProDwgtableIsFromFormat(&table, &from_format);
    TEST_CALL_REPORT ("ProDwgtableIsFromFormat()",
            "ProTestTableInfo()",error, error!=PRO_TK_NO_ERROR);

    ProTKFprintf (fp, "%s",(from_format)?("Is"):("Not"));
    ProTKFprintf (fp, " associated with the format on %d sheet.\n", cur_sheet);
    ProTKFprintf (fp, "\tcell is comment/path length(top model of region->");
    ProTKFprintf (fp, "the model of the record of the cell)\n");

    for (j=1; j<=table_info.nrows; j++)
    {
        for (i=1; i<=table_info.ncols; i++)
        { 
            error = ProDwgtableCellIsComment(&table, i, j, &is_comment);
            TEST_CALL_REPORT ("ProDwgtableCellIsComment()",
                "ProTestTableInfo()", error, error!=PRO_TK_NO_ERROR);

            ProTKFprintf (fp,"\t%s/",(is_comment)?"yes":"no");
/*--------------------------------------------------------------------*\
    Get specified member identifier table.
\*--------------------------------------------------------------------*/
	    error = ProDwgtableCellComponentGet(&table, i, j, &component);
            TEST_CALL_REPORT ("ProDwgtableCellComponentGet()",
                    "ProTestTableInfo()", error, error == PRO_TK_NO_ERROR);
	    ProTKFprintf (fp, "%d", component.table_num);		
/*--------------------------------------------------------------------*\
    Get a model pointer by decoding a cell in a repeat region.
\*--------------------------------------------------------------------*/
            if (error != PRO_TK_NO_ERROR)
            { 
                ProTKFprintf (fp, "(none->none)");
            }
            else
            {
		error = ProMdlMdlnameGet(component.owner, modelName);
                TEST_CALL_REPORT ("ProMdlMdlnameGet()",
                       "ProTestTableInfo()", error, error != PRO_TK_NO_ERROR);

                ProTKFprintf (fp, "(%s->", ProWstringToString(cstr, modelName));

		error = ProAsmcomppathMdlGet(&component, &mdl);
		TEST_CALL_REPORT ("ProAsmcomppathMdlGet()",
			"ProTestTableInfo()", error, error != PRO_TK_NO_ERROR);

		error = ProMdlMdlnameGet(mdl, modelName);
                TEST_CALL_REPORT ("ProMdlMdlnameGet()",
                       "ProTestTableInfo()", error, error != PRO_TK_NO_ERROR);

                    ProTKFprintf (fp, "%s)", ProWstringToString(cstr, modelName));
            }
        }

    ProTKFprintf (fp,"\n");
    }
        
    fclose (fp);
    
/*--------------------------------------------------------------------*\
    Display information
\*--------------------------------------------------------------------*/
    error = ProInfoWindowDisplay(ProStringToWstring(f_name,(char*)TBL_INFO_NAME),NULL,NULL);
    TEST_CALL_REPORT ("ProInfoWindowDisplay()","ProTestTableInfo()", 
        error, error != PRO_TK_NO_ERROR);
    
    return (PRO_TK_NO_ERROR);
}
 
/*===========================================================================*\
  FUNCTION: ProTestTableRetrieve
  PURPOSE:  retrieve table from disk
\*===========================================================================*/
int ProTestTableRetrieve(ProDrawing drawing)
{
    ProError error;
    ProDwgtable table;
    ProCharLine f_name, c_name;
    ProPath w_full_name, w_path;
    ProMdlName w_name;
	ProMdlExtension w_type;
    int ver, mdl_num,i;
    ProMouseButton but;
    ProPoint3d point;
    ProMdl  mdl = NULL, *mdl_arr = NULL;

/*--------------------------------------------------------------------*\
    Display information
\*--------------------------------------------------------------------*/
    error = ProUtilFileOpen((char*)"*.tbl", f_name);
    
    if(error!=PRO_TK_NO_ERROR)
        return(error);
        
    ProUtilMsgPrint("gen", "TEST %0s", "Select table origin.");

/*--------------------------------------------------------------------*\
    Collect all models in the current session
\*--------------------------------------------------------------------*/
    error = ProSessionMdlList ( PRO_MDL_ASSEMBLY, &mdl_arr, &mdl_num);
    
    if (error == PRO_TK_NO_ERROR && mdl_num>0)
    {
        for (i=0; i<mdl_num; i++)
        {
            error = ProMdlMdlnameGet (mdl_arr[i], w_name);
            TEST_CALL_REPORT("ProMdlMdlnameGet()", "ProTestTableRetrieve()", 
	        error, error != PRO_TK_NO_ERROR);
            
	    ProTKSprintf(c_name,"Copy data into table from model %s:", 
		ProWstringToString (c_name, w_name));

	    ProUtilMsgPrint("gen", "TEST %0s", c_name);

	    if (ProUtilYesnoGet((char*)"yes")==1)
            {
                mdl = mdl_arr[i];
                break;
            }   
        } 
    }
    error = ProMousePickGet(PRO_LEFT_BUTTON, &but, point);
    TEST_CALL_REPORT("ProMousePickGet()", "ProTestTableRetrieve()", 
	error, error != PRO_TK_NO_ERROR);

    if (error == PRO_TK_NO_ERROR)
    {
    
	error = ProFileMdlnameParse(ProStringToWstring(w_full_name, f_name), 
                w_path, w_name, w_type, &ver);
	TEST_CALL_REPORT("ProFileMdlnameParse()", "ProTestTableRetrieve()", 
		error, error != PRO_TK_NO_ERROR);
                
/*--------------------------------------------------------------------*\
    Retrive table from the disk
\*--------------------------------------------------------------------*/
        error = ProDwgtableRetrieve((ProDrawing)drawing,
	        w_name, w_path, ver, point,(ProSolid) mdl, NULL, &table);
        TEST_CALL_REPORT("ProDwgtableRetrieve()", "ProTestTableRetrieve()", 
                error, error!=PRO_TK_NO_ERROR);
        if (error == PRO_TK_NO_ERROR)
        {
            error = ProDwgtableDisplay(&table);
            TEST_CALL_REPORT("ProDwgtableDisplay()", "ProTestTableRetrieve()", 
                error, error!=PRO_TK_NO_ERROR);
        }        
                
    }

    return (PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableSizeByLenGet
  PURPOSE:  Get table cols width
\*===========================================================================*/
ProError ProTestTableSizeByLenGet(double *width, double *height, int *ncols, int *nrows)
{ 
    double d=0;
    double range[2]={1e-9, 1e3};
    
    *ncols=*nrows=0;

    if((width == NULL)||(height == NULL)||(ncols == NULL)||(nrows == NULL))
        return(PRO_TK_BAD_INPUTS);
        
    ProUtilMsgPrint("gen", "TEST %0s",
	    "Enter the width of the first column in the drawing units ( INCH ) [QUIT]:");

    if (ProMessageDoubleRead(range, &d)!=PRO_TK_NO_ERROR)
        return (PRO_TK_BAD_INPUTS);
            
    width[(*ncols)++] =  d;
    while (*ncols<PRO_TABLE_MAX_COLS)
    {
        ProUtilMsgPrint("gen", "TEST %0s",
		"Enter the width of the next column in the drawing units ( INCH ) [DONE]:");

        if (ProMessageDoubleRead(range, &d)!=PRO_TK_NO_ERROR)
    	    break;
	width[(*ncols)++] =  d;
    }
    
    ProUtilMsgPrint("gen", "TEST %0s",
	"Enter the height of the first row in the drawing units( INCH ) [QUIT]:");

    if (ProMessageDoubleRead(range, &d)!=PRO_TK_NO_ERROR)
	    return (PRO_TK_BAD_INPUTS);
            
    height[(*nrows)++] =  d;
    
    while (*nrows<PRO_TABLE_MAX_ROWS)
    {
        ProUtilMsgPrint("gen", "TEST %0s",
            "Enter the height of the next row in the drawing units ( INCH ) [DONE]:");

	if (ProMessageDoubleRead(range, &d)!=PRO_TK_NO_ERROR)
		break;
                
	height[(*nrows)++] =  d;
    }
    
    return(PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableLength
  PURPOSE:  Return table length or width
\*===========================================================================*/
double ProTestTableLength(double *width, int ncols)
{   int i;
    double d=0;

    if (width == NULL)
        return(0.0);
        
    for (i=0; i<ncols; i++)
	d += width[i];
        
    return(d);
}

/*===========================================================================*\
  FUNCTION: ProTestTableFlip
  PURPOSE:  Flip table
\*===========================================================================*/
ProError ProTestTableFlip(double *width, int ncols)
{   int i;
    double d;
    
    for (i=0; i<ncols/2; i++)
    {
        d = width[i];
	width[i] = width[ncols-1-i];
	width[ncols-1-i] = d;
    }
    
    return(PRO_TK_NO_ERROR);    
}

/*===========================================================================*\
  FUNCTION: ProTestTableCreate
  PURPOSE:  create table
\*===========================================================================*/
int ProTestTableCreate(ProDrawing drw,
        int right_left,
        int desc_asc,
        int num_len)
{
    static char *size=(char*)"123456789012345678901234567890";
    static char *sizo=(char*)"098765432109876543210987654321";
    double d, k;
    ProMatrix matrix;
    double width[PRO_TABLE_MAX_COLS], 
	   height[PRO_TABLE_MAX_ROWS]; 
    ProHorzJust justifications[PRO_TABLE_MAX_COLS]; 
    double sw, sh;
    ProPoint2d arr[4];
    ProPoint3d point, pos ={0.0, 0.0, 0.0};
    ProDwgtabledata table_data;
    wchar_t w_size[PRO_NAME_SIZE];
    ProTextAttribute text_attr;
    ProDwgtable table;
    ProColor old_color, old_color0;
	ProColor drawing_color, background_color;
    ProError error;
    int sign = 1, start=0;
    int  ncols=0, nrows=0, i, len;
    ProMouseButton but;
    ProPoint3d origin;
	
	drawing_color.method = PRO_COLOR_METHOD_TYPE;
	drawing_color.value.type = PRO_COLOR_DRAWING;
	
	background_color.method = PRO_COLOR_METHOD_TYPE;
	background_color.value.type = PRO_COLOR_BACKGROUND;
    
/*--------------------------------------------------------------------*\
    Get current transformation matrix
\*--------------------------------------------------------------------*/
    error = ProWindowCurrentMatrixGet(matrix);
    TEST_CALL_REPORT("ProWindowCurrentMatrixGet()", 
	"ProTestTableCreate", error, error != PRO_TK_NO_ERROR);
    k=matrix[0][0];
    
    ProUtilMsgPrint("gen", "TEST %0s", "Select table origin.");
    error = ProMousePickGet(PRO_LEFT_BUTTON, &but, origin);
    
    if (num_len == TBL_CREATE_LENGTH)
    {
/*--------------------------------------------------------------------*\
    Table created by length
\*--------------------------------------------------------------------*/
        
        if(ProTestTableSizeByLenGet(width, height, &ncols, &nrows)!=PRO_TK_NO_ERROR)
            return (PRO_TK_GENERAL_ERROR);
        
	if (right_left == TBL_CREATE_LEFTWARD)
	{
            d=ProTestTableLength(width,ncols);
	    origin[0] -= d/k; 
	}
        
	if (desc_asc == TBL_CREATE_LEFTWARD)
	{
            d=ProTestTableLength(height, nrows); 
	    origin[1] += d/k; 
	}
    }
    else
    {
/*--------------------------------------------------------------------*\
    Get  current text attributes
\*--------------------------------------------------------------------*/
	error = ProTextAttributesCurrentGet(&text_attr);
        TEST_CALL_REPORT ("ProTextAttributesCurrentGet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);
	sh = text_attr.height;
	sw = text_attr.height*0.5;
        
	memcpy(pos, origin, sizeof(double)*3);
        
	if (right_left == TBL_CREATE_LEFTWARD)
	    sign = -1;
            
	error = ProGraphicsColorModify(&background_color, &old_color0);
        TEST_CALL_REPORT ("ProGraphicsColorModify()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	len = strlen(size); 

	while (ncols<PRO_TABLE_MAX_COLS)
	{
	    if (ncols>0)
	    {
		error = ProGraphicsPolygonDraw(arr, 4, PRO_COLOR_BACKGROUND);
	        TEST_CALL_REPORT ("ProGraphicsPolygonDraw()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    }
	    error = ProGraphicsColorModify(&drawing_color, &old_color);
            TEST_CALL_REPORT ("ProGraphicsColorModify()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    ProGraphicsPenPosition(pos);
	    pos[1]-=sh;
	    ProGraphicsLineDraw(pos);
	    pos[1]+=sh;
	    error = ProGraphicsColorModify(&background_color, &old_color);
            TEST_CALL_REPORT ("ProGraphicsColorModify()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    ProUtilMsgPrint("gen", "TEST %0s", (ncols == 0) ? 
		(" Mark off the %0s of the first column. (Middle buton - to quit.)"): 
		(" Mark the next column. (Middle buton - to quit.) width Enter the height of the next row in the drawing units ( INCH ) [DONE]:"));

    	    memcpy(point, pos, sizeof(double)*3);

	    if (right_left == TBL_CREATE_LEFTWARD)
	    {
		point[0] -= sw * len;
		error = ProGraphicsTextDisplay(point, ProStringToWstring(w_size, sizo));
                TEST_CALL_REPORT ("ProGraphicsTextDisplay()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    }
	    else
	    {
		error = ProGraphicsTextDisplay(pos, ProStringToWstring(w_size, size));
                TEST_CALL_REPORT ("ProGraphicsTextDisplay()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    }
            
	    arr[0][0] = arr[3][0] = point[0];
	    arr[1][0] = arr[2][0] = point[0] + sw*len;
    	    arr[0][1] = arr[1][1] = point[1];
	    arr[2][1] = arr[3][1] = point[1] + sh;

	    error = ProMousePickGet(PRO_ANY_BUTTON, &but, point);
            TEST_CALL_REPORT ("ProMousePickGet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    if ((error!=PRO_TK_NO_ERROR)||(but == PRO_MIDDLE_BUTTON))
	    	break;
                
	    if ((point[0]-pos[0])*sign<=sw)
	    {
		ProUtilMsgPrint("gen", "TEST %0s", "Less than minimal size - ignored.");
		continue;
	    }
            
	    width[ncols] = (point[0]-pos[0])*sign/sw;
	    pos[0] += width[ncols]*sw*sign;
            
	    ncols++;
	}
	error = ProGraphicsPolygonDraw(arr, 4, PRO_COLOR_BACKGROUND);
        TEST_CALL_REPORT ("ProGraphicsPolygonDraw()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	sign  = (desc_asc == TBL_CREATE_DESCENDING) ?  -1: 1;
	start = (desc_asc == TBL_CREATE_DESCENDING) ?  0: 1;
	len = 5;

	if (ncols!=0) while (nrows<PRO_TABLE_MAX_ROWS)
	{
	    if (nrows>0)
	    {
		error = ProGraphicsPolygonDraw(arr, 4, PRO_COLOR_BACKGROUND);
	        TEST_CALL_REPORT ("ProGraphicsPolygonDraw()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);
	    }
            
	    error = ProGraphicsColorModify(&drawing_color, &old_color);
            TEST_CALL_REPORT ("ProGraphicsColorModify()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    pos[0]+=sw;
	    ProGraphicsPenPosition(pos);
	    pos[0]+=sw;
	    ProGraphicsLineDraw(pos);
	    pos[0]-=2*sw;
	    error = ProGraphicsColorModify(&background_color, &old_color);
            TEST_CALL_REPORT ("ProGraphicsColorModify()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    ProUtilMsgPrint("gen", "TEST %0s", (nrows == 0) ? 
		("USER Mark off the %0s of the first column. (Middle buton - to quit.)"): 
		("USER Mark the next column. (Middle buton - to quit.) height"));
    	    
	    for (i=0; i<len; i++)
	    {
		char sym[2];

		sym[0] = size[i];
		sym[1] = '\0';

		memcpy(point, pos, sizeof(double)*3);
		point[1] += (i+start)*sign*sh;
		ProGraphicsTextDisplay(point, ProStringToWstring(w_size, sym));
	    }

	    memcpy(point, pos, sizeof(double)*3);
	    arr[0][0] = arr[3][0] = point[0];
	    arr[1][0] = arr[2][0] = point[0] + sw;
    	    arr[0][1] = arr[1][1] = point[1] + sh*start;
	    arr[2][1] = arr[3][1] = point[1] + sh*(len+start)*sign;

	    error = ProMousePickGet(PRO_ANY_BUTTON, &but, point);
            TEST_CALL_REPORT ("ProMousePickGet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	    if ((error!=PRO_TK_NO_ERROR)||(but == PRO_MIDDLE_BUTTON))
	    	break;

	    if ((point[1]-pos[1])*sign<=sh)
	    {
		ProUtilMsgPrint("gen", "TEST %0s", "Less than minimal size - ignored.");
		continue;
	    }
	    height[nrows] = (point[1]-pos[1])*sign/sh;
	    pos[1] += ((height[nrows]+0)*sh )*sign;
	    nrows++;
	}
	if (ncols!=0)
	{
	    error = ProGraphicsPolygonDraw(arr, 4, PRO_COLOR_BACKGROUND);
            TEST_CALL_REPORT ("ProGraphicsPolygonDraw()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	}
	error = ProGraphicsColorModify(&old_color0, &old_color);
        TEST_CALL_REPORT ("ProGraphicsColorModify()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	if ((ncols >0) && (nrows>0))
	{
	    if (right_left == TBL_CREATE_LEFTWARD)
	    {
		d=ProTestTableLength(width,ncols);
		origin[0] -= d*sw; 
	    }
	    if (desc_asc == TBL_CREATE_ASCENDING)
	    {
		d=ProTestTableLength(height,nrows);
		origin[1] += d*sh; 
	    }
	}
    }
/*--------------------------------------------------------------------*\
    Create table
\*--------------------------------------------------------------------*/
    if (ncols>0 && nrows>0)
    {
	if (right_left == TBL_CREATE_LEFTWARD)
            error = ProTestTableFlip(width, ncols);

	if (desc_asc == TBL_CREATE_ASCENDING)
            error = ProTestTableFlip(height, nrows);

	error = ProDwgtabledataAlloc(&table_data);
        TEST_CALL_REPORT ("ProDwgtabledataAlloc()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);
	if(error!=PRO_TK_NO_ERROR)
	    return (PRO_TK_GENERAL_ERROR);
            
	error = ProDwgtabledataOriginSet(table_data, origin);
        TEST_CALL_REPORT ("ProDwgtabledataOriginSet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	for (i=0; i<ncols; i++) justifications[i] = PROHORZJUST_LEFT;
	error = ProDwgtabledataColumnsSet(table_data, ncols, 
	    width, justifications);
        TEST_CALL_REPORT ("ProDwgtabledataColumnsSet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	error = ProDwgtabledataRowsSet(table_data, nrows, height);
        TEST_CALL_REPORT ("ProDwgtabledataColumnsSet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);
	error = ProDwgtabledataSizetypeSet(table_data, PRODWGTABLESIZE_CHARACTERS);
        TEST_CALL_REPORT ("ProDwgtabledataSizetypeSet()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);

	error = ProDrawingTableCreate((ProDrawing)(drw), table_data, 1, &table);
        TEST_CALL_REPORT ("ProDrawingTableCreate()",
                    "ProTestTableCreate()", error, error != PRO_TK_NO_ERROR);
    }
    return (PRO_TK_NO_ERROR);
}

/*===========================================================================*\
  FUNCTION: ProTestTableCreateMenu
  PURPOSE:  Show "table create" menu
\*===========================================================================*/
ProError ProTestTableCreateMenu(ProDrawing drawing,
        int opt_left_right,
        int opt_des_as,
        int opt_num_len)
{
    int n;
    ProError error;
    int left_right=(opt_left_right==-1)?TBL_CREATE_RIGHTWARD:opt_left_right;
    int des_as=(opt_des_as==-1)?TBL_CREATE_DESCENDING:opt_des_as;
    int num_len=(opt_num_len==-1)?TBL_CREATE_NUM_CHARS:opt_num_len;
    
    static ProUtilMenuButtons  TMenu[] ={
		{"TkTblCreate", -1, TEST_CALL_PRO_MENU_DELETE},
		{"",      TBL_TEST_MN_LEFT_RIGHT, 0},
		{"",      TBL_TEST_MN_DES_AS,     0},
		{"",      TBL_TEST_MN_NUM_LEN,    0},
		{"-Done", TBL_TEST_MN_DONE,       0},
		{"-Quit",    -1,TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};
    
    ProTKSprintf(TMenu[1].button,"%s",(left_right==TBL_CREATE_RIGHTWARD)?"-rightward":"-leftward");
    ProTKSprintf(TMenu[2].button,"%s",(des_as==TBL_CREATE_DESCENDING)?"-descending":"-ascending");
    ProTKSprintf(TMenu[3].button,"%s",(num_len==TBL_CREATE_NUM_CHARS)?"-by num chars":"-by length");
    
    error = ProUtilMenuIntValueSelect(TMenu, &n);

    if((error!=PRO_TK_NO_ERROR)||(n<0))
        return(PRO_TK_USER_ABORT);
        
    if(n!=TBL_TEST_MN_DONE)
    {
        switch(n)    
        {
            case TBL_TEST_MN_LEFT_RIGHT:
                left_right=(left_right==TBL_CREATE_RIGHTWARD)?
                        TBL_CREATE_LEFTWARD:TBL_CREATE_RIGHTWARD;
                break;
            case TBL_TEST_MN_DES_AS:       
                des_as=(des_as==TBL_CREATE_DESCENDING)?
                        TBL_CREATE_ASCENDING:TBL_CREATE_DESCENDING;    
                break;
            case TBL_TEST_MN_NUM_LEN:
                num_len=(num_len==TBL_CREATE_NUM_CHARS)?
                        TBL_CREATE_LENGTH:TBL_CREATE_NUM_CHARS;                   
                break;
        }

        if(ProTestTableCreateMenu(drawing,
           left_right, des_as, num_len)!=PRO_TK_NO_ERROR)
                return(PRO_TK_USER_ABORT);
    }
    else
    {   
        ProTestTableCreate(drawing, left_right, des_as, num_len);
	error = ProWindowRepaint(PRO_VALUE_UNUSED);
	TEST_CALL_REPORT("ProWindowRepaint()","ProTestTableCreateMenu", 
                error, error != PRO_TK_NO_ERROR);
        
        error = ProTestTableCreateMenu(drawing,left_right, des_as, num_len);
    }    

    return(PRO_TK_NO_ERROR);
} 
 
/*=================================================================*\
    FUNCTION : ProTestDrwTable()
    PURPOSE  : Create main menu for Table test
\*=================================================================*/
ProError ProTestDrwTable()
{
    int n;
    ProError error;
    ProDrawing drawing;
    static ProUtilMenuButtons  TMenu[] ={
		{"TkTable",    -1, TEST_CALL_PRO_MENU_DELETE},
		{"-Create",     TBL_TEST_MN_CREATE,  0},
		{"-Delete",     TBL_TEST_MN_DELETE,  0},
		{"-Modify",     TBL_TEST_MN_MODIFY,  0},
		{"-Info",       TBL_TEST_MN_INFO,    0},
/*		{"-Retrive",    TBL_TEST_MN_RETRIVE, 0}, */
		{"-UpDate",     TBL_TEST_MN_UPDATE, 0},
		{"-Done/Return",-1,  TEST_CALL_PRO_MENU_DELETE},
		{"",      -1,0}};
    do
    {
        error = ProUtilMenuIntValueSelect(TMenu, &n);

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

        error = ProMdlCurrentGet((ProMdl*)&drawing);
        TEST_CALL_REPORT ("ProMdlCurrentGet()",
            "ProTestTblMainMenu()", error, error != PRO_TK_NO_ERROR);            
        
        switch(n)
        {        
            case TBL_TEST_MN_CREATE:   
                ProTestTableCreateMenu(drawing, -1,-1,-1);
                break;
            case TBL_TEST_MN_DELETE:
                ProTestTableDelete(drawing);
                break;
            case TBL_TEST_MN_MODIFY:
                ProTestTableModifyMenu(drawing);
                break;
            case TBL_TEST_MN_INFO:
                ProTestTableInfo(drawing);
                break;
/*--------------------------------------------------------------------*\
    Table retrive temporary disable
\*--------------------------------------------------------------------*/
/*
        case TBL_TEST_MN_RETRIVE:
            ProTestTableRetrieve(drawing);
            break;
*/
            case TBL_TEST_MN_UPDATE:
                error = ProDrawingTablesUpdate(drawing);
                TEST_CALL_REPORT ("ProDrawingTablesUpdate()",
                    "ProTestTblMainMenu()", error, error != PRO_TK_NO_ERROR);            
                break;                   
        }
    } while(1);        
    return (error);    
}