/*******************************************************************************
 * Copyright (c) 2002, 2004 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug fixes
 *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49445
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor.model;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.ant.internal.ui.editor.outline.AntModel;
import org.eclipse.ant.internal.ui.editor.outline.IProblem;
import org.eclipse.ant.internal.ui.editor.outline.LocationProvider;
import org.eclipse.ant.internal.ui.editor.outline.XMLProblem;
import org.eclipse.ant.internal.ui.model.AntImageDescriptor;
import org.eclipse.ant.internal.ui.model.AntUIImages;
import org.eclipse.ant.internal.ui.model.AntUtil;
import org.eclipse.ant.internal.ui.model.IAntUIConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;

/**
 * General representation of an Ant buildfile element.
 * 
 */
public class AntElementNode implements IAdaptable {
    
	/**
	 * The offset of the corresponding source.
	 * @see #getOffset()
	 */
	protected int offset= -1;
	
	/**
	 * The length of the corresponding source.
	 * @see #getLength()
	 */
	protected int length= -1;
	
	/**
	 * The length of the source to select for this node
	 */
	protected int selectionLength;
	
    /**
     * The parent node.
     */
    protected AntElementNode parent;
    
    /**
     * The import node that "imported" this element
     */
    private AntElementNode importNode;

    /**
     * The child nodes.
     */
    protected List childNodes= null;

    /**
     * The (tag-)name of the element.
     */
    protected String name;

	/**
	 * Whether this element has been generated as part of an element hierarchy
	 * this has problems. This is the severity of the problem.
	 * @see XMLProblem#NO_PROBLEM
	 * @see XMLProblem#SEVERITY_ERROR
	 * @see XMLProblem#SEVERITY_WARNING
	 * @see XMLProblem#SEVERITY_FATAL_ERROR
	 */
	private int problemSeverity= XMLProblem.NO_PROBLEM;
	
	/**
	 * The absolute file system path of the file this element is
	 * defined within.
	 */
	private String filePath;
	
	/**
	 * Whether this element has been generated from an external entity definition
	 */
	private boolean isExternal = false;
	
	/**
	 * The unique (in the corresponding element tree) path of this element.
	 */
	private String fElementPath;
	
	/**
	 * The (not necessarily unique) identifier of this element.
	 */
	private String fElementIdentifier;

	/**
	 * The problem associated with this node. May be <code>null</code>.
     */
	private IProblem fProblem;
	
	/**
	 * Only used when opening an import element to indicate the location in the imported file
	 */
	private int fLine;
	private int fColumn;

	/**
     * Creates an instance with the specified name.
     */
    public AntElementNode(String aName) {
       name = aName;
    }
    
    /**
     * Creates an instance with the specified name.
     */
    public AntElementNode() {
    }
    
    
    /**
     * Returns the name.
     */
    public String getName() {
        return name;
    }
    
    
    /**
     * Returns the label that is used for display in outline view.
     * <P>
     * The default implementation returns just the same as the method <code>getName()</code>.
     * Override this method in your own subclass for special elements in order to provide a
     * custom label.
     */
    public String getLabel() {
    	return getName();
    }
    
    
    /**
     * Returns the child nodes.
     */
    public List getChildNodes() {
        return childNodes;
    }
    
    /**
     * Returns all the descendents of this target
     */
    public List getDescendents() {
    	if (childNodes == null) {
    		return null;
    	}
    	List descendents= new ArrayList();
        determineDescendents(descendents, childNodes);
        
        return descendents;
    }
    
    
    private void determineDescendents(List descendents, List childrenNodes) {
		Iterator itr= childrenNodes.iterator();
        while (itr.hasNext()) {
			AntElementNode element = (AntElementNode) itr.next();
			if (element.hasChildren()) {
				determineDescendents(descendents, element.getChildNodes());
			}
			descendents.add(element);
		}
	}

	/**
     * Returns the parent <code>AntElementNode</code>.
     * 
     * @return the parent or <code>null</code> if this element has no parent.
     */
    public AntElementNode getParentNode() {
        return parent;
    } 
    
    public AntProjectNode getProjectNode() {
    	AntElementNode projectParent= getParentNode();
    	while (projectParent != null && !(projectParent instanceof AntProjectNode)) {
    		projectParent= projectParent.getParentNode();
    	}
    	return (AntProjectNode)projectParent;
    }
    
    
    /**
     * Adds the specified element as child.
     * <P>
     * The specified element will have this assigned as its parent.
     * 
     */
    public void addChildNode(AntElementNode childElement) {
    	childElement.setParent(this);
        if (childNodes == null) {
        	childNodes= new ArrayList();
        }
        childNodes.add(childElement);
    }
    
	protected void setParent(AntElementNode node) {
		parent= node;
	}

	/**
	 * Sets the absolute file system path of the file this element is defined
	 * within.
	 */
	public void setFilePath(String path) {
		URL url= null;
		try {		
			url= new URL(path);
		} catch (MalformedURLException e) {		
			filePath= path;
			return;
		}
		filePath = new Path(new File(url.getPath()).getAbsolutePath()).toString();
	}
	
	/**
	 * Returns the absolute file system path of the file this element is defined
     * within. Only relevant for nodes that are external
     * @see #isExternal()
     */
	public String getFilePath() {
		return filePath;
	}

    /**
	 * Returns the 0-based index of the first character of the source code for this element,
	 * relative to the source buffer in which this element is contained.
	 * 
	 * @return the 0-based index of the first character of the source code for this element,
	 * relative to the source buffer in which this element is contained
	 */
	public int getOffset() {
		return offset;
	}

	
	/**
	 * Sets the offset.
	 * 
	 * @see #getOffset()
	 */
	public void setOffset(int anOffset) {
		offset = anOffset;
	}
	
	/**
	 * Returns the number of characters of the source code for this element,
	 * relative to the source buffer in which this element is contained.
	 * 
	 * @return the number of characters of the source code for this element,
	 * relative to the source buffer in which this element is contained
	 */
    public int getLength() {
        return length;
    }

	/**
	 * Sets the length.
	 * 
	 * @see #getLength()
	 */
	public void setLength(int aLength) {
		length = aLength;
		if (fProblem != null && fProblem instanceof XMLProblem) {
			((XMLProblem)fProblem).setLength(aLength);
			fProblem= null;
		}
	}

	/**
	 * Returns a string representation of this element.
	 */
	public String toString() {
		return "Ant Element Node: " + getLabel() + " Offset: " + getOffset() + " Length: " + getLength();  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
	}
	
	/**
	 * Returns whether this element has been generated as part of an element
	 * hierarchy this is not complete as a result of an error.
	 */
	public boolean isErrorNode() {
		return problemSeverity == XMLProblem.SEVERITY_ERROR || problemSeverity == XMLProblem.SEVERITY_FATAL_ERROR;
	}
	
	/**
	 * Returns whether this element has been generated as part of an element
	 * hierarchy that has warning(s) associated with it
	 */
	public boolean isWarningNode() {
		return problemSeverity == XMLProblem.SEVERITY_WARNING;
	}
	
	/**
	 * Sets whether this element has been generated as part of an element
	 * hierarchy that has problems. The severity of the problem is provided.
	 */
	public void setProblemSeverity(int severity) {
		this.problemSeverity= severity;
	}
	
	/**
	 * Returns whether this xml element is defined in an external entity.
	 * 
	 * @return boolean
	 */
	public boolean isExternal() {
		return isExternal;
	}

	/**
	 * Sets whether this xml element is defined in an external entity.
	 */
	public void setExternal(boolean isExternal) {
		this.isExternal = isExternal;
	}
	
	private String getElementPath() {
		if (fElementPath == null) {
			StringBuffer buffer= new StringBuffer(getParentNode() != null ? getParentNode().getElementPath() : ""); //$NON-NLS-1$
			buffer.append('/');
			buffer.append(getElementIdentifier());
			buffer.append('[');
			buffer.append(getParentNode() != null ? getParentNode().getElementIndexOf(this) : 0);
			buffer.append(']');
			
			fElementPath= buffer.toString();
		}
		return fElementPath;
	}

	private String getElementIdentifier() {
		if (fElementIdentifier == null) {
			StringBuffer buffer= escape(new StringBuffer(getName() != null ? getName() : ""), '\\', "$/[]\\"); //$NON-NLS-1$ //$NON-NLS-2$
			buffer.append('$');
			buffer.append(escape(new StringBuffer(getLabel() != null ? getLabel() : ""), '\\', "$/[]\\").toString()); //$NON-NLS-1$ //$NON-NLS-2$
			
			fElementIdentifier= buffer.toString();
		}
		return fElementIdentifier;
	}

	private StringBuffer escape(StringBuffer sb, char esc, String special) {
		for (int i= 0; i < sb.length(); i++) {
			if (special.indexOf(sb.charAt(i)) >= 0) {
				sb.insert(i++, esc);
			}
		}

		return sb;
	}

	private int getElementIndexOf(AntElementNode child) {
		if (getChildNodes() == null) {
			return -1;
		}
		
		int result= -1;
		
		Iterator iter= getChildNodes().iterator();
		AntElementNode current= null;
		while (current != child && iter.hasNext()) {
			current= (AntElementNode) iter.next();
			if (child.getElementIdentifier().equals(current.getElementIdentifier()))
				result++;
		}
		
		if (current != child) {
			return -1;
		}
		
		return result;
	}

	/*
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object o2) {
		// prepared to be used in an IElementComparer, depends on http://dev.eclipse.org/bugs/show_bug.cgi?id=32254
		Object o1= this;
		
		if (o1 == o2) {
			return true;
		}
		if (o1 == null || o2 == null) {
			return false;
		}
		if (!(o1 instanceof AntElementNode || o2 instanceof AntElementNode)) {
			return o2.equals(o1);
		}
		if (!(o1 instanceof AntElementNode && o2 instanceof AntElementNode)) {
			return false;
		}
		
		AntElementNode e1= (AntElementNode) o1;
		AntElementNode e2= (AntElementNode) o2;
	
		return e1.getElementPath().equals(e2.getElementPath());
	}

	/*
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		// prepared to be used in an IElementComparer, depends on http://dev.eclipse.org/bugs/show_bug.cgi?id=32254
		
		return getElementPath().hashCode();
	}

	/**
	 * Returns the length of source to select for this node.
	 * @return the length of source to select
	 */
	public int getSelectionLength() {
		return selectionLength;
	}
	
	public void setSelectionLength(int selectionLength) {
		this.selectionLength= selectionLength;
	}
	
	/**
	 * Returns the node with the narrowest source range that contains the offset.
	 * It may be this node or one of its children or <code>null</code> if the offset is not in the source range of this node.
	 * @param sourceOffset The source offset
	 * @return the node that includes the offset in its source range or <code>null</code>
	 */
	public AntElementNode getNode(int sourceOffset) {
		if (childNodes != null) {
			for (Iterator iter = childNodes.iterator(); iter.hasNext(); ) {
				AntElementNode node = (AntElementNode) iter.next();
				AntElementNode containingNode= node.getNode(sourceOffset);
				if (containingNode != null) {
					return containingNode;
				}
			}
		}
		if (length == -1 && offset <= sourceOffset && !isExternal()) { //this is still an open element
			return this;
		}
		if (offset <= sourceOffset && sourceOffset <= (offset + length - 2)) {
			return this;
		}
		
		return null;
	}
	
	public Image getImage() {
		int flags = 0;
		
		if (isErrorNode()) {
			flags = flags | AntImageDescriptor.HAS_ERRORS;
		} else if (isWarningNode()) {
			flags = flags | AntImageDescriptor.HAS_WARNINGS;
		}
		if(importNode != null || isExternal()){
			flags = flags | AntImageDescriptor.IMPORTED;
		}
		ImageDescriptor base= getBaseImageDescriptor();
		return AntUIImages.getImage(new AntImageDescriptor(base, flags));			
	}

	protected ImageDescriptor getBaseImageDescriptor() {
		return AntUIImages.getImageDescriptor(IAntUIConstants.IMG_TASK_PROPOSAL);
	}
	
	protected AntModel getAntModel() {
		AntElementNode parentNode= getParentNode();
		while (!(parentNode instanceof AntProjectNode)) {
			parentNode= parentNode.getParentNode();
		}
		return parentNode.getAntModel();
	}

	/**
	 * Sets the problem associated with this element
	 * @param problem The problem associated with this element.
	 */
	public void associatedProblem(IProblem problem) {
		fProblem= problem;
	}

	protected void appendEntityName(StringBuffer displayName) {
		String path= getFilePath();
		
		if (getImportNode() != null) {
			displayName.append(MessageFormat.format(AntModelMessages.getString("AntElementNode.9"), new String[]{getImportNode().getLabel()})); //$NON-NLS-1$
		} else {
			String entityName= getAntModel().getEntityName(path);
			displayName.append(MessageFormat.format(AntModelMessages.getString("AntElementNode.9"), new String[]{entityName})); //$NON-NLS-1$
		}
	}
	
	public AntElementNode getImportNode() {
		return importNode;
	}
	
	public void setImportNode(AntElementNode importNode) {
		this.importNode = importNode;
	}
	
	public boolean hasChildren() {
		if (childNodes == null) {
			return false;
		}
		return !childNodes.isEmpty();
	}

	public void reset() {
		childNodes= null;
	}

	public void setExternalInfo(int line, int column) {
		fLine= line;
		fColumn= column;
	}
	
	public int[] getExternalInfo() {
		return new int[] {fLine, fColumn};
	}
	
	public IFile getIFile() {
		IFile file;
		if (isExternal()) {
			file= AntUtil.getFileForLocation(filePath, null);
		} else {
			LocationProvider locationProvider= getAntModel().getLocationProvider();
			file= locationProvider.getFile();
		}
		return file;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}
}