/*-----------------------------------------------------------------------------------

Hit ctrl-enter to execute.

Description:

	This example demonstrates how to annotate images using image document components
	The script annotates the front-most image, illustrating how to format, position,
	search for text annotations and how to extract information from them.
	Copyright © 2001 Gatan Inc.

-----------------------------------------------------------------------------------*/


// Define the font size and style to be used  

string fontName = "Arial"
number fontSize = 10
number true =1, false = 0


/*	This method adds text annotation to an existing image document component.
	It is called with an existing image document component, column and row co-ordinates, 
	the annotation text and a name for the annotation.
	The annotation name is added to the components tag group for reference.
	The method returns the new annotation image document component.						*/
 
component AddTextAnnotation( Component comp, Number col, Number row, String text, string name )
{
		
	// Initialise annotation co-ordinate variables			 
	number top, left, bottom, right, maxBottom = 0				 
	
	// Find how many annotations are present in component 'comp', and loop over each
	number i, count = comp.ComponentCountChildren() 
	for (i=0; i < count; i++)                                    
	{
		// Find last annotation in this group (last in y position, that is)
		Component compChild = comp.ComponentGetChild( i )
		
		// Finding the bottom most co-ordinate of the i'th annotations restangular bounds...  
		ComponentGetRect( compChild, top, left, bottom, right )  

		//  ... and set as 'maxbottom' if bottom-most
		if (bottom > maxBottom)									 
			maxBottom = bottom
	}

	// Declare a new component called 'annot'
	component annot 
	
	// Create new text annotation component.  Note this fontSize doesn't work											 
	annot = NewTextAnnotation( 0, maxBottom, text, fontSize ) 
	
	// Add the child component 'annot' to the end of the parent 'comp's list of sub-annotations. 	 
	comp.ComponentAddChildAtEnd( annot ) 
	
	// Set the font size and style. Must be called AFTER adding component to the image display.						
	annot.componentSetFontSize( fontSize ) 						
	annot.ComponentSetFontFaceName( fontName )	

	// Open an OK dialog containing the current font style				 
	okdialog( annot.ComponentGetFontFaceName( ) )				 
	
	// Get the component tag group into a tag group 'tgs', and place 
	// the annotation name string into the tag group, under the entry 'name'
	TagGroup tgs = annot.ComponentGetTagGroup()					
	tgs.TagGroupSetTagAsString( "name", name )					 

	// Return the new annotation component
	return annot												
}	


/*	This method adds a new group annotation component to an image at specified co-ordinates
	It is called with the image to be annotated, and the annotaion box co-ordinates. 
	The method returns the new image document component								*/

component AddGroupAnnotation(Image img, Number top, number left, number bottom, number right )
{
	// Get the height (y-dimension) size of the input image in pixels
	number height = img.ImageGetDimensionsize( 1 )				 
 
	// Create a new group annotation component, andet the rectangular bounds of the annotation
	component annot = NewGroupAnnotation( )						 
	annot.ComponentSetRect( top, left, bottom, right ) 
	
	// Add the child component 'annot' to the end of the image display document of 'img'  
	// and return the image document component 'annot'       
	img.ImageGetImageDisplay(0).ComponentAddChildAtEnd(annot)    
	return annot												
}	


/*	This method searches through an input image document component for annotaion
	of the specified name, as written to the tag group in the AddTextAnnotation method
	The method is called with the parent image document component and a name string of the annoation
	It returns the annotaion child component.											*/
 
Component FindAnnotationWithName( Component comp, string compname )
{
	// Create the output component, and initialise the flag 'found' to zero	 
	Component desiredComp 										 
	number found = false
											 
	// Count the number of child components (annotations) associated with the parent component comp
	// and loop through all the child components while the desired component isn't found
	number i, count = comp.ComponentCountChildren() 		     
	for (i=0; i<count && !found; i++)							 
	{
		// Get the i'th child component from the parent
		Component compChild = comp.ComponentGetChild( i )
		
		// and get the corresponding tag group for the ith child component		 
		TagGroup tgs = compChild.ComponentGetTagGroup()	
		
		// Get any tag entry under "name" and put into string 'name'		 
		string name
		tgs.TagGroupGetTagAsString( "name", name )				 

		// Does the tag string correspond to the desired component name??
		if (name == compName) 									 
		{
			// If so, the return component is set to the i'th child component
			// and set the found flag is set to true
			desiredComp = compChild								 
			found = true										 
		}
		
		// If the string does not match, does this child component have any children?
		else if ( compChild.ComponentCountChildren() != 0 )		 
		{
			// If so, search for annotation with the corresponding name, and place in the component 'temp'
			Component temp = FindAnnotationWithName(compChild, compName )
			
			// If component 'temp' is valid, then this child component does contain the annotation	
			if ( temp.ComponentIsValid() )						 
			{
				// Set the return component to the child component 
				// and set the 'found' flag to true to end the search
				desiredComp = temp								 
				found = true									 
			}
		}	
	}	// end of the i loop

	// Return the desired component 
	// Note this has no component associated with it if the search was unsuccessftl
	return desiredComp											 
}



/*	This method provides an output of the component information to the results window, 
	illustrating how to extract annotaion information from an image document component
	It is called with the image document component of interest, and a level number
	specifying the child component level from which information is being read. 
	The method returns nothing.													*/
	
void PrintComponentInfoToResults( Component comp, number level )
{	
	// Count the number of child components associated with 'comp'
	number i, count
	count = comp.ComponentCountChildren()	
	
	// Loop 'level' times, creating a string 'indent' whith an indent size corresponding to the level number			  
	number l 
	string indent
	for ( l=0; l < level; l++)								 	    
		indent += "   "											  

	// Output the number of child components to the results window, indented by string 'indent'
	result( indent + "Component has " + count + " children.\n")  
	
	// Get the rectangular bounds of component 'comp'
	number top, left, bottom, right
	ComponentGetRect( comp, top, left, bottom, right )	
	
	// Get the component name from the tag group		  	
	TagGroup tgs = comp.ComponentGetTagGroup()					  
	string name
	tgs.TagGroupGetTagAsString( "name", name )

	// Output the component id, the bounding co-ords and the component name to the results window. 
	result( indent+"ID = " + comp.ComponentGetID() + ", rect = [" + \
						top+", "+left +", "+bottom+", "+right+"], name =" +name+"\n")

	// Loop through the number of child components															  
	for (i=0; i < count; i++)									  
	{
		// Get the i'th child component
		Component compChild = comp.ComponentGetChild( i )		  

		// Check to see if the i'th child component also has child components
		// If so, perform this whole method on the child component, with the level index raised by one
		if ( compChild.ComponentCountChildren() != 0 )			  
			PrintComponentInfoToResults( compChild, level + 1 )	  
	}
}


/* This method performs the Component example, calling the other methods when required. */

void PerformExample()
{
	// Get the front image.  Note the use of ':=', any function performed on 'img' affects the front image by implication.
	// Then get the image display component of img (and hence the front image)
	image img :=GetFrontImage()									   
	Component comp = img.ImageGetImageDisplay(0)				   

	{
		// Create a group annotation with pixel co-ordinates top (0), left (0), bottom (100) and right (100)
		// Then call the AddTextAnnotation method to add the image name of img at coulmn 0 and row 1, 
		// giving the annotation the reference name "ImageName". Likewise, also add the date on the next line 
		// (note the AddTextAnnotaion method searches for the bottom of the current annotation bounds)
		Component grp = AddGroupAnnotation( img, 0, 0, 100, 100 )  
		AddTextAnnotation( grp, 0, 1, img.GetName(), "ImageName")  
		AddTextAnnotation( grp, 0, 1, GetDate(0), "Date")		   
	}
	{
		// Create a group annotation, this time at (100, 0, 200, 100), that is, bounding (top, left, bottom, right) 
		// Add another annotation reference string "ann1", and repeat with no reference name
		Component grp = AddGroupAnnotation( img, 100, 0, 200, 100 ) 
		AddTextAnnotation( grp, 0, 1, "Next annotation", "ann1")	
		AddTextAnnotation( grp, 0, 1, "Another Line", "")			
	}
	{
		// Add a single annotaion (i.e. not a group annotation), at the bottom of the current annotations.
		AddTextAnnotation( comp, 0, 1, "Just a plain old annotation", "") 
	}

	// Now call method PrintComponentInfoToResults to output the annotation information in component 'comp', level 0
	result("-----\n")
	PrintComponentInfoToResults( comp, 0 )                          
 
	// Finally, demonstrate searching for a component using the method FindAnnotationWithName
	// Note that we're using an annotation tag explicitly created by this script to find the annotation.  We could also use the annotation ID,
	Component foundComp = FindAnnotationWithName( comp, "ImageName") 
	result("-----Found this component:\n")	 
	
	// Now, output the information relating to the found component						 
	PrintComponentInfoToResults( foundComp, 0 )	                    
}

// Call the PerformExample method to execute the example
PerformExample()													
