/**
 * 
 */
package d2rq;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.event.*;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import javax.swing.*;
import de.fuberlin.wiwiss.d2rq.mapgen.MappingGenerator;

/**
 * graphical interface of the 2nd step of the mapping generation by generate_mapping
 * @author Simeon Polfliet
 * (simeon.polfliet@ensimag.imag.fr)
 */
public class check_mapping implements ActionListener{

	/** List of the attributes and the ontologies entities associated */
	private static LinkedList<String> tabAttributes = new LinkedList<String>();
	private static LinkedList<String> ontoEntities = new LinkedList<String>();
	/** List of attributes to use as labels */
	private LinkedList<String> labels = new LinkedList<String>();
	/** Graphic elements */
	private LinkedList<JTextField> fAttribute = new LinkedList<JTextField>();
	private LinkedList<JTextField> fOntoEntity = new LinkedList<JTextField>();
	private LinkedList<JCheckBox> fLabel = new LinkedList<JCheckBox>();
	private JButton generate;
	private JLabel lTable = new JLabel("Table");
	private JLabel lAttribute = new JLabel("Attribute");
	private JLabel lOntoEntity = new JLabel("Ontology entity associated");
	
	
	private static JFrame frame;
	private generate_mapping gen;
	private MappingGenerator mGen;
	
	/**
	 * Standard constructor
	 * @param f the frame 
	 * @param g the JPannel from grenerate_mapping
	 * @param m the associated MappingGenerator
	 */
	public check_mapping(JFrame f, generate_mapping g, MappingGenerator m){
		frame = f;
		gen = g;
		mGen = m;
		init();
		redraw();
	}
	
	/**
	 * Add an attribute in the list
	 * @param s the attribute name
	 */
	public static void addAttribute(String s){
		tabAttributes.add(s);
	}
	/**
	 * Add a table in the list
	 * @param s the table name
	 */
	public static void addTable(String s){
		tabAttributes.add("###" + s);
	}
	/**
	 * Add an ontology entity in the list
	 * @param s the entity name
	 */
	public static void addOntoEntity(String s){
		ontoEntities.add(s);
	}
	
	/**
	 * Initialisation of the graphic elements
	 */
	private void init(){
		generate = new JButton("Generate");
		generate.setActionCommand("generate");
		generate.addActionListener(this);
		
		Iterator<String> it1 = tabAttributes.iterator();
		Iterator<String> it2 = ontoEntities.iterator();
		while(it1.hasNext()){
			JTextField att = new JTextField(20);
			JTextField ont = new JTextField(20);
			JCheckBox lab = new JCheckBox("is label");
			String ent = it2.next();
			if (ent.toLowerCase().contains(":name")){
				lab.setSelected(true);
			}
			att.setText(it1.next());
			att.setEditable(false);
			ont.setText(ent);
			fAttribute.add(att);
			fOntoEntity.add(ont);		
			fLabel.add(lab);
		}
	}
	
	/**
	 * Add an graphic component 
	 * @param comp the component to add
	 * @param c the GridBagConstraint
	 * @param x the horizontal position 
	 * @param y the vertical position
	 */
	private void addComp(Component comp, GridBagConstraints c, int x, int y){
		c.gridx = x;
		c.gridy = y;
		gen.add(comp, c);
	}
	
	/**
	 * Display the graphic elements
	 */
	private void redraw(){
		gen.removeAll();
		Iterator<JTextField> it1 = fAttribute.iterator();
		Iterator<JTextField> it2 = fOntoEntity.iterator();
		Iterator<JCheckBox> it3 = fLabel.iterator();
		GridBagConstraints c = new GridBagConstraints();
		int i = 0;
		int j = 0;

		addComp(lTable,c,0,i);
		addComp(lAttribute,c,1,i);
		addComp(lOntoEntity,c,2,i++);

		while (it1.hasNext()){
			JTextField att = it1.next();
			JCheckBox lab = it3.next();
			if (att.getText().startsWith("###")){
				j = 0;
				lab.setEnabled(false);
				lab.setVisible(false);
				att.setText(att.getText().substring(3));
			} else {
				j = 1;
			}
			addComp(att, c,j,i);
			addComp(it2.next(), c,2,i);
			addComp(lab, c,3,i++);	
		}

		addComp(generate, c,2,i);
		
		frame.pack();
		frame.validate();
		frame.repaint();
	}
	
	/**
	 * Action handler
	 */
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().contains("generate")){
			generate();
		}
		redraw();
	}
	
	/**
	 * Save the user modifications and finish the generation
	 */
	private void generate(){
		Hashtable<String, String> update = new Hashtable<String, String>();
		LinkedList<String> prefix = gen.getPrefix();
		LinkedList<String> uri = gen.getUri();
		Iterator<JTextField> it1 = fAttribute.iterator();
		Iterator<JTextField> it2 = fOntoEntity.iterator();
		Iterator<JCheckBox> it3 = fLabel.iterator();
		Iterator<String> it4, it5;
		String tableName="";
		while(it1.hasNext()){
			JTextField att = it1.next();
			JTextField ont = it2.next();
			JCheckBox lab = it3.next();
			// Save the association attribute - entity
			if (lab.isEnabled()){
				update.put(att.getText() + tableName + "." + att.getText(), ont.getText());
				// Save the labels
				if (lab.isSelected()){
					labels.add(tableName + "." +att.getText());
				}
			} else {
				tableName = att.getText();
				update.put(tableName, ont.getText());
			}
			it4 = prefix.iterator();
			it5 = uri.iterator();
			// Save the ontologies that were really used
			while(it4.hasNext()){
				String pre = it4.next();
				String url = it5.next();
				if (ont.getText().startsWith(pre)){
					mGen.addUsedOnto(pre + ": <" + url + ">");
				}
			}
		}
		mGen.setLabels(labels);
		mGen.updateDico(update);
		gen.endGeneration();
	}

}
