/**
 * Class AElementRDF
 * This class implements some useful features to extract the metadatas
 * embeded in an SVG document (coded in RDF).
 * An instance of this class points to the RDF description of a given SVG
 * entity, identified by its 'id' attribute. ie, it points to an Element node
 * of the document's associated DOM whose name is 'rdf:Description', and whose
 * attribute 'about' equals to the 'id' attribute of the described entity.
 * Its main method is spitDesc, which prints out such a description in
 * understandable English (I said understandable, not Shakespearian), using
 * some public methods of the Class Property.
 **/

package axsvg;

import java.io.*;
import fr.dyade.koala.dom.*;
import fr.dyade.koala.dom.util.*;
import org.w3c.dom.*;
import java.util.*; 

public class AElementRDF {
    private Element generator;
    private boolean firstLoop;


    /**
     * method AElementRDF
     * @param  an Element node of the document's associated DOM whose name is
     * 'rdf:Description'.
     * The constructor of the class. Sets the attribute generator as an RDF
     * node father of the description of a SVG entity (the 'about' attribute
     * of this node identifying this last entity).
     * Also sets the firstLoop attribute to true. This private attribute will
     * be used within the method spitDesc.
     **/
    public AElementRDF(Element elt) {
	generator = elt;
	firstLoop = true;
    }


    /**
     * method getGenerator
     * @return the Element node which is the generator attribute of the
     * calling object.
     **/
     public Element getGenerator() {
	return(generator);
    }
    
		   	
    /**
     * method spitDesc
     * @param the DocumentMixte image of the SVG document's DOM.
     * This method converts in understandable English the description held
     * by the calling AElementRDF (which is basically a bunch of RDF
     * statements with the 'about' attribute of the generator node as the
     * subject of the triplet).
     * The algorithm used works as described (effects of other classes methods
     * are explained too):
     * First of all, it removes the key corresponding to $about (where $about
     * is the value of the about attribute of the generator node) in the
     * hashtable tableRDF, setting that this description has already been done
     * (actually, is being done).
     * If the generator node has no child representing an RDF property, it
     * prints nothing. Else:
     * If the entity being described has not yet been mentionned (ie if there
     * is a key equals to $about in the hashtable tableSVG, which at the
     * beginning contains all the SVG nodes which have an id), it prints "An
     * entity called $about".
     * It then prints the SVG description (ie the content of the node 'desc'
     * in the SVG code, thanx to the method AElementSVG.getDesc) preceded by
     * "which" and removes the key corresponding to $about in tableSVG (the
     * entity has then been already 'mentionned').
     * Else it only prints "The entity $about".
     * It then gets the name of the first RDF property, and calls the method
     * Sentence.print which will print the corresponding English sentence (the
     * predicate).
     * If this property is 'by reference' (ie the object of the statement is
     * another SVG entity), it prints "an entity called $resource, which
     * $theResourceSVGDesc" or "the entity $resource" (where $resource is the
     * value of the 'resource' attribute of the RDF property node: the
     * statement 'Object'), depending on wether or not the entity $resource
     * has already been mentionned.
     * Of course, if the RDF property node has a child node named 'rdf:Bag',
     * it previously prints:
     * "several elements"
     * and does the required enumeration.
     *
     * Then it calls a method of Class Sentence which prints the sentences
     * corresponding to the attributes of the RDF property node (other than
     * 'resource', of course).
     *
     * Now, if the processing of the RDF statement did not result in an
     * enumeration of objects (thanx to a
     * 'rdf:Bag' node), it recursively calls the spitDesc method of the
     * mentionned entity, object of the RDF statement processed (whose id is
     * therefore $resource). 
     * For applying such a call it first looks in tableRDF wether such an
     * entity has already been described, and if not (ie there is a key
     * corresponding to $resource), it extracts the AElementRDF holding this
     * entity description off the table and applies spitDesc to it.
     * Such a recursive call is here to avoid a 'robot-like' description of
     * an SVG document, only listing all the rdf triplets, thus repeating
     * several times the same subject in a row.
     *
     * Eventually, if there is another property, it goes on to that one, after
     * having printed a linkword randomly chosen among Also, Moreover, and
     * Furthermore (another 'trying-not-to-speak-like-a-robot' feature).
     **/

    public void spitDesc(DocumentMixte doc) throws Exception {
	Hashtable tableSVG, tableRDF;
	String id, propertyName, resourceId;
	AElementSVG eltSVG;
	AElementRDF eltRDF;
	Node propertyNode;
	boolean transitive;
	
	Sentence sentence = doc.getSentence();
	tableSVG = doc.getTableSVG();
	tableRDF = doc.getTableRDF();
	id = generator.getAttribute("about");
	eltSVG = (AElementSVG)tableSVG.get(id);
	propertyNode = generator.getFirstChild();

	tableRDF.remove(id);

	while(propertyNode != null) {
	    if(propertyNode.getNodeType() == propertyNode.ELEMENT_NODE) {
		Property proper = new Property((Element)propertyNode,
					       id, tableSVG);
		proper.subjectDesc(firstLoop);
		firstLoop = false;
		resourceId = proper.getResourceId();
		transitive = proper.printPredicate(sentence);
		if(transitive) {
		    if(resourceId.equals("")) {
			System.out.println("several elements:");
			Node node =  propertyNode.getFirstChild();
			while(node != null) {
			   if(node.getNodeName().equalsIgnoreCase("rdf:Bag")) {
				Node childNode = node.getFirstChild();
				while(childNode != null) {
				    if(childNode.getNodeName().equalsIgnoreCase
				       ("rdf:li")){ 
					System.out.print(" -");
					proper = new Property(
					     (Element)childNode, id, tableSVG);
				        proper.objectDesc(sentence);
				    }
				    childNode = childNode.getNextSibling();
				}
			    }
			    node = node.getNextSibling();
			}
		    }
		    else {
			proper.objectDesc(sentence);
			eltRDF = (AElementRDF)tableRDF.get(resourceId);
			if(eltRDF != null) {
			    eltRDF.spitDesc(doc);
			}
		    }
		}
	    }
	    propertyNode = propertyNode.getNextSibling();
	}
    }
}		
