package com.tandbergtv.metadatamanager.model;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents a node in the Field Tree
 * 
 * @author vgoyal
 * 
 */
public class FieldTreeNode {
	private String name;
	private Integer currentIndex;
	private Field field;
	private List<FieldTreeNode> children;
	private boolean isAttribute;

	/**
	 * constructor
	 */
	public FieldTreeNode() {
		field = null;
		currentIndex = 0;
		isAttribute = false;
		children = new ArrayList<FieldTreeNode>();
	}

	/**
	 * 
	 * @return name
	 */
	public String getName() {
		return name;
	}

	/**
	 * 
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 
	 * @return field
	 */
	public Field getField() {
		return field;
	}

	/**
	 * 
	 * @param field
	 */
	public void setField(Field field) {
		this.field = field;
	}

	/**
	 * creates a blank arraylist of fieldtreenode's if none exists
	 * 
	 * @return
	 */
	public List<FieldTreeNode> getChildren() {
		if (this.children == null) {
			return new ArrayList<FieldTreeNode>();
		}
		return children;
	}

	/**
	 * 
	 * @param children
	 */
	public void setChildren(List<FieldTreeNode> children) {
		this.children = children;
	}

	/**
	 * 
	 * @return
	 */
	public Integer getCurrentIndex() {
		return currentIndex;
	}

	/**
	 * 
	 * @param currentIndex
	 */
	public void setCurrentIndex(Integer currentIndex) {
		this.currentIndex = currentIndex;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isAttribute() {
		return isAttribute;
	}

	/**
	 * 
	 * @param isAttribute
	 */
	public void setAttribute(boolean isAttribute) {
		this.isAttribute = isAttribute;
	}

	/**
	 * adds a child to the node
	 * 
	 * @param child
	 */
	public void addChild(FieldTreeNode child) {
		if (children == null) {
			children = new ArrayList<FieldTreeNode>();
		}
		children.add(child);
	}

	/**
	 * returns true if it has a valid field object. Only leaf level nodes have
	 * non null field objects
	 * 
	 * @return
	 */
	public boolean isLeafNode() {
		if (field != null) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * gets the child that matches the name and index. if none is found returns
	 * null
	 * 
	 * @param name
	 * @param index
	 * @return
	 */
	public FieldTreeNode getNode(String name, Integer index) {
		for (FieldTreeNode node : children) {
			if (node.getName().equals(name)
					&& node.getCurrentIndex().equals(index)) {
				return node;
			}
		}
		return null;
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("\n").append("{").append(getName().toString()).append("(")
				.append(getCurrentIndex().toString()).append(")").append(",[");
		int i = 0;
		for (FieldTreeNode e : getChildren()) {
			if (i > 0) {
				sb.append(",");
			}
			sb.append(e.getName().toString());
			i++;
		}
		sb.append("]").append("}");
		return sb.toString();
	}
	
	@Override
	public boolean equals(Object o) {
		if(o instanceof FieldTreeNode) {
			FieldTreeNode f = (FieldTreeNode) o;
			//check to make sure the field is the same
			if ((this.field != null || f.field != null) && 
					!this.field.equals(f.field)) {
				return false;
			}
			
			// check to make sure that have the same number of children
			if(this.children.size() != f.children.size()) {
				return false;
			}
			
			// check to make sure their children are equal
			for(int i = 0; i < this.children.size(); i ++) {
				if(!this.children.get(i).equals(f.children.get(i)))
					return false;
			}
			
			return true;
				
		}
		
		//if o isn't a FieldTreeNode return false.
		return false;
	}
}
