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



/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProEdgedata.h>
#include <ProFeatType.h>
#include <ProFeature.h>
#include <ProIntfData.h>
#include <ProImportfeat.h>
#include <ProQuiltdata.h>
#include <ProSolid.h>
#include <ProSurfacedata.h>
#include <ProUtil.h>

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

/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "UtilMenu.h"
#include "UtilMessage.h"
#include "UtilCollect.h"
#include <PTApplsUnicodeUtils.h>
#include <ProTKRunTime.h>
#include <ProMenu.h>
#include <TestDbms.h>

#define NEW_PART_NAME "new_impfeat_part"

#define UV_POINTS 1
#define UV_CURVES 2
#define XYZ_CURVE 4

#define JOIN_SURFACES 1
#define MAKE_SOLID    2
#define ADD_SOLID     4

static int  cr_type = UV_POINTS | UV_CURVES | XYZ_CURVE;
static  ProPartConversionOptions opt = { {1, 1, 1}, PRO_PART_CURVES_AS_DEFAULT,
    PRO_PART_SURFACES_AS_DEFAULT }; 

/*====================================================================*\
    FUNCTION :  ProUtilIntfTypeToStr()
    PURPOSE  :  convert ProIntfType to str
                Must contain same intf types as in ProTestSelectIntfType()
\*====================================================================*/
char * ProUtilIntfTypeToStr(ProIntfType type)
{
  int i;
  static struct intf_type_str
  {
    ProIntfType type;
    char *str;
  } tab[] = {
    {PRO_INTF_NONE, (char *)"PRO_INTF_NONE"},
    {PRO_INTF_NEUTRAL, (char *)"PRO_INTF_NEUTRAL"},
    {PRO_INTF_NEUTRAL_FILE, (char *)"PRO_INTF_NEUTRAL_FILE"},
    {PRO_INTF_IGES, (char *)"PRO_INTF_IGES"},
    {PRO_INTF_STEP, (char *)"PRO_INTF_STEP"},
    {PRO_INTF_VDA, (char *)"PRO_INTF_VDA"},
    {PRO_INTF_NONE, (char *)"UNKNOWN"}
  };
  
  for (i=0; i<sizeof(tab)/sizeof(tab[0])-1; i++)
  {
    if (tab[i].type == type)
      break;
  }
  return (tab[i].str);
}

/*====================================================================*\
    FUNCTION :  ProUtilImportfeatInfoPrint()
    PURPOSE  :  write import feat info to file 
\*====================================================================*/
ProError ProUtilImportfeatInfoPrint(
  ProFeature *import_feat)  /* In: import feat */
{
  ProError err;
  FILE *fp;
  int cont=1, i, j, *p_item_id, n_map, n_uid=0, n_iid=0;
  int *p_user_id;
  ProImportfeatData if_data;
  char fname[PRO_PATH_SIZE];
  ProImportfeatIdMap *p_id_map, id_map;
  
  fp = (FILE *)PTApplsUnicodeFopen("impfeat_part.txt", "w");
  
  do 
  {
    ProTKFprintf(fp, "Import feature info:\n");
    
    err = ProImportfeatDataGet(import_feat, &if_data);
    TEST_CALL_REPORT("ProImportfeatDataGet()",
      "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
    
    if (err != PRO_TK_NO_ERROR)
      break;
    
    ProTKFprintf(fp,"Interface type: %s\n",ProUtilIntfTypeToStr(if_data.intf_type)); 
    ProWstringToString(fname, if_data.filename);
    ProTKFprintf(fp, "Filename: %s\n", fname);
    ProTKFprintf(fp, "Attributes: %x\n\n", if_data.attr);
    
    
    err = ProImportfeatIdArrayCreate(import_feat, &p_id_map);
    TEST_CALL_REPORT("ProImportfeatIdArrayCreate()",
      "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
    
    if (err != PRO_TK_NO_ERROR)
      break;
    
    err = ProImportfeatIdArrayMapCount(p_id_map, &n_map);
    TEST_CALL_REPORT("ProImportfeatIdArrayMapCount()",
      "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
    
    if (n_map == 0)
      p_id_map = NULL;
    else
    ProTKFprintf(fp, "Map N   Type   UserId ItemId UId->IId                      "
      "IId->UId\n");
    for (i=0; i<n_map; i++)
    {
      err = ProImportfeatIdArrayMapGet(p_id_map, i, &id_map);
      TEST_CALL_REPORT("ProImportfeatIdArrayMapGet()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
      err = ProArrayAlloc(0, sizeof(p_item_id[0]), 1, (ProArray*)&p_item_id);
      TEST_CALL_REPORT("ProArrayAlloc()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
      err = ProImportfeatUserIdToItemId(import_feat, id_map.user_id,
        id_map.item_type, &p_item_id);
      TEST_CALL_REPORT("ProImportfeatUserIdToItemId()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
      err = ProArraySizeGet((ProArray*)p_item_id, &n_iid);
      TEST_CALL_REPORT("ProArraySizeGet()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
      err = ProArrayAlloc( 0, sizeof(int), 1, (ProArray*)&p_user_id );
      TEST_CALL_REPORT("ProArrayAlloc()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      if (err != PRO_TK_NO_ERROR)
        break;
      
      err = ProImportfeatItemIdToUserId(import_feat, id_map.item_id,
        id_map.item_type, &p_user_id);
      TEST_CALL_REPORT("ProImportfeatItemIdToUserId()",
        "ProUtilImportfeatInfoPrint()", 
        err, err != PRO_TK_NO_ERROR && err != PRO_TK_NOT_IMPLEMENTED );
      
      err = ProArraySizeGet((ProArray*)p_user_id, &n_uid);
      TEST_CALL_REPORT("ProArraySizeGet()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
      ProTKFprintf(fp, "%5d  %5d  %5d  %5d", i, id_map.item_type, id_map.item_id,
        id_map.user_id);
      
      for (j=0; j<n_iid || j<5; j++)
      {
        if (j<n_iid)
          ProTKFprintf(fp, " %5d", p_item_id[j]);
        else
          ProTKFprintf(fp, "      ");
      }
      for (j=0; j<n_uid; j++)
        ProTKFprintf(fp, "%5d", p_user_id[j]);
      
      ProTKFprintf(fp, "\n");
      
      err = ProArrayFree( (ProArray*)&p_item_id );
      TEST_CALL_REPORT("ProArrayFree()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
      err = ProArrayFree( (ProArray*)&p_user_id );
      TEST_CALL_REPORT("ProArrayFree()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
      
    }
    
    if (p_id_map != NULL)
    {
      err = ProImportfeatIdArrayFree(p_id_map);
      TEST_CALL_REPORT("ProImportfeatIdArrayFree()",
        "ProUtilImportfeatInfoPrint()", err, err != PRO_TK_NO_ERROR);
    }
    
  } while (!cont);
  
  fclose(fp);
  return (err);   
}

/*====================================================================*\
    FUNCTION :  ProUtilIntfDataCopy()
    PURPOSE  :  copy all data using different functions
\*====================================================================*/
ProError ProUtilIntfDataCopy(
  ProIntfData **p_i_data)   /* In, Out: intf data */
{
  ProIntfData *out_data = NULL;
  ProError err;
  int stop=0, num_surf, s, num_quilt, q, num_edge, e, d, num_datum;
  ProSurfacedata *p_surf_data;
  ProQuiltdata *p_quilt_data;
  ProEdgedata *p_edge_data;
  ProDatumdata *p_datum_data=NULL;
  double acc;
  ProAccuracytype acc_type;
  ProOutline xyz_outline;
  
  err = ProIntfDataAlloc(&out_data);
  TEST_CALL_REPORT("ProIntfDataAlloc()",
    "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
  
  do
  {
    err = ProIntfDataSurfaceCount(*p_i_data, &num_surf);
    TEST_CALL_REPORT("ProIntfDataSurfaceCount()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
      break;
    
    for (s=0; s<num_surf; s++)
    {
      err = ProIntfDataSurfaceGet(*p_i_data, s, &p_surf_data);
      TEST_CALL_REPORT("ProIntfDataSurfaceGet()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProUtilSurfacedataCopy(&p_surf_data);
      
      err = ProIntfDataSurfaceAppend(out_data, p_surf_data);
      TEST_CALL_REPORT("ProIntfDataSurfaceAppend()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProSurfacedataMemoryFree(p_surf_data);
      TEST_CALL_REPORT("ProSurfacedataMemoryFree()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    }
    
    err = ProIntfDataQuiltCount(*p_i_data, &num_quilt);
    TEST_CALL_REPORT("ProIntfDataQuiltCount()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
      break;
    
    for (q=0; q<num_quilt; q++)
    {
      err = ProIntfDataQuiltGet(*p_i_data, q, &p_quilt_data);
      TEST_CALL_REPORT("ProIntfDataQuiltGet()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProUtilQuiltdataCopy(&p_quilt_data);
      
      err = ProIntfDataQuiltAppend(out_data, p_quilt_data);
      TEST_CALL_REPORT("ProIntfDataQuiltAppend()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProQuiltdataMemoryFree(p_quilt_data);
      TEST_CALL_REPORT("ProQuiltdataMemoryFree()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    }
    
    err = ProIntfDataEdgeCount(*p_i_data, &num_edge);
    TEST_CALL_REPORT("ProIntfDataEdgeCount()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
      break;
    
    for (e=0; e<num_edge; e++)
    {
      err = ProIntfDataEdgeGet(*p_i_data, e, &p_edge_data);
      TEST_CALL_REPORT("ProIntfDataEdgeGet()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProUtilEdgedataCopy(&p_edge_data);
      
      err = ProIntfDataEdgeAppend(out_data, p_edge_data);
      TEST_CALL_REPORT("ProIntfDataEdgeAppend()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProEdgedataMemoryFree(p_edge_data);
      TEST_CALL_REPORT("ProEdgedataMemoryFree()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    }
    err = ProIntfDataDatumCount(*p_i_data, &num_datum);
    TEST_CALL_REPORT("ProIntfDataDatumCount()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
      break;
    
    err = ProDatumdataAlloc( &p_datum_data );
    TEST_CALL_REPORT("ProDatumdataAlloc()", "ProUtilIntfDataCopy()", 
      err, err != PRO_TK_NO_ERROR);
    
    for (d=0; d<num_datum; d++)
    {
      err = ProIntfDataDatumGet(*p_i_data, d, &p_datum_data);
      TEST_CALL_REPORT("ProIntfDataDatumGet()",
        "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
      
      err = ProUtilDatumdataCopy(&p_datum_data);
      
      if (err == PRO_TK_NO_ERROR)
      {
        
        err = ProIntfDataDatumAppend(out_data, p_datum_data);
        TEST_CALL_REPORT("ProIntfDataDatumAppend()",
          "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
        
        err = ProDatumdataMemoryFree(p_datum_data);
        TEST_CALL_REPORT("ProDatumdataMemoryFree()",
          "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);              
        
      }
    }
    
    err = ProIntfDataAccuracytypeGet(*p_i_data, &acc_type);
    TEST_CALL_REPORT("ProIntfDataAccuracytypeGet()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    
    err = ProIntfDataAccuracytypeSet(out_data, acc_type);
    TEST_CALL_REPORT("ProIntfDataAccuracytypeSet()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    
    err = ProIntfDataAccuracyGet(*p_i_data, &acc);
    TEST_CALL_REPORT("ProIntfDataAccuracyGet()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    
    err = ProIntfDataAccuracySet(out_data, acc);
    TEST_CALL_REPORT("ProIntfDataAccuracySet()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    
    err = ProIntfDataOutlineGet(*p_i_data, xyz_outline);
    TEST_CALL_REPORT("ProIntfDataOutlineGet()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    
    err = ProIntfDataOutlineSet(out_data, xyz_outline);
    TEST_CALL_REPORT("ProIntfDataOutlineSet()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
  } while (stop);
  
  if (err == PRO_TK_NO_ERROR)
  {
    
    memset(*p_i_data, '\0', sizeof(ProIntfData));
    
    err = ProIntfDataFree(*p_i_data);
    TEST_CALL_REPORT("ProIntfDataFree()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    
    p_i_data[0] = out_data;
    return (PRO_TK_NO_ERROR);
  }
  else
  {
    err = ProIntfDataFree(out_data);
    TEST_CALL_REPORT("ProIntfDataFree()",
      "ProUtilIntfDataCopy()", err, err != PRO_TK_NO_ERROR);
    return (PRO_TK_GENERAL_ERROR);
  }
}

/*====================================================================*\
    FUNCTION :  ProTestEdgeCreationTypeGet()
    PURPOSE  :  returns creation type
\*====================================================================*/
void ProTestEdgeCreationTypeGet (int *creation_type)
{
  *creation_type = cr_type;
}

/*====================================================================*\
    FUNCTION :  ProTestEdgeMenuAction()
    PURPOSE  :  action function for edge creation type menu
\*====================================================================*/
int ProTestEdgeMenuAction (ProAppData data, int action)
{
  int *cr_type = (int *)data;
  *cr_type ^= action;
  return (0);
}

/*====================================================================*\
    FUNCTION :  ProUtilSurfaceMenuAction()
    PURPOSE  :  action function for edge creation type menu
\*====================================================================*/
int ProUtilSurfaceMenuAction(
  ProAppData data, int action)
{
  *(int*)data = action;
  return (0);
}

/*====================================================================*\
    FUNCTION :  ProTestSelectEdgeCreationType()
    PURPOSE  :  Selects edge creation type
\*====================================================================*/
void ProTestSelectEdgeCreationType (
  ProPartConversionOptions *p_opts)
{
  ProError status;
  int menu_id, action, cr_type;
  static char *cmpnd_menu[] = 
  {"TkEdgeCreat", "TkSurfCreat", "TkCurvCreat", "DONE",""};
  
  status = ProMenuFileRegister( (char*)"TkEdgeCreat", (char*)"tkedgecreat.mnu", 
    &menu_id );
  TEST_CALL_REPORT( "ProMenuFileRegister()", 
    "ProTestSelectEdgeCreationType()",
    status,  status != PRO_TK_NO_ERROR );
  
  ProMenubuttonActionSet( (char*)"TkEdgeCreat", (char*)"UV points",
    (ProMenubuttonAction)ProTestEdgeMenuAction, 
    (ProAppData)&cr_type, UV_POINTS );
  ProMenubuttonActionSet( (char*)"TkEdgeCreat", (char*)"UV curves",
    (ProMenubuttonAction)ProTestEdgeMenuAction, 
    (ProAppData)&cr_type, UV_CURVES );
  ProMenubuttonActionSet( (char*)"TkEdgeCreat", (char*)"XYZ curve",
    (ProMenubuttonAction)ProTestEdgeMenuAction, 
    (ProAppData)&cr_type, XYZ_CURVE);
  ProMenubuttonActionSet( (char*)"TkEdgeCreat", (char*)"TkEdgeCreat",
    (ProMenubuttonAction)ProMenuHold, NULL,  0 );
  
  status = ProMenuFileRegister( (char*)"TkSurfCreat", (char*)"tksurfcreat.mnu", 
    &menu_id );
  ProMenubuttonActionSet( (char*)"TkSurfCreat", (char*)"Default Surf",
    (ProMenubuttonAction)ProUtilSurfaceMenuAction, 
    (ProAppData)&p_opts->surface_representation, 
    PRO_PART_SURFACES_AS_DEFAULT );
  ProMenubuttonActionSet( (char*)"TkSurfCreat", (char*)"Spl as BSpl",
    (ProMenubuttonAction)ProUtilSurfaceMenuAction, 
    (ProAppData)&p_opts->surface_representation, 
    PRO_PART_SPL_SURFACES_AS_BSPL_SURFACES );
  ProMenubuttonActionSet( (char*)"TkSurfCreat", (char*)"Srf as BSpl",
    (ProMenubuttonAction)ProUtilSurfaceMenuAction, 
    (ProAppData)&p_opts->surface_representation, 
    PRO_PART_SURFACES_AS_BSPL_SURFACES );
  ProMenubuttonActionSet( (char*)"TkSurfCreat", (char*)"TkSurfCreat",
    (ProMenubuttonAction)ProMenuHold, NULL,  0 );
  
  status = ProMenuFileRegister( (char*)"TkCurvCreat", (char*)"tkcurvcreat.mnu", 
    &menu_id );
  ProMenubuttonActionSet( (char*)"TkCurvCreat", (char*)"Default Curve",
    (ProMenubuttonAction)ProUtilSurfaceMenuAction, 
    (ProAppData)&p_opts->curve_representation, 
    PRO_PART_CURVES_AS_DEFAULT );
  ProMenubuttonActionSet( (char*)"TkCurvCreat", (char*)"Spl as BSpl",
    (ProMenubuttonAction)ProUtilSurfaceMenuAction, 
    (ProAppData)&p_opts->curve_representation, 
    PRO_PART_SPLINES_AS_BSPLINES );
  ProMenubuttonActionSet( (char*)"TkCurvCreat", (char*)"Curve as BSpl",
    (ProMenubuttonAction)ProUtilSurfaceMenuAction, 
    (ProAppData)&p_opts->curve_representation, 
    PRO_PART_CURVES_AS_BSPLINES );
  ProMenubuttonActionSet( (char*)"TkCurvCreat", (char*)"TkCurvCreat",
    (ProMenubuttonAction)ProMenuHold, NULL,  0 );
  
  
  status = ProMenuModeSet ((char*)"TkEdgeCreat", PROMENUMODE_DATA);
  TEST_CALL_REPORT( "ProMenuModeSet()", "ProTestSelectEdgeCreationType()",
    status,  status != PRO_TK_NO_ERROR );
  status = ProMenuDatamodeSet ((char*)"TkEdgeCreat", PRO_B_TRUE);
  TEST_CALL_REPORT( "ProMenuDatamodeSet()", "ProTestSelectEdgeCreationType()",
    status,  status != PRO_TK_NO_ERROR );
  
  status = ProMenuFileRegister((char*)"DONE",(char*)"tketdone.mnu", &menu_id);
  TEST_CALL_REPORT("ProMenuFileRegister()", "ProTestSelectEdgeCreationType()",
    status , status != PRO_TK_NO_ERROR);
  status = ProMenubuttonActionSet((char*)"DONE",(char*)"-Done",
    (ProMenubuttonAction)ProUtilMenuKill, NULL, 4);
  
  status = ProMenubuttonActionSet((char*)"DONE",(char*)"DONE",
    (ProMenubuttonAction)ProMenuHold,NULL,0);
  
  status = ProCompoundmenuCreate(cmpnd_menu, &menu_id);
  TEST_CALL_REPORT("ProCompoundmenuCreate()", 
    "ProTestSelectEdgeCreationType()",
    status , status != PRO_TK_NO_ERROR);
  
  cr_type = 0;
  if (opt.edge_representation.uv_points) 
    cr_type |= UV_POINTS;
  if (opt.edge_representation.uv_curves)
    cr_type |= UV_CURVES;
  if (opt.edge_representation.xyz_curve)
    cr_type |= XYZ_CURVE;
  
  ProUtilMenubuttonHighlight ((char*)"TkEdgeCreat", (char*)"UV points", cr_type& UV_POINTS);
  ProUtilMenubuttonHighlight ((char*)"TkEdgeCreat", (char*)"UV curves", cr_type& UV_CURVES);
  ProUtilMenubuttonHighlight ((char*)"TkEdgeCreat", (char*)"XYZ curve", cr_type& XYZ_CURVE);
  ProUtilMenubuttonHighlight ((char*)"TkSurfCreat", (char*)"Default Surf", 1);
  ProUtilMenubuttonHighlight ((char*)"TkCurvCreat", (char*)"Default Curve", 1);
  
  if( status == PRO_TK_NO_ERROR )
  {
    status = ProMenuProcess( (char*)"TkEdgeCreat", &action );
    TEST_CALL_REPORT( "ProMenuProcess()", "ProTestSelectEdgeCreationType()",
      status,  status != PRO_TK_NO_ERROR );
  }
  
  opt.edge_representation.uv_points = (cr_type & UV_POINTS) && 1;
  opt.edge_representation.uv_curves = (cr_type & UV_CURVES) && 1;
  opt.edge_representation.xyz_curve = (cr_type & XYZ_CURVE) && 1;
}

/*====================================================================*\
    FUNCTION :  ProTestSelectIntfType()
    PURPOSE  :  Commands for testing import feature in Pro/TOOLKIT
                Must contain same intf types as in ProUtilIntfTypeToStr()
\*====================================================================*/
void ProTestSelectIntfType(
  ProIntfType *type)
{
  ProError err;
  int action;    
  static ProUtilMenuButtons intf_type[] = { 
    {"TkIntfType", 0, TEST_CALL_PRO_MENU_DELETE},
    {"Neutral", PRO_INTF_NEUTRAL, 0},
    {"Neutral File", PRO_INTF_NEUTRAL_FILE, 0},
    {"Iges File", PRO_INTF_IGES, 0},
    {"Step File", PRO_INTF_STEP, 0},
    {"Vda File", PRO_INTF_VDA, 0},
    {"",0,0}
  };
  err = ProUtilMenuIntValueSelect(intf_type, &action);
  if (err != PRO_TK_NO_ERROR)
    *type = PRO_INTF_NONE;
  else
    *type = (ProIntfType)action;
}

/*====================================================================*\
    FUNCTION :  ProTestImportfeat()
    PURPOSE  :  Commands for testing import feature in Pro/TOOLKIT
\*====================================================================*/
int ProTestImportfeat(ProMdl *mdl)
{
  ProError err;
  ProIntfType intf_type;
  ProIntfDataSourceType intfdatasrc_type;    
  ProPart part = (ProPart)*mdl, new_part;
  ProIntfDataSource id_source;
  ProIntfData *id_data = NULL;
  int cont = 1, w_id;
  ProName w_file_name;
  ProMdlName w_name;
  ProFeature feat;
  ProImportfeatRedefSource redef_source;
  ProImportfeatRedefSourceType redefsourcetype;    
  void *vp;
  
  ProTestSelectIntfType(&intf_type);
  if (intf_type == PRO_INTF_NONE)
    return (0);
  
  if (intf_type == PRO_INTF_NEUTRAL)
  {    
    ProTestSelectEdgeCreationType (&opt);
  }
    
  ProUtilMsgPrint("gen", "TEST %0s", "Enter new part name.");
  ProStringToWstring(w_name, (char *)NEW_PART_NAME);
    
  ProUtilStringGet(w_name, w_name, PRO_MDLNAME_SIZE);
  err = ProSolidMdlnameCreate(w_name, PRO_MDLFILE_PART, &new_part);
  TEST_CALL_REPORT("ProSolidMdlnameCreate()",
    "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
    
  do
  {
    intfdatasrc_type = ProIntfTypeToIntfDataSourceType(intf_type);
    TEST_CALL_REPORT(" ProIntfTypeToIntfDataSourceType()",
      "ProTestImportfeat()", PRO_TK_NO_ERROR, 0);
    
    if (intfdatasrc_type == PRO_INTF_DATA_SOURCE_NONE)
      break;
    
    if (intfdatasrc_type == PRO_INTF_DATA_SOURCE_FILE)
    {
      ProUtilMsgPrint("gen", "TEST %0s", "Enter the import file name.");
      if (ProUtilStringGet(w_file_name, NULL, PRO_NAME_SIZE) == 0)
        break;
      vp = (void*)w_file_name;  
    }
    else
    {    
      err = ProIntfDataAlloc(&id_data);
      TEST_CALL_REPORT("ProIntfDataAlloc()",
        "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
      
      err = ProPartToProInterfaceData(part, &opt, id_data);
      TEST_CALL_REPORT("ProPartToProInterfaceData()",
        "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
      if (err != PRO_TK_NO_ERROR)
        break;
      
      vp = (void*)id_data;  
    }
    
    err = ProIntfDataSourceInit( intf_type, vp, &id_source);
    TEST_CALL_REPORT("ProIntfDataSourceInit()",
      "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
    if (err != PRO_TK_NO_ERROR)
      break;
    
    err = ProImportfeatCreate(new_part, &id_source, NULL, NULL, &feat);
    TEST_CALL_REPORT("ProImportfeatCreate()",
      "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
    
    if (err != PRO_TK_NO_ERROR)
      break;
    
#ifndef PT_PRODUCTS_BUILD
    err = ProObjectwindowMdlnameCreate(w_name, PRO_PART, &w_id);
    TEST_CALL_REPORT("ProObjectwindowMdlnameCreate()",
      "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
    
    err = ProMdlDisplay((ProMdl)new_part);
    TEST_CALL_REPORT("ProMdlDisplay()",
      "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
    
    err = ProWindowActivate(w_id);
    TEST_CALL_REPORT("ProWindowActivate()",
      "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
    
#endif
    if (id_data != NULL)
    {      
      err = ProImportfeatRedefSourceInit(PRO_IMPORT_FEAT_REDEF_SUBSTITUTE,
        (void*)&id_source, &redef_source);
      TEST_CALL_REPORT("ProImportfeatRedefSourceInit()",
        "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
      
      redefsourcetype = ProImportfeatRedefSourceTypeGet(
        PRO_IMPORT_FEAT_REDEF_SUBSTITUTE);
      TEST_CALL_REPORT("ProImportfeatRedefSourceTypeGet()",
        "ProTestImportfeat()", PRO_TK_NO_ERROR, 0);
            
      err = ProImportfeatRedefine(&feat, &redef_source); 
      TEST_CALL_REPORT("ProImportfeatRedefine()",
        "ProTestImportfeat()", err, 
        (err != PRO_TK_NO_ERROR)&&
        (err != PRO_TK_NOT_IMPLEMENTED));      
    }
    ProUtilImportfeatInfoPrint(&feat);
    
  } while (!cont);
  
  if (id_data != NULL)
  {
    err = ProIntfDataFree(id_data);
    TEST_CALL_REPORT("ProIntfDataFree()",
      "ProTestImportfeat()", err, err != PRO_TK_NO_ERROR);
  }
  
  return (0);
}


/*====================================================================*\
    FUNCTION :  ProUtilImportfeatFilter()
    PURPOSE  :  Allows to collect only import features
\*====================================================================*/
ProError ProUtilImportfeatFilter(
  ProFeature *p_feature)
{
  ProError err;
  ProFeattype feattype;
  
  err = ProFeatureTypeGet(p_feature, &feattype);
  TEST_CALL_REPORT( " ProFeatureTypeGet()", 
    " ProUtilImportfeatFilter()", err,  err != PRO_TK_NO_ERROR );
  return (err == PRO_TK_NO_ERROR && feattype == PRO_FEAT_IMPORT ?
  PRO_TK_NO_ERROR : PRO_TK_CONTINUE);
}


int ProTestImpfeatAttrMenuAction( ProAppData data, int action )
{
  ProImportfeatAttr *p_attrs = (ProImportfeatAttr*)data;
  
  switch( action )
  {
  case JOIN_SURFACES:
    p_attrs->join_surfaces = p_attrs->join_surfaces ? 0 : 1;
    break;
    
  case MAKE_SOLID:
    p_attrs->attempt_make_solid = p_attrs->attempt_make_solid ? 0 : 1;
    break;
    
  case ADD_SOLID:
    p_attrs->cut_or_add = p_attrs->cut_or_add ? 0 : 1;
    break;
  }
  
  return 0;
}