

/**
 * Create a simple TreeNode oObject
 * @constructor
 * @param {string} name Name of this TreeNode
 * @param {number} value Value of this TreeNode
 */
function TreeNode(id,value , name, url, info, date, imageurl, category, related, color_one, color_two, color_three, time_one, time_two, time_three, hour, minute, day, month, year, showrelated, showbookmark)
{
	if( TreeNode.arguments.length === 0 ) return; // NB: this is a base class constructor .. sometimes
	this.name = name;
	this.id = id;
	this.url = url;
	this.imageurl = imageurl;
	this.info = info;
	this.value = value;
	this.date = date;
	this.category = category;
	this.related = related;
	this.color_one = color_one;
	this.color_two = color_two;
	this.color_three = color_three;
	this.time_one = time_one;
	this.time_two = time_two;
	this.time_three = time_three;
	this.showrelated = showrelated;
	this.showbookmark = showbookmark;
	this.hour = hour;
	this.minute = minute;
	this.day = day;
	this.month = month;
	this.year = year;
	this.parent = null;
}


/**
 * Get the value of this node
 * A simple value accessor .. something TreeParentNode can overload
 * @return {number} the value of this node
 */
TreeNode.prototype.getValue = function()
{
	return this.value;
};

TreeNode.prototype.getRelated = function() {
	return this.related;
}

TreeNode.prototype.getInfo = function () {
	return this.info;
}

TreeNode.prototype.getCategory = function () {
	return this.category;
};

TreeNode.prototype.getId = function () {
	return this.id;
}
TreeNode.prototype.getImageurl = function () {
	return this.imageurl;
}

TreeNode.prototype.getUrl = function () {
	return this.url;
}

TreeNode.prototype.getDate = function () {
	return this.date;
}

TreeNode.prototype.colorOne = function() {
	return this.color_one;
}

TreeNode.prototype.colorTwo = function() {
	return this.color_two;
}

TreeNode.prototype.colorThree = function() {
	return this.color_three;
}

TreeNode.prototype.timeOne = function () {
	return this.time_one;
}

TreeNode.prototype.timeTwo = function () {
	return this.time_two;
}

TreeNode.prototype.timeThree = function () {
	return this.time_three;
}

TreeNode.prototype.showRelated = function () {
	return this.showrelated;
}

TreeNode.prototype.showBookmark = function () {
	return this.showbookmark;
}

TreeNode.prototype.hour = function() {
	return this.hour;
}

TreeNode.prototype.minute = function() {
	return this.minute;
}

TreeNode.prototype.day = function() {
	return this.day;
}

TreeNode.prototype.month = function() {
	return this.month;
}

TreeNode.prototype.year = function() {
	return this.year;
}
/**
 * Fetch a string representation for this object
 * @return {String} the fully qualified name of this node
 */
TreeNode.prototype.toString = function()
{
	return this.getFqName() + "=" + this.value;
};

/**
 * Get the name of this node, preceded by the name of all parent nodes
 * @return {string} fully qualified node name
 */
TreeNode.prototype.getFqName= function()
{
	if( this.parent === null )
		return this.name;
	else
		return this.parent.getFqName() + "/" + this.name;
};

// ============================================================================

// The TreeParentNode class

/**
 * Construct a TreeParentNode object
 * this inherits from the TreeNode class
 * @constructor
 * @param {string} name Name of this TreeNode
 * @param children Array of TreeNode objects to contain
 */
function TreeParentNode( name, children )
{
	TreeNode.call( this, name, -1 );

	// Some additional state
	this.children = new Array();
	
	// Parent the children & weed out cuckoos (cause by trailing commas in IE - bah)
	for( var i=0; i< children.length; i++ )
	{
		if( children[i] instanceof TreeNode )
		{
			children[i].parent = this;
			this.children.push( children[i] );
		}
	}
}

// Inherits from TreeNode class
TreeParentNode.prototype = new TreeNode();

/**
 * Get the value of this object, from a cache if possible
 * Otherwise recursively calculate it
 * @retun {number} the value of this object
 */
TreeParentNode.prototype.getValue = function()
{
	var result = 0;
	if( this.value < 0 ) // Check for cached values
	{
		for( var i=0; i< this.children.length; i++ )
			result += this.children[i].getValue();
		this.value = result;
	}
	return this.value;
};

/**
 * How deep does this rabbit warren go?
 * @return {number} number of levels this data model has
 */
TreeParentNode.prototype.countDepth = function()
{
	
	if( this.children.length === 0 ) return 0;
	
	var childDepth = 0;
	for( var i=0; i<this.children.length; i++ )
	{
		if( this.children[i] instanceof TreeParentNode )
		{
			childDepth = Math.max( childDepth, this.children[i].countDepth() );
		}
	}			
	return 1 + childDepth;
	
};
