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

#include <ProToolkit.h>
#include <ProMenuBar.h>
#include <ProMdl.h>
#include <ProFeature.h>
#include <ProLayer.h>
#include <ProAnnotationFeat.h>
#include <ProAnnotationElem.h>


#include <PTAFExamples.h>
#include <ProTKRunTime.h>

/*====================================================================*\
  FUNCTION :	 TestPTAFExUpdatePatternNotes()
  PURPOSE  :   Enable access to the Update Pattern Notes	
\*====================================================================*/
uiCmdAccessState TestPTAFExUpdatePatternNotes(uiCmdAccessMode access_mode)
{
  ProMdl mdl;
  ProMdlType mdltype;
  ProModelitem selected_item;
  ProSelection *sel=NULL;
  ProFeattype feat_type;
  ProPattern annot_pattern;

/*---------------------------------------------------------------------*\
Test to See if the current model is a Part / Assembly where annotation 
features exist
\*---------------------------------------------------------------------*/
  status = ProMdlCurrentGet(&mdl);
  if (status != PRO_TK_NO_ERROR) return (ACCESS_UNAVAILABLE);

  ProMdlTypeGet(mdl, &mdltype); 
  if ((mdltype != PRO_MDL_PART) && (mdltype != PRO_MDL_ASSEMBLY))
    return (ACCESS_UNAVAILABLE);

/*---------------------------------------------------------------------*\
Test to see if the Selection buffer if empty
Get the Annotation Element from the Selection buffer
\*---------------------------------------------------------------------*/
  status = PTAFExTestforSelectionsInBuffer();

  PT_TEST_LOG_SUCC("PTAFExTestforSelectionsInBuffer ");

  if (status != PRO_TK_NO_ERROR) return (ACCESS_UNAVAILABLE);
  
/*---------------------------------------------------------------------*\
User gets the ProSelection from the selection buffer
\*---------------------------------------------------------------------*/
  status = ProSelbufferSelectionsGet(&sel);

/*---------------------------------------------------------------------*\
Get ModelItem from the ProSelection
\*---------------------------------------------------------------------*/
  status = ProSelectionModelitemGet(sel[0], &selected_item);
  PT_TEST_LOG_SUCC("PTAFExCreateRoundfromAE::ProSelectionModelitemGet ");
  
  ProSelectionarrayFree (sel);

  if (selected_item.type == PRO_FEATURE) {
/*---------------------------------------------------------------------*\
Make sure that the feature type is Annotation
\*---------------------------------------------------------------------*/
    status = ProFeatureTypeGet((ProFeature *)&selected_item, &feat_type);

    if (feat_type == PRO_FEAT_ANNOTATION) {
/*---------------------------------------------------------------------*\
Get the Pattern for this feature, if available
\*---------------------------------------------------------------------*/
      status = ProFeaturePatternGet((ProFeature *)&selected_item, PRO_FEAT_PATTERN, &annot_pattern);

      if (status == PRO_TK_NO_ERROR) 	return (ACCESS_AVAILABLE);
      else return (ACCESS_UNAVAILABLE);
    }
  }
  return (ACCESS_UNAVAILABLE);
}

/*====================================================================*\
  FUNCTION :   PTAFExFeatureAnnotElemUpdateVisitAction()
  PURPOSE  :   Enable access to the Update Pattern Notes	
\*====================================================================*/
ProError PTAFExFeatureAnnotElemUpdateVisitAction (ProAnnotationElem *annot_elem, 
						  ProError status, 
						  ProAppData p_new_string)
{
  ProError err;
  ProAnnotation note;
  wchar_t** existing_note;
  wchar_t** new_note;
  int i;
  int p_size, new_size;

/*---------------------------------------------------------------------*\
Get the Annotation from the Annotation element
\*---------------------------------------------------------------------*/
  err = ProAnnotationelemAnnotationGet(annot_elem, &note);

  ProAnnotationUndisplay (&note, NULL, NULL);

/*---------------------------------------------------------------------*\
Make sure that the annotation is a 3D note
\*---------------------------------------------------------------------*/
  if (note.type != PRO_NOTE) return PRO_TK_NO_ERROR;

  else {
/*---------------------------------------------------------------------*\
Get the existing Note from the ProNote
\*---------------------------------------------------------------------*/
    err = ProNoteTextGet((ProNote *)&note, PRODISPMODE_SYMBOLIC, 
			 &existing_note);

/*---------------------------------------------------------------------*\
Get the size (array) of the existing note
\*---------------------------------------------------------------------*/
    err = ProArraySizeGet((ProArray)existing_note, &p_size);

/*---------------------------------------------------------------------*\
Allocate the new note text as a new array. This allows us to use
ProWstringproarrayFree on the existing note text array, later.
\*---------------------------------------------------------------------*/
    err = ProArrayAlloc (p_size+1, sizeof (wchar_t*), 1, 
			 (ProArray*)&new_note);
    for (i = 0; i < p_size; i ++)
      {
	new_note [i] = existing_note [i];
      }

    new_note [p_size] = (wchar_t*)calloc (strlen (p_new_string) + 1, 
					  sizeof (wchar_t));
    
/*---------------------------------------------------------------------*\
Add the new string value to the array
\*---------------------------------------------------------------------*/
    
    ProStringToWstring(new_note[p_size], (char *)p_new_string);

/*---------------------------------------------------------------------*\
Add the new line to the 3D note
\*---------------------------------------------------------------------*/
    err = ProNoteTextSet((ProNote *)&note, new_note);

    ProAnnotationDisplay (&note, NULL, NULL, NULL);

/*---------------------------------------------------------------------*\
Free allocated memory
\*---------------------------------------------------------------------*/
    free (new_note [p_size]);
    ProArrayFree ((ProArray*)&new_note);

    ProWstringproarrayFree (existing_note);
  }

  return PRO_TK_GENERAL_ERROR;
}

/*====================================================================*\
    FUNCTION :	 PTAFExFeatureAnnotElemVisitAction()
    PURPOSE  :   Visit function for Annotation Elements in a Feature	
\*====================================================================*/
ProError PTAFExFeatureAnnotElemVisitAction (ProAnnotationElem *annot_elem, 
					    ProError status, 
					    ProAppData dummy)
{
  ProError err;
  ProLayer layer;
  ProLayerItem layer_item;
  ProMdl current_model;
  ProName layer_name;
  ProFeature feature;
  ProNote note;

  err = ProMdlCurrentGet(&current_model);
  if (status != PRO_TK_NO_ERROR) return (ACCESS_UNAVAILABLE);
  
  ProStringToWstring(layer_name, "PTAFEX_TK");

/*---------------------------------------------------------------------*\
Get the Feature from the Annotation element
\*---------------------------------------------------------------------*/
  err = ProAnnotationelemFeatureGet(annot_elem, &feature);
  err = ProAnnotationelemAnnotationGet (annot_elem, &note);
 
/*---------------------------------------------------------------------*\
Since the Annotation Erase does not work consistently, 
We will use the blanked layer approach
\*---------------------------------------------------------------------*/
  err = ProLayerCreate(current_model, layer_name, &layer);
  
  if ((err == PRO_TK_NO_ERROR) || (err == PRO_TK_E_FOUND)) 
    {
      
/*---------------------------------------------------------------------*\
Add the annotation element to the layer
\*---------------------------------------------------------------------*/
      err = ProLayerItemInit(PRO_LAYER_FEAT, feature.id, current_model, &layer_item);
      
      err = ProLayerItemAdd(&layer, &layer_item);

/*---------------------------------------------------------------------*\
Set the layer status to BLANK and save 
\*---------------------------------------------------------------------*/
      err = ProLayerDisplaystatusSet(&layer, PRO_LAYER_TYPE_BLANK);
      err = ProLayerDisplaystatusSave(current_model);
 
    }
	
  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
  FUNCTION :	 TestPTAFExUpdatePatternNotes()
  PURPOSE  :   Enable access to the Update Pattern Notes	
\*====================================================================*/
ProError PTAFExUpdateAnnotationLeader(ProMdl model, int leader_feat_id, int num_members)
{
  ProFeature feat;
  char new_string[PRO_LINE_SIZE];

/*---------------------------------------------------------------------*\
Initialize a feature object
\*---------------------------------------------------------------------*/
  status = ProFeatureInit(model, leader_feat_id, &feat);

/*---------------------------------------------------------------------*\
Create the New string to be passed to add to the Leader Annotation Feature
\*---------------------------------------------------------------------*/
  ProTKSprintf(new_string, "%i: REF GENERAL PATTERN", num_members);

/*---------------------------------------------------------------------*\
Visit the Annotation Elements in the Annotation Feature
\*---------------------------------------------------------------------*/
  status = ProFeatureAnnotationelemsVisit(&feat, (ProAnnotationelemVisitAction)PTAFExFeatureAnnotElemUpdateVisitAction, NULL, (ProAppData)new_string);
	
  return PRO_TK_NO_ERROR;
}


/*====================================================================*\
  FUNCTION :	 TestPTAFExUpdatePatternNotes()
  PURPOSE  :   Enable access to the Update Pattern Notes	
\*====================================================================*/
ProError PTAFExHidePatternAnnotation (ProMdl model, int pattern_feat_id)
{
  ProFeature feat;
  int dummy=0;

/*---------------------------------------------------------------------*\
Initialize a feature object
\*---------------------------------------------------------------------*/
  status = ProFeatureInit(model, pattern_feat_id, &feat);

/*---------------------------------------------------------------------*\
Visit the Annotation Elements in the Annotation Feature
\*---------------------------------------------------------------------*/
  status = ProFeatureAnnotationelemsVisit(&feat, (ProAnnotationelemVisitAction)PTAFExFeatureAnnotElemVisitAction, NULL, NULL);
  
  return PRO_TK_NO_ERROR;
}

/*====================================================================*\
  FUNCTION :	 TestPTAFExUpdatePatternNotes()
  PURPOSE  :   Enable access to the Update Pattern Notes	
\*====================================================================*/
ProError PTAFExUpdateNotePattern()
{
  ProSelection *sel=NULL;
  ProModelitem feature;
  ProFeature pattern_leader;
  ProFeattype feat_type;
  ProPattern annot_pattern;
  ProMdl curr_mdl;
  ProFeature* feat_members;
  int num_members;
  int i=0, j=0;

  
  
  status = ProMdlCurrentGet(&curr_mdl);
  if (status != PRO_TK_NO_ERROR) return (ACCESS_UNAVAILABLE);
/*---------------------------------------------------------------------*\
Check to see if the pre-selected item is a Pattern of Annotation Features
User gets the ProSelection from the selection buffer
\*---------------------------------------------------------------------*/
  status = ProSelbufferSelectionsGet(&sel);

/*---------------------------------------------------------------------*\
Get ModelItem from the ProSelection
\*---------------------------------------------------------------------*/
  status = ProSelectionModelitemGet(sel[0], &feature);

  ProSelectionarrayFree (sel); 

/*---------------------------------------------------------------------*\
Make sure the item selected is a feature
\*---------------------------------------------------------------------*/
  if (feature.type != PRO_FEATURE) {
    ProMessageDisplay(message_file_init, "PTAFEX ERROR %0s", "Object selected is not a Pro/E Feature.");
    return PRO_TK_NO_ERROR;
  }

  status = ProFeatureTypeGet(&feature, &feat_type);
  
  if (feat_type == PRO_FEAT_ANNOTATION) {
/*---------------------------------------------------------------------*\
Get the Pattern for this feature
\*---------------------------------------------------------------------*/
    status = ProFeaturePatternGet(&feature, PRO_FEAT_PATTERN, &annot_pattern);

/*---------------------------------------------------------------------*\
Get the leader of the pattern
\*---------------------------------------------------------------------*/
    status = ProPatternLeaderGet(&annot_pattern, &pattern_leader);


/*---------------------------------------------------------------------*\
Get the pattern information from the Pro/DEVELOP functions
\*---------------------------------------------------------------------*/

	status = ProPatternMembersGet(&annot_pattern, &feat_members);
	status = ProArraySizeGet(feat_members, &num_members);
	status = PTAFExUpdateAnnotationLeader(curr_mdl, feat_members[0].id, num_members);

/*---------------------------------------------------------------------*\
Erase the annotation in the feature
\*---------------------------------------------------------------------*/

	for (i=1; i<num_members; i++) 
	{
		status = PTAFExHidePatternAnnotation(curr_mdl, feat_members[i].id);

	}



  }

  ProWindowRepaint (PRO_VALUE_UNUSED);

  return PRO_TK_NO_ERROR;
}