/* *******************************************************************
 * Copyright (c) 1999-2001 Xerox Corporation, 
 *               2002 Palo Alto Research Center, Incorporated (PARC).
 * 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: 
 *     Xerox/PARC     initial implementation 
 * ******************************************************************/


package org.aspectj.ajde.ui;

import java.io.*;
import java.util.*;

import org.aspectj.bridge.*;

/**
 * @author Mik Kersten
 * 
 * TODO: clean-up after merging of org.aspectj.asm.StructureNode
 */
public class BuildConfigNode {



	protected BuildConfigNode parent = null;
	protected String name = "";
	protected Kind kind;
	// children.listIterator() should support remove() operation
	protected List children = new ArrayList();
	protected IMessage message = null;
	protected ISourceLocation sourceLocation = null;

	/**
	 * Used during serialization.
	 */
	public BuildConfigNode() { }

//	public BuildConfigNode(String name, String kind, String resourcePath, List children) {
//		this(name, kind, children);
//		this.resourcePath = resourcePath;
//	}

	public BuildConfigNode(String name, Kind kind, String resourcePath) {	
		this(name, kind);
		this.kind = kind;
		this.resourcePath = resourcePath;	
	}

//	public BuildConfigNode(String name, Kind kind, List children) {
//		this.name = name;
//		this.kind = kind;
//		if (children != null) {
//			this.children = children;
//		}
//		setParents();
//	}

	public BuildConfigNode(String name, Kind kind) {
		this.name = name;
		this.kind = kind;
	}

	public String toString() {
		return  name;
	}

	public List getChildren() {
		return children;
	}

	public void addChild(BuildConfigNode child) {
		if (children == null) {
			children = new ArrayList();
		}
		children.add(child);
		child.setParent(this);
	}
    
	public void addChild(int position, BuildConfigNode child) {
		if (children == null) {
			children = new ArrayList();
		}
		children.add(position, child);
		child.setParent(this);
	}
    
	public boolean removeChild(BuildConfigNode child) {
		child.setParent(null);
		return children.remove(child);	
	}

	/**
	 * Comparison is string-name based only.
	 */
	public int compareTo(Object o) throws ClassCastException {
		if (this == o) {
			return 0;
		} else {
			BuildConfigNode sn = (BuildConfigNode)o;
			return this.getName().compareTo(sn.getName());
		}
	}

	public String getName() {
		return name;
	}

	public ISourceLocation getSourceLocation() {
		return sourceLocation;
	}

	public void setSourceLocation(ISourceLocation sourceLocation) {
		this.sourceLocation = sourceLocation;
	}

	public IMessage getMessage() {
		return message;
	}

	public void setMessage(IMessage message) {
		this.message = message;
	}

	public BuildConfigNode getParent() {
		return parent;
	}

	public void setParent(BuildConfigNode parent) {
		this.parent = parent;
	}

//	private void setParents() {
//		if (children == null) return;
//		for (Iterator it = children.iterator(); it.hasNext(); ) {
//			((BuildConfigNode)it.next()).setParent(this);	
//		}	
//	}

	public void setName(String string) {
		name = string;
	}
	

	private String resourcePath;
	private boolean isActive = true;
	
	public String getResourcePath() {
		return resourcePath;
	}

	public void setResourcePath(String resourcePath) {
		this.resourcePath = resourcePath;
	}
	
	public boolean isValidResource() {
		return name.endsWith(".java") 
			|| name.endsWith(".aj") 
			|| name.endsWith(".lst");	
	}
	
	public boolean isActive() {
		return isActive;
	}

	public void setActive(boolean isActive) {
		this.isActive = isActive;
	}

	/**
	 * Uses "typesafe enum" pattern.
	 */
	public static class Kind implements Serializable {
		
		public static final Kind FILE_JAVA = new Kind("Java source file");
		public static final Kind FILE_ASPECTJ = new Kind("AspectJ source file");
		public static final Kind FILE_LST = new Kind("build configuration file");
		public static final Kind ERROR = new Kind("error");
		public static final Kind DIRECTORY = new Kind("directory");


		public static final Kind[] ALL = { FILE_JAVA, FILE_ASPECTJ, FILE_LST, DIRECTORY };
		
		private final String name;
		
		private Kind(String name) {
			this.name = name;
		}
		
		public String toString() {
			return name;
		}	
		
		public boolean equals(Object o) {
			return o.equals(name);	
		}
		
		public boolean isDeclareKind() {
			return name.startsWith("declare");	
		} 

		// The 4 declarations below are necessary for serialization
		private static int nextOrdinal = 0;
		private final int ordinal = nextOrdinal++;
		private Object readResolve() throws ObjectStreamException {
			return ALL[ordinal];
		}
	}
	
	public Kind getBuildConfigNodeKind() {
		return kind;
	}
}



