package net.sourceforge.ganttproject.export;

import java.util.Enumeration;

import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;

import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskContainmentHierarchyFacade;

public class TaskHierarchyTreeModel extends DefaultTreeModel implements TreeModel{

	public TaskHierarchyTreeModel(TaskContainmentHierarchyFacade containment) {
		super(new TaskTreeNode(containment.getRootTask(), containment));
	}
	
	static class TaskTreeNode implements TreeNode {
		private Task myTask;
		private TaskContainmentHierarchyFacade myContainment;
		TaskTreeNode(Task task, TaskContainmentHierarchyFacade containment) {
			myTask = task;
			myContainment = containment;
		}
		public Enumeration children() {
			return new Enumeration() {
				private Task[] myNestedTasks = getNestedTasks();
				private int myIndex = 0;
				public boolean hasMoreElements() {
					return myIndex < myNestedTasks.length;
				}
				public Object nextElement() {
					return new TaskTreeNode(myNestedTasks[myIndex++], myContainment);
				}
			};
		}
		public boolean getAllowsChildren() {
			return true;
		}
		public TreeNode getChildAt(int childIndex) {
			return new TaskTreeNode(getNestedTasks()[childIndex], myContainment);
		}
		public int getChildCount() {
			return getNestedTasks().length;
		}
		private Task[] getNestedTasks() {
			return myContainment.getNestedTasks(myTask);
		}
		public int getIndex(TreeNode node) {
			Task[] nestedTasks = getNestedTasks();
			TaskTreeNode taskNode = (TaskTreeNode) node;
			for (int i=0; i<nestedTasks.length; i++) {
				if (taskNode.myTask == nestedTasks[i]) {
					return i;
				}
			}
			return -1;
		}
		public TreeNode getParent() {
			if (myContainment.getContainer(myTask)!=null) {
				return new TaskTreeNode(myContainment.getContainer(myTask), myContainment);
			}
			return null;
		}
		public boolean isLeaf() {
			return getNestedTasks().length==0;
		}
		public boolean equals(Object o){
			if (o instanceof TaskTreeNode) {
				TaskTreeNode right = (TaskTreeNode) o;
				return this.myTask==right.myTask;
			}
			return false;
		}
		public int hashCode() {
			return myTask.hashCode();
		}
		public String toString() {
			return myTask.getName();
		}
		Task getTask() {
			return myTask;
		}
	}

}
