/**
 * Class Xstatement
 * The class which is in charge of building the JComponent that contains the
 * rdf statement : 3 labelized comboBoxes, set as protected attributes, in
 * order to be accessed by other classes which may process the information
 * offered by the boxes.
 * Also gives access to the processed DocumentMixte (DOM tree image of the
 * svg file with rdf metadatas) by setting it as a protected attribute as well.
 * Implements some private methods useful to fill the boxes with the right
 * items, considering the DocumentMixte beeing processed.
 * The public method 'reload' allows other classes to set a new DocumentMixte
 * and to modify the boxes in consequence.
 **/

package axsvg.edition;

import axsvg.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Xstatement {
    //The DocumentMixte beeing processed
    protected DocumentMixte docMixte;

    //The Hastable that links a property name with its meaning (ie the
    //corresponding english sentence)
    protected Hashtable propertiesTable;

    //The box that contains all the possible subjects for the RDF statement
    protected JComboBox subjectBox;

    //The box that contains all the possible predicates  for the RDF statement
    protected JComboBox predicateBox;

    //The box that contains all the possible objects for the RDF statement
    protected JComboBox objectBox;

    /**
     * Method Xstatement.
     * The constructor of the class.
     * @param the DocumentMixte to be processed.
     **/
    public Xstatement(DocumentMixte doc) {
	docMixte = doc;
	propertiesTable = docMixte.getSentence().getTranslator();	
    }

    /**
     * Method reload
     * @param the new DocumentMixte to be processed.
     * It resets the attributes and refill the boxes in consequence.
     **/
    public void reload(DocumentMixte doc) {
	docMixte = doc;
	propertiesTable = docMixte.getSentence().getTranslator();
	fillBoxes();
    }

    /**
     * Method fillOneBox
     * @param a JCombobox
     * @param an Enumeration
     * It fills the given box with the elements of the given Enumeration.
     **/
    private void fillOneBox(JComboBox box, Enumeration entites) {
	//resets the box (delete all former items)
	if(box.getItemCount() != 0) box.removeAllItems();
	if(!entites.hasMoreElements()) return;
	String leNom = (String)entites.nextElement();
	
	//removes the '#' that may be at begining of an entity name.
	if(leNom.startsWith("#")) {
	    leNom = leNom.substring(1);
	}
	box.addItem(leNom);	
	while(entites.hasMoreElements()) {
	    leNom = (String)entites.nextElement();
	    if(leNom.startsWith("#")) {
		leNom = leNom.substring(1);
	    }

	    //Sorts the items in alphabetical order.
	    int i=0;
	    while(leNom.compareTo(box.getItemAt(i)) > 0) {
		i++;
		if(i == box.getItemCount()) break;
	    }
	    box.insertItemAt(leNom, i);
	}
	box.setMaximumRowCount(15);
	return;
    }

    /**
     * Method createLebeledBox
     * @param a JComboBox
     * @param a String
     * @return a panel which is basicaly made of the given
     * JComboBox labelized with the given String.
     **/
    private Component createLabeledBox(JComboBox box, String name) {
	final JLabel label = new JLabel(name);
        /*
         * An easy way to put space between a top-level container
         * and its contents is to put the contents in a JPanel
         * that has an "empty" border.
         */
        JPanel element = new JPanel();
        /*element.setBorder(BorderFactory.createEmptyBorder(
                                        0, //top
                                        5, //left
                                        5, //bottom
                                        5) //right
                                        );
	*/
	element.setLayout(new GridLayout(0, 1));
        element.add(label);
	element.add(box);

        return(element);
    }


    /**
     * Method createStatement.
     * @return a bordered panel that contains the 3 labelized comboboxes
     * which constitutes the rdf statement to be edited.
     **/
    public Component createStatement() {	
	JPanel statement = new JPanel();

	statement.setLayout(new FlowLayout());
	statement.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Statement"),
                                BorderFactory.createEmptyBorder(5,5,5,5)));

	subjectBox = new JComboBox();
	objectBox = new JComboBox();
	predicateBox = new JComboBox();
	fillBoxes();
	// tries to set the selected item at index 0 or 1
	// IF the comboBoxes are not empty.
	try {
	subjectBox.setSelectedIndex(0);
	predicateBox.setSelectedIndex(0);
	objectBox.setSelectedIndex(1);
	} catch(IllegalArgumentException e) {}
	statement.add(createLabeledBox(subjectBox,"Subject"));
	statement.add(createLabeledBox(predicateBox,"Predicate"));
	statement.add(createLabeledBox(objectBox,"Object"));


	return(statement);
    }

    /**
     * Method fillBoxes
     * Calls the fillOneBox method over each of the 3 boxes, with the
     * appropriate Enumeration computed on the basis of the DocumentMixte
     * to be processed (which is a protected attribute of this object)
     **/
    private void fillBoxes() {
	//The subject box is filled with the SVG entities id of the
	//processed svg file (ie svg elements that have an id attribute)...
	Enumeration entitesSVG = docMixte.getTableSVG().keys();
	fillOneBox(subjectBox, entitesSVG);

	//The predicate box is filled with the names of the properties
	//of the axsvg namespace, defined in the rdf Schema axsvg-schema.rdf
	Enumeration properties =  propertiesTable.keys();
	fillOneBox(predicateBox, properties);

	//A good programmer would have looked for the way to clone an
	//Enumeration longer than I did.
	entitesSVG = docMixte.getTableSVG().keys();
	fillOneBox(objectBox, entitesSVG);
    }    
}
