package net.trevize.pascalvoc;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;
import java.util.List;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import net.trevize.galatee.Galatee;
import net.trevize.galatee.GalateeProperties;
import net.trevize.pascalvoc.annotation.jaxb.Annotation;
import net.trevize.pascalvoc.annotation.jaxb.Filename;

/**
 * 
 * 
 * @author Nicolas James <nicolas.james@gmail.com> [[http://njames.trevize.net]]
 * PascalVOCBrowser.java - Jun 30, 2010
 */

public class PascalVOCBrowser {

	private Galatee galatee;

	public PascalVOCBrowser() {
		JFrame frame = new JFrame("PascalVOC browser");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Dimension screen_dim = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setSize((int) (screen_dim.width * 10. / 12.),
				(int) (screen_dim.height * 10. / 12.));
		frame.setLocationRelativeTo(null);

		initGalatee();
		frame.getContentPane().add(galatee);

		frame.setVisible(true);
	}

	private void initGalatee() {
		String annotations_path = PascalVOCProperties
				.getPascalvoc_devkit_path()
				+ File.separator
				+ PascalVOCProperties.getPascalvoc_annotations_subdir();
		String images_path = PascalVOCProperties.getPascalvoc_devkit_path()
				+ File.separator
				+ PascalVOCProperties.getPascalvoc_jpgimages_path();

		//create the JAXBContext.
		JAXBContext jaxb_context = null;
		try {
			jaxb_context = JAXBContext
					.newInstance("net.trevize.pascalvoc.annotation.jaxb");
		} catch (JAXBException e) {
			e.printStackTrace();
		}

		//instantiate an Unmarshaller.
		Unmarshaller u = null;
		try {
			u = jaxb_context.createUnmarshaller();
		} catch (JAXBException e) {
			e.printStackTrace();
		}

		//get all the annotation XML files.
		File[] annotations_file = new File(annotations_path).listFiles();

		Vector<URI> v_uri = new Vector<URI>();
		Vector<Vector<Object>> v_object = new Vector<Vector<Object>>();

		for (File f : annotations_file) {
			//create an XMLStreamReader on the annotation file.
			XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
			XMLStreamReader xmlsr = null;
			try {
				xmlsr = xmlInputFactory
						.createXMLStreamReader(new FileInputStream(f));
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
			} catch (XMLStreamException e1) {
				e1.printStackTrace();
			}

			//load the annotation.
			Annotation annotation = null;
			try {
				annotation = (Annotation) u.unmarshal(xmlsr);
			} catch (JAXBException e) {
				e.printStackTrace();
			}

			String filename = null;
			StringBuffer text_description = new StringBuffer(); //textual description for the Galatee browser, the first element in the data list of each image.
			Vector<net.trevize.pascalvoc.annotation.jaxb.Object> annotation_object_list = new Vector<net.trevize.pascalvoc.annotation.jaxb.Object>(); //the second element of each image (the list of her annotated objects).

			List<Object> annotation_content = annotation.getContent(); //like we have a XSD choice element in the XSD, we can't get directly the XML elements we specifically want.
			for (Object o : annotation_content) {
				if (o instanceof Filename) {
					filename = ((Filename) o).getContent();
				}

				else

				if (o instanceof net.trevize.pascalvoc.annotation.jaxb.Object) {
					net.trevize.pascalvoc.annotation.jaxb.Object annotation_object = (net.trevize.pascalvoc.annotation.jaxb.Object) o;

					text_description.append(annotation_object.getName()
							.getContent()
							+ "\n");

					annotation_object_list.add(annotation_object);
				}
			}

			//we add the URI to the list of the URI for the Galatee browser.
			v_uri.add(new File(PascalVOCProperties.getPascalvoc_devkit_path()
					+ File.separator
					+ PascalVOCProperties.getPascalvoc_jpgimages_path()
					+ File.separator + filename).toURI());

			//prepare the data for this image: we add the two elements (the textual description and the list of annotated objects).
			Vector<Object> v = new Vector<Object>();
			v.add(filename + "\n" + text_description.toString()); //the textual description.
			v.add(annotation_object_list); //the list of annotated objects.
			
			v_object.add(v); //add the data vector to the list of the data for the Galatee browser.
		}

		galatee = new Galatee(v_uri, v_object, new Dimension(GalateeProperties
				.getDefault_image_width(), GalateeProperties
				.getDefault_image_height()), GalateeProperties
				.getDefault_description_width(), GalateeProperties
				.getDefault_number_of_column());

		galatee.addGalateeListener(new GListenerImpl());
	}

	public static void main(String[] args) {
		// setting the system look and feel
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}

		new PascalVOCBrowser();
	}

}

