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


#include "ProToolkit.h"
#include "ProRelSet.h"
#include "ProModelitem.h"
#include "ProSelection.h"
#include "ProMessage.h"
#include "ProUtil.h"
#include "ProSolid.h"
#include "UtilString.h"
#include "TestError.h"

#define RELSFILE "rels.txt"
#define MSGFILE "msg_ugutils.txt"

/*--------------------------------------------------------------------------*\
FUNCTION : UserRelsEdit()
PURPOSE  : Top Level of this example : initializes data, gets the relsets,
                invokes the edition function.
\*--------------------------------------------------------------------------*/
ProError UserRelsEdit()
{
  int 			status, status2;
  int			n_sel;
  int 			xar_size;
  ProSelection * 	p_sel_arr;  
  ProModelitem		mdlitem;
  ProRelset		relset;
  ProWstring *		rels_xar;
  ProWstring *		rels_xar2;
  ProPath		wrels_file;
  ProFileName		wmsgfile;
  ProSolid		solid;

  ProStringToWstring(wmsgfile, MSGFILE); 

/*--------------------------------------------------------------------------*\
  Ask for selecting an item that contains relations to edit
\*--------------------------------------------------------------------------*/
  status = ProSelect("part,asm,datum,feature,edge", 
		1, NULL,NULL,NULL,NULL, &p_sel_arr, &n_sel);
  ERROR_CHECK("UserRelsEdit","ProSelect",status);
  if (status != PRO_TK_NO_ERROR) return (status);

/*--------------------------------------------------------------------------*\
  Extract the relations out of the selected modelitem
\*--------------------------------------------------------------------------*/
  status = ProSelectionModelitemGet(*p_sel_arr, &mdlitem);
  ERROR_CHECK("UserRelsEdit","ProSelectionModelitemGet",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProModelitemToRelset(&mdlitem, &relset);
  ERROR_CHECK("UserRelsEdit","ProModelitemToRelset",status);
  if (status != PRO_TK_NO_ERROR) 
  {
    /* If the selection doesn't contain relations, notify and quit */ 
    status2 = ProMessageDisplay (wmsgfile, 
	"USER Selected item does not contain any relation");
    ERROR_CHECK("UserRelsEdit","ProMessageDisplay",status2);
    if (status2 != PRO_TK_NO_ERROR) return (status2);
    
    return (status);
  }
 
  status = ProArrayAlloc (0, sizeof(ProWstring), 1, (ProArray*)&rels_xar);
  ERROR_CHECK("UserRelsEdit","ProArrayAlloc", status);
  if (status != PRO_TK_NO_ERROR) return status;

  status = ProRelsetRelationsGet(&relset, &rels_xar);
  ERROR_CHECK("UserRelsEdit","ProRelsetRelationsGet",status);
  if (status != PRO_TK_NO_ERROR) return status;

/*--------------------------------------------------------------------------*\
  Write the relations to a file, edit that file, and reload the new relations
\*--------------------------------------------------------------------------*/
  ProStringToWstring(wrels_file, RELSFILE);
  status = ProUtilWstringArrayToFile(rels_xar, wrels_file);
  ERROR_CHECK("UserRelsEdit","ProUtilWstringArrayToFile",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProFileEdit(wrels_file);
  ERROR_CHECK("UserRelsEdit","ProFileEdut",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&rels_xar2);
  ERROR_CHECK("UserRelsEdit","ProArrayAlloc",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProUtilFileToWstringArray(wrels_file, &rels_xar2);
  ERROR_CHECK("UserRelsEdit","ProUtilFileToWstringArray",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProArraySizeGet(rels_xar2, &xar_size);
  ERROR_CHECK("UserRelsEdit","ProArraySizeGet",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProRelsetRelationsSet(&relset, rels_xar2, xar_size);
  ERROR_CHECK("UserRelsEdit","ProRelsetRelationsSet",status);
  if (status != PRO_TK_NO_ERROR) return (status);

/*--------------------------------------------------------------------------*\
  Try to regenerate the relations set. If it fails, restore the 
	initial relations and regenerate again
\*--------------------------------------------------------------------------*/
  status = ProRelsetRegenerate(&relset);
  ERROR_CHECK("UserRelsEdit","ProRelsetRegenerate",status);
  if (status != PRO_TK_NO_ERROR) 
  {
      status2 = ProMessageDisplay(wmsgfile, 
	"USER New relations are not valid. Replacing with old ones.");
      ERROR_CHECK("UserRelsEdit","ProMessageDisplay",status2);
      if (status2 != PRO_TK_NO_ERROR) return (status2);

      status2 = ProRelsetRelationsSet(&relset, rels_xar, xar_size);
      ERROR_CHECK("UserRelsEdit","ProRelsetRelationsSet",status2);
      if (status2 != PRO_TK_NO_ERROR) return (status2);

      status2 = ProRelsetRegenerate(&relset);
      ERROR_CHECK("UserRelsEdit","ProRelsetRegenerate",status2);
      if (status2 != PRO_TK_NO_ERROR) return (status2); 
 
      return (status);
  }
 
/*--------------------------------------------------------------------------*\
  Regenerate and repaint the solid so we can see the changes
\*--------------------------------------------------------------------------*/
  status = ProMdlCurrentGet((ProMdl*)&solid);
  ERROR_CHECK("UserRelsEdit","ProMdlCurrentGet",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProSolidRegenerate(solid, PRO_B_TRUE);
  ERROR_CHECK("UserRelsEdit","ProSolidRegenerate",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProWindowRepaint(PRO_VALUE_UNUSED);
  ERROR_CHECK("UserRelsEdit","ProWindowRepaint",status);
  if (status != PRO_TK_NO_ERROR) return (status);

/*--------------------------------------------------------------------------*\
  Deallocate the memory used by the temporary arrays
\*--------------------------------------------------------------------------*/
  status = ProArrayFree((ProArray *)&rels_xar);
  ERROR_CHECK("UserRelsEdit","ProArrayFree",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  status = ProArrayFree((ProArray *)&rels_xar2);
  ERROR_CHECK("UserRelsEdit","ProArrayFree",status);
  if (status != PRO_TK_NO_ERROR) return (status);
  
  status = ProMessageDisplay(wmsgfile, "USER Relations replaced successfully.");
  ERROR_CHECK("UserRelsEdit","ProMessageDisplay",status);
  if (status != PRO_TK_NO_ERROR) return (status);

  return (PRO_TK_NO_ERROR);
}