package eu.dnetlib.dlms.view;


import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ParserXMLView extends DefaultHandler {

	public enum AttributeValue 
	{
		view, 
		entrypoint, 
		label, 
		name, 
		visitby, 
		node
	};

	SAXParser theParser;
	ParserView result;
	Stack<String>lastRelationStack;
	boolean isClosedView;

	public ParserXMLView() throws ParserConfigurationException, SAXException {
		SAXParserFactory spf = SAXParserFactory.newInstance();
		theParser = spf.newSAXParser();
		lastRelationStack= new Stack<String>();
	}

	public void Parse(String FileNamePath) throws SAXException, IOException {
		theParser.parse(FileNamePath, this);
		isClosedView = false;
	}
	
	public void Parse(InputSource source)  throws SAXException, IOException {
		theParser.parse(source, this);
		isClosedView= false;
	}

	// Event Handlers
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if (isClosedView == true)
			throw new SAXException("Error the view must have one View tag",
					null);
		if (result == null) 
		{
			lastRelationStack.clear();
			isClosedView = false;
			result = new ParserView();
			if (!qName.equals(AttributeValue.view.toString()))
				throw new SAXException(
						"Error the view must init with a VieW tag", null);
			if (attributes.getValue(AttributeValue.name.toString()) == null)
				throw new SAXException(
						"Error in the tag View: attribute name missing", null);
			if (attributes.getValue(AttributeValue.entrypoint.toString()) == null)
				throw new SAXException(
						"Error in the tag View: attribute EntryPoint missing",
						null);
			result.addEntryPoint(attributes.getValue(AttributeValue.entrypoint.toString()));
			result.setViewName(attributes.getValue(AttributeValue.name.toString()));
		} 
		else 
		{
			if (qName.equals(AttributeValue.node.toString())) 
			{
				if (attributes.getValue(AttributeValue.name.toString()) == null)
					throw new SAXException("Error in the tag Node: attribute name missing",	null);
				result.AddRelationToCurrent(lastRelationStack.lastElement());
				result.reachNode(attributes.getValue(AttributeValue.name.toString()));
			} 
			else if (qName.equals(AttributeValue.visitby.toString())) 
			{
				if (attributes.getValue(AttributeValue.label.toString()) == null)
					throw new SAXException(
							"Error in the tag VisitBy: attribute label missing",
							null);
				lastRelationStack.push(attributes.getValue(AttributeValue.label.toString()));
			} 
			else
				throw new SAXException("Error in the tag inexpected", null);

		}

		System.out.println("Iniziato un elemento " + qName);
		for (int i = 0; i < attributes.getLength(); i++) {
			System.out.println(attributes.getQName(i) + " : "
					+ attributes.getValue(i));
		}

	}

	public void characters(char[] ch, int start, int length) throws SAXException {

	}

	public void endElement(String uri, String localName, String qName) throws SAXException 
	{
		if (qName.equals(AttributeValue.view.toString()))
			isClosedView = true;
		else if (qName.equals(AttributeValue.node.toString())) 
		{
			try {
				result.relationsClose();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
		else if (qName.equals(AttributeValue.visitby.toString()))
		{
			lastRelationStack.pop();
		}
	}
	
	
	public ParserView getResult()
	{
		return result;
	}

}


