package org.eclipse.jpt.jpadiagrameditor.ui.internal.util;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.JPADiagramEditorPlugin;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.i18n.JPAEditorMessages;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.util.ModelIntegrationUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

public class EntitiesCoordinatesXML {
	
	private Document document;
	private Element rootElement;
	private String projectName;
	
	public static final String XML_ELEMENT_POSITION = "\n\t\t"; //$NON-NLS-1$
		
	public EntitiesCoordinatesXML(String projectName){
		this.projectName = projectName;
		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
		documentBuilderFactory.setNamespaceAware(true);
		InputStream is = null;
		try {
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			is = (InputStream)findXMLFile(true);
			document = documentBuilder.parse(is);
			rootElement = document.getDocumentElement();
		} catch (ParserConfigurationException e) {
			JPADiagramEditorPlugin.logError(JPAEditorMessages.EntitiesCoordinatesXML_CannotParseFileErrorMSG, e);
		} catch (SAXException e) {
			JPADiagramEditorPlugin.logError(JPAEditorMessages.EntitiesCoordinatesXML_CannotParseFileErrorMSG, e);
		} catch (IOException e) {
			JPADiagramEditorPlugin.logError(JPAEditorMessages.EntitiesCoordinatesXML_CannotReadFileErrorMSG, e);
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
					// ignore
				}
		}
	}

	
    private Closeable findXMLFile(boolean inputStream) throws FileNotFoundException{
    	IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
		try {
			IResource[] resources = project.members();
			for (IResource res : resources) {
				if (res instanceof IFolder) {
					IFile existingXMLFile = ((IFolder) res).getFile(projectName + "." + ModelIntegrationUtil.DIAGRAM_XML_FILE_EXTENSION); //$NON-NLS-1$
					if (existingXMLFile != null && existingXMLFile.exists()) {
						return inputStream ? 
								new FileInputStream(new File(existingXMLFile.getLocationURI())) :
									new FileOutputStream(new File(existingXMLFile.getLocationURI()));
					}
				}
			}
		} catch (CoreException e) {
			JPADiagramEditorPlugin.logError(JPAEditorMessages.EntitiesCoordinatesXML_CannotObtainProjectErrorMSG, e);
		}
		IFile existingXMLFile = project.getFile(ModelIntegrationUtil.getDiagramsXMLFolderPath(project).append(projectName).addFileExtension(ModelIntegrationUtil.DIAGRAM_XML_FILE_EXTENSION));
		return inputStream ? new FileInputStream(new File(existingXMLFile.getLocationURI())) :
									new FileOutputStream(new File(existingXMLFile.getLocationURI()));
    }
	
    synchronized public void store() {
    	IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
    	Diagram diagram = ModelIntegrationUtil.getDiagramByProject(project);
		List<Shape> picts = diagram.getChildren();
		Iterator<Shape> it = picts.iterator();
		// collecting data from the saved pictograms
		document.removeChild(rootElement);
		rootElement = document.createElement("entities"); //$NON-NLS-1$
		document.appendChild(rootElement);

		while (it.hasNext()) {
			Shape pict = it.next();
			String name = Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.PROP_ENTITY_CLASS_NAME);

			RoundedRectangle rect = (RoundedRectangle) pict.getGraphicsAlgorithm();

			boolean isPrimaryCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict,
							JPAEditorConstants.PRIMARY_COLLAPSED));
			boolean isRelationCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict,
							JPAEditorConstants.RELATION_COLLAPSED));
			boolean isBasicCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict,
							JPAEditorConstants.BASIC_COLLAPSED));

			Element entity = createEntityElementTag(document, rootElement, JPAEditorConstants.ENTITY_XML_TAG, XML_ELEMENT_POSITION);
			Text nameText = document.createTextNode(name);
			Element entityName = document.createElement(JPAEditorConstants.ENTITY_NAME_TAG);
			createChildElementTag(document, nameText, entityName, entity, XML_ELEMENT_POSITION);

			Text width = document.createTextNode(String.valueOf(rect.getWidth()));
			Element entityWidth = document.createElement(JPAEditorConstants.ENTITY_WIDTH_TAG);
			createChildElementTag(document, width, entityWidth, entity, XML_ELEMENT_POSITION);

			Text height = document.createTextNode(String.valueOf(rect.getHeight()));
			Element entityHeight = document.createElement(JPAEditorConstants.ENTITY_HEIGHT_TAG);
			createChildElementTag(document, height, entityHeight, entity, XML_ELEMENT_POSITION);

			Text xCoordinate = document.createTextNode(String.valueOf(rect.getX()));
			Element entityXCoordinate = document.createElement(JPAEditorConstants.ENTITY_X_COORDINATE_TAG);
			createChildElementTag(document, xCoordinate, entityXCoordinate,	entity, XML_ELEMENT_POSITION);

			Text yCoordinate = document.createTextNode(String.valueOf(rect.getY()));
			Element entityYCoordinate = document.createElement(JPAEditorConstants.ENTITY_Y_COORDINATE_TAG);
			createChildElementTag(document, yCoordinate, entityYCoordinate,	entity, XML_ELEMENT_POSITION);
			
			Text primaryCollapsed = document.createTextNode(String.valueOf(isPrimaryCollapsed));
			Element entityPrimaryCollapsed = document.createElement(JPAEditorConstants.ENTITY_PRIMARY_SECTION_STATE_TAG);
			createChildElementTag(document, primaryCollapsed, entityPrimaryCollapsed, entity, XML_ELEMENT_POSITION);	
			
			Text relationCollapsed = document.createTextNode(String.valueOf(isRelationCollapsed));
			Element entityRelationCollapsed = document.createElement(JPAEditorConstants.ENTITY_RELATION_SECTION_STATE_TAG);
			createChildElementTag(document, relationCollapsed, entityRelationCollapsed,	entity, XML_ELEMENT_POSITION);
			
			Text basicCollapsed = document.createTextNode(String.valueOf(isBasicCollapsed));
			Element entityBasicCollapsed = document.createElement(JPAEditorConstants.ENTITY_BASIC_SECTION_STATE_TAG);
			createChildElementTag(document, basicCollapsed, entityBasicCollapsed,	entity, "\n\t");	 //$NON-NLS-1$
			
			rootElement.appendChild(document.createTextNode("\n")); //$NON-NLS-1$

		}
		ModelIntegrationUtil.setXmiExists(false);
	}

	synchronized public void load(Hashtable<String, SizePosition> marks){
		
		if(rootElement.getChildNodes().getLength()<=1){
			if(ModelIntegrationUtil.xmiExists()){
				store();
				clean();
			}
		} 
		
		NodeList nodeList = rootElement.getElementsByTagName(JPAEditorConstants.ENTITY_XML_TAG);
		for(int i=0; i<nodeList.getLength();i++){
			Element node = (Element) nodeList.item(i);
			String entityName = node.getElementsByTagName(JPAEditorConstants.ENTITY_NAME_TAG).item(0).getTextContent();
			int width = Integer.parseInt(node.getElementsByTagName(JPAEditorConstants.ENTITY_WIDTH_TAG).item(0).getTextContent());
			int height = Integer.parseInt(node.getElementsByTagName(JPAEditorConstants.ENTITY_HEIGHT_TAG).item(0).getTextContent());
			int xCoordinate = Integer.parseInt(node.getElementsByTagName(JPAEditorConstants.ENTITY_X_COORDINATE_TAG).item(0).getTextContent());
			int yCoordinate = Integer.parseInt(node.getElementsByTagName(JPAEditorConstants.ENTITY_Y_COORDINATE_TAG).item(0).getTextContent());
			boolean isPrimaryCollapsed = Boolean.parseBoolean(node.getElementsByTagName(JPAEditorConstants.ENTITY_PRIMARY_SECTION_STATE_TAG).item(0).getTextContent());
			boolean isRelationCollapsed = Boolean.parseBoolean(node.getElementsByTagName(JPAEditorConstants.ENTITY_RELATION_SECTION_STATE_TAG).item(0).getTextContent());
			boolean isBasicCollapsed = Boolean.parseBoolean(node.getElementsByTagName(JPAEditorConstants.ENTITY_BASIC_SECTION_STATE_TAG).item(0).getTextContent());
			
			SizePosition rectSP = new SizePosition(width, height, xCoordinate, yCoordinate);
			rectSP.primaryCollapsed = isPrimaryCollapsed;
			rectSP.relationCollapsed = isRelationCollapsed;
			rectSP.basicCollapsed = isBasicCollapsed;
			
			marks.put(entityName, rectSP);
		}
		
	}
	
	private Element createEntityElementTag(Document document, Element scheduleElement, String descr, String position) {
		Element job = document.createElement(descr);
		scheduleElement.appendChild(document.createTextNode("\n\t")); //$NON-NLS-1$
		scheduleElement.appendChild(job);
		job.appendChild(document.createTextNode(position));
		
		return job;
	}
	
	private void createChildElementTag(Document document, Text nameText, Element nameEl, Element parentElement, String position) {
		parentElement.appendChild(nameEl);
		nameEl.appendChild(nameText);
		parentElement.appendChild(document.createTextNode(position));
	}
	
	synchronized public void close() {
		OutputStream os = null;
		try {
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			os = (OutputStream)findXMLFile(false);
			transformer.transform(new DOMSource(document), new StreamResult(os));
			os.flush();
		} catch (Exception e) {
			JPADiagramEditorPlugin.logError(JPAEditorMessages.EntitiesCoordinatesXML_CannotCreateDOMFileErrorMSG, e);
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				// ignore
			}
		}
		
		clean();
	}
	
	synchronized public void clean() {
		try {
	    	IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);			
	    	project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
		} catch (CoreException e) {
			JPADiagramEditorPlugin.logError(JPAEditorMessages.EntitiesCoordinatesXML_CannotRefrfreshFile, e);
		}		
		document = null;
		rootElement = null;
	}


}
