///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register app namespace
YAHOO.namespace('app', 'app.Core');

/**
* @class 
* App class contains all application JS methods and properties
* @param none
* @constructor
*/
YAHOO.app.Core = function() {
	this.init();
};

YAHOO.app.Core.prototype = {
	version: '1.0.0',
	/**
	* Validate settings and initializes the App object 
    * @param none
	*/
	init: function() {
		// Make some verifications e.g. YUI, Prototipe library versions, etc

		if((typeof Prototype=='undefined') || 
		parseFloat(Prototype.Version.split(".")[0] + "." +
					Prototype.Version.split(".")[1]) < 1.4)
		throw("YAHOO.App requires the Prototype JavaScript framework >= 1.4.0");
	},


	/**
	* Set errors
    * @param {array}	errors	array of Error objects
	*/
	setErrors: function(errors, separator) {
		if(typeof separator == 'undefined') 
			separator = "<br />"

		var el = null;
		// Loop through errors
		for(var i=0; i<errors.length; i++)	{
			try	{
				el = YAHOO.util.Dom.get(errors[i].Element + '_Error');
				if (el == null) {					
					var parent = YAHOO.util.Dom.get(errors[i].Element).parentNode;
					//alert(parent);
					el = document.createElement('span');
					el.id = parent.id;
					YAHOO.util.Dom.addClass(el, 'error');
					parent.appendChild(el);
				}
				el.innerHTML = el.innerHTML + "<br />" + errors[i].Message;
				// Make error element visible
				Element.show(el);
			}
			catch(e){
				// output error using JS alert
				alert(errors[i].Message);
			}
		}

	},

	/**
	* Print window 
    * @param none
	*/
	printWindow: function() {
	 	window.print();
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// BreadCrumb, BreadCrumb.Selector, BreadCrumb.Selector.Element
YAHOO.namespace('app', 'app.BreadCrumb', 'app.BreadCrumb.Selector', 'app.BreadCrumb.Selector.Element');

YAHOO.app.BreadCrumb = {}

YAHOO.app.BreadCrumb.Selector = function(elements, tree, selected) {
       this.init(elements, tree, selected);    
};
//function test() {alert("test");} // just for test
YAHOO.app.BreadCrumb.Selector.prototype = {

	elements: [],
	opt: [],
	arr: [],
	selectedValues: [],	
	onBreadCrumbChange: null,
	fnBreadCrumbChange: null,
	/**
	* initializes Breadcrumb.Selector and add events listeners
	* @param DESCRIBE
	*/
	init: function(elements, tree, selected) {
		// Parse input elements
		var el = null;
		for (var i = 0, len = elements.length; i < len; ++i) {
			el = document.getElementById(elements[i].el);
			this.elements.push(el);
			this.opt.push(elements[i].opt);
			// Process some conf options
			if (elements[i].opt && elements[i].opt.multiple)
			{
				/* 
				* IE 6.0.29 workaround - further options selection (initial selections) doesn't
				* work if we set multiple from JS. We have to set "multiple" from HTML
				* el.multiple = elements[i].opt.multiple;
				*/
			}
		}

		// Parse data tree
		for (var i = 0, len = tree.length; i < len; ++i) {
			this.arr.push(new YAHOO.app.BreadCrumb.Selector.Element(tree[i][0], tree[i][1], tree[i][2], tree[i][3]))
		}

		this.selectedValues = selected;
	},

	// Add events to a elements
	render: function() {
        var oSelf = this;

		for (var i = 0, len = this.elements.length; i < len; ++i) {
			this.elements[i].level = i;
			YAHOO.util.Event.addListener(this.elements[i], "change", oSelf.loadElements, oSelf);
		}

		// Load first level elements
		var ptype = null;
		for (var i = 0; i < this.arr.length; ++i){
			ptype = this.arr[i];
			if (ptype.ParentID != 0) continue;
			this.elements[0].options[this.elements[0].options.length] = new Option(ptype.Value, ptype.ID);
		}

		// Make initial selections
		this.reset();
	},

	reset: function() {
		// Make initial selections
		for (var i = 0, len = this.elements.length; i < len; ++i) {
			Source = this.elements[i];
			for (var j = 0, optLen = Source.options.length; j < optLen; ++j){
				for (var n = 0, selLen = this.selectedValues.length; n < selLen; ++n){
				 	if (this.selectedValues[n] == Source.options[j].value)
				 	{
						Source.options[j].selected = true;
					}
				}
			}

			// Load entries for a selected option(s)
			this.fnBreadCrumbChange(Source);
		}
	},


	// Method which handles BreadCrumbChange change
	fnBreadCrumbChange: function(Source) {

		//Current level
		Level = Source.level;

		// Next elemenent in a sequence
		var NextElement = this.elements[Level + 1];

		if (!NextElement) return;
		
		// Remove options from all next elements in a sequence
		for (var i = (Level + 1), len = this.elements.length; i < len; ++i) {
			if (this.elements[i]) this.elements[i].options.length = 0;
		}

		// Array of values of selected options
		var selectedOptions = new Array();
		if (Source){
			for (var i = 0; i < Source.options.length; ++i){
				if (Source.options[i].value != "0" && Source.options[i].selected) {
					selectedOptions.push(Source.options[i].value);
				}
			} 
		}
		
		if (Source && !selectedOptions.length) return;

		// Check if we should display "All" option
		if (this.opt[Level + 1] && this.opt[Level + 1].allOption)
		{
			if (Source && Level && NextElement && (!NextElement.options.length || NextElement.options[0].value != 'All')){
				NextElement.options[NextElement.options.length] = new Option('All', 'All');        
			}else if (!Source && !NextElement.options.length){
				NextElement.options[0] = new Option('All', '0');  
			}
		}

		for (var i = 0; i < this.arr.length; ++i){
			var ptype = this.arr[i];
			if (!Source && !ptype.ParentID){
				NextElement.options[NextElement.options.length] = new Option(ptype.Value, ptype.ID);
			}
			else{
				for (var j = 0; j < selectedOptions.length; ++j){
					if (ptype.ParentID == selectedOptions[j]){
						var v = (selectedOptions.length > 1) ? ptype.Value + ' ' + ptype.Parents:ptype.Value;
						NextElement.options[NextElement.options.length] = new Option(v, ptype.ID);
					}
				}     
			}
		}

		/* Deprecated
		if (Source && Level && NextElement && NextElement.options.length == 1){
			NextElement.length = 0;
		}
		*/
	},


	// Serialize BreadCrumb.Selector. Return serialized string e.g. sel1[]=1&sel2[]=216&sel3[]=217&sel3[]=218&sel3[]=219
	serialize: function() {
		var Source = null;
		var selArr = [];
		for (var i = 0, len = this.elements.length; i < len; ++i) {
			Source = this.elements[i];
			var selOptions = [];
			for (var j = 0, optLen = Source.options.length; j < optLen; ++j){
				if (Source.options[j].value != "0" && Source.options[j].selected) {
					selOptions.push(Source.id + "[]=" +Source.options[j].value);
				}
			} 
			selArr.push(selOptions.join('&'));
		}
		return selArr.join('&'); 
		
	},


	/*
	* Handles 'select' change events that and load new elements.
	*
	* @param {event} v The change event
	* @param {object} oSelf The YAHOO.app.BreadCrumb.Selector instance
	* @private
	*/
	loadElements: function(ev, oSelf){
		// Get event element
		var Source = YAHOO.util.Event.getTarget(ev);

		//fire the custom event
		oSelf.fnBreadCrumbChange(Source);
	}
}

//445, 'Townhouse (Row)', 14, '(Multi-Tenant)');
YAHOO.app.BreadCrumb.Selector.Element = function(id, desc, parent_id, parents) {
       this.init(id, desc, parent_id, parents);    
};

YAHOO.app.BreadCrumb.Selector.Element.prototype = {

	ID: null, 
	Value: null,
	ParentID: null,
	Parents: null,

	/**
	* initializes Breadcrumb.Selector and add events listeners
	* @param DESCRIBE
	*/
	init: function(id, desc, parent_id, parents) {

		this.ID = id;
		this.Value = desc;
		this.ParentID = parent_id;
		this.Parents = parents; 
	}

}


//////////////////////////////////////////////////////////////////////////////////////////////////////
// Custom subclass
YAHOO.app.CustomApp = function(){}

// Inherit from YAHOO.widget.App
YAHOO.extend(YAHOO.app.CustomApp, YAHOO.app.Core);

YAHOO.app.CustomApp.prototype.test = function(){
	alert("test");
} 

// Instantiate application class 
var myApp = new YAHOO.app.CustomApp();
//App.test();
