if(typeof Portal == 'undefined'){
	var Portal = {};
}
/*
 * @description: structor
 * @param selectElement {HTMLSelectElement} select element object
 * @param loaderOptions {Object} options see below example:
 *			loaderOptions = {
 *				url:'xx.php',									//webservice address
 *				method:'GET',									//request method
 *				headers:{'headerName':'headerValue',...},		//request headers
 *				parameters:'a=1&b=2&c=3...',					//additional parameters
 *				onLoading:function(){..},						//on loading callback
 *				onLoadingComplete:function(){...}				//on complete callback
 *			}
 */
Portal.SelectLoader = function(selectElement,loaderOptions){
	this.selectElement = selectElement;
	this.selectElement.loader = this;
	this.loaderOptions = $.extend({
		autoCallSubLoaders:true
	},loaderOptions);
	this.subLoaders = {};
	var __this = this;
	$(selectElement).change(function(){
		__this.callSubLoaders();
	});
	Portal.SelectLoader.instances.push(this);
}
Portal.SelectLoader.instances = [];
Portal.SelectLoader.prototype = {
	/*
	 * @description add sub loader
	 * @params selectLoader {SelectLoader} SelectLoader instance
	 */
	addSubLoader:function(name,selectLoader){
		this.subLoaders[name] = selectLoader;
	},
	/*
	 * @description remove sub loader
	 * @params selectLoader {SelectLoader} SelectLoader instance
	 */	
	removeSubLoader:function(name){
		delete this.subLoaders[name];	
	},
	/*
	 * @description load selection datas, if any sub loader exists, sub loaders will be called also.
	 * @params parentSelectValue {Object} Parent loader's value
	 */
	loadData:function(parentSelectValue){
		var loaderOptions = this.loaderOptions;
		var url = loaderOptions.url;
		var __this = this;
		var params = (loaderOptions.parameters || '') + '&selectname=' + __this.selectElement.name + '&parentselectvalue=' + (parentSelectValue || '') + '&timestamp=' + new Date().getTime();
		if(loaderOptions.onLoading)
		{
			loaderOptions.onLoading(this);	
		}
		$.getJSON(url, params , function(data){
			__this.buildOptions(data, true);
		})
		this.selectElement.disabled = true;
	},
	/*
	 * @description build options
	 * @param data {Object} data object
	 * @param isRebuild {Bool} whether rebuild all options
	 */	
	buildOptions:function(data,isRebuild){
		try
		{
			this.values = {};
			var dataItem;
			var selectElement = this.selectElement;
			if(isRebuild)
			{
				$(selectElement).children().each(function(i,n){
					n.parentNode.removeChild(n);
				})
			}
			for(var i = 0,l = data.length; i < l; i ++)
			{
				dataItem = data[i];
				if(dataItem.optgroup){
					var optg = document.createElement('optgroup');
					optg.label = dataItem.name;
					selectElement.appendChild(optg);
				} else {
					var opt = document.createElement('option');
					opt.value = dataItem.value;
					opt.appendChild(document.createTextNode(dataItem.name));
					if(dataItem.selected){
						opt.selected = true;
					}
					selectElement.appendChild(opt);
					this.values[dataItem.value] = dataItem.name;
				}
			}
			if(this.loaderOptions.onLoadingComplete)
			{
				this.loaderOptions.onLoadingComplete(this);
			}
			if(this.loaderOptions.autoCallSubLoaders)this.callSubLoaders();
			this.selectElement.disabled = false;
		}
		catch(e)
		{
			this.selectElement.disabled = false;
			throw new Error('Failed to build options.');	
		}
		
	},
	/*
	 * @description call sub loaders
	 */		
	callSubLoaders:function(v){
		var subLoaders = this.subLoaders , subLoader , loaderName;
		var value = v || this.selectElement.value;
		for(loaderName in subLoaders)
		{
			subLoader = subLoaders[loaderName];
			subLoader.loadData(value);
		}
	}
}

var CategorySelector = {
	init:false,
	initFlag:0,
	bindEvents:function(isInit){
		var selector = $('.category-extra-row:last select.category-selector')[0];
		selector.selectedIndex = 0;
	},
	addRow:function(obj,manually,options){
		if($('.category-extra-row:last .category-selector:last')[0] !== obj && !manually)return;
		$('.category-extra-row:last').after('<div class="category-extra-row">' + $('.category-extra-row:first').html() + '</div>');
		CategorySelector.bindEvents();
		CategorySelector.bindSelectorLoaders($('.category-extra-row:last select'),options);
	},
	removeRows:function(){
		$('.category-extra-row').each(function(i,row){
			if(i > 0)$(row).remove();
		})
	},
	syncPortals:function(){
		var source = $('.category-base-row .portal-selector');
		$('.category-extra-row:first .portal-selector').each(function(i,selector){
			selector.options.length = 0;
			var option = source[i].options[source[i].selectedIndex];
			selector.options[selector.options.length] = new Option(option.text, option.value);
		})
	},
	onSelectionChanged:function(obj){
		var selector = $('.category-extra-row:last select.category-selector')[0];
		if(obj == selector && obj.value != ''){
			CategorySelector.addRow(obj);
		}
	},
	onBaseSelectionChanged:function(obj){
		if(obj.value == '' || obj.value == 0)return;
		$('.category-extra-row:first select').enable();
		if(CategorySelector.init == false){
			CategorySelector.bindSelectorLoaders($('.category-extra-row:first select'));
			CategorySelector.init = true;
		}
	},
	bindSelectorLoaders:function(selectors, options){
		var loaderOptions = $.extend({
			url:Portal.basePath  + 'ajaxprocess/getcategorydata'
		}, options || {});
		var p1 = new Portal.SelectLoader(selectors[0],loaderOptions);
		var p2 = new Portal.SelectLoader(selectors[1],loaderOptions);
		var c1 = new Portal.SelectLoader(selectors[2],loaderOptions);
		p1.addSubLoader('p2',p2);
		p2.addSubLoader('c1',c1);
		p1.loadData();
	},
	initialize:function(obj,initDatas){
		if(CategorySelector.init)return;
		var setSelectValue = function(s,v){
			try{$(s).val(v);}catch(e){}
		}
		if(obj.selectElement == $('.category-base-row select')[0]){
			//obj.selectElement.value = initDatas[0].portalId;
			setSelectValue(obj.selectElement,initDatas[0].portalId);
			obj.callSubLoaders(initDatas[0].portalId);
		}
		else if(obj.selectElement == $('.category-base-row select')[1]){
			//obj.selectElement.value = initDatas[0].subPortalId;
			setSelectValue(obj.selectElement,initDatas[0].subPortalId);
			obj.callSubLoaders(initDatas[0].subPortalId);
		}
		else if(obj.selectElement == $('.category-base-row select')[2]){
			//obj.selectElement.value = initDatas[0].tid;
			setSelectValue(obj.selectElement,initDatas[0].tid);
			CategorySelector.initFlag ++;
			if(CategorySelector.initFlag == initDatas.length){
				CategorySelector.init = true;
				CategorySelector.bindSelectorLoaders($('.category-extra-row:fitst select'));
			}
			else {
				CategorySelector.bindSelectorLoaders($('.category-extra-row select'), {
					onLoadingComplete:function(obj){
						CategorySelector.initialize(obj,initDatas);
					},
					autoCallSubLoaders:false
				});
			}
		}
		else if(obj.selectElement == $('.category-extra-row:last select')[0]){
			//obj.selectElement.value = initDatas[CategorySelector.initFlag].portalId;
			setSelectValue(obj.selectElement,initDatas[CategorySelector.initFlag].portalId);
			obj.callSubLoaders(initDatas[CategorySelector.initFlag].portalId);
		}
		else if(obj.selectElement == $('.category-extra-row:last select')[1]){
			//obj.selectElement.value = initDatas[CategorySelector.initFlag].subPortalId;
			setSelectValue(obj.selectElement,initDatas[CategorySelector.initFlag].subPortalId);
			obj.callSubLoaders(initDatas[CategorySelector.initFlag].subPortalId);
		}
		else if(obj.selectElement == $('.category-extra-row:last select')[2]){
			//obj.selectElement.value = initDatas[CategorySelector.initFlag].tid;
			setSelectValue(obj.selectElement,initDatas[CategorySelector.initFlag].tid)
			CategorySelector.initFlag ++;
			if(CategorySelector.initFlag == initDatas.length){
				CategorySelector.init = true;
				//Portal.SelectLoader.instances[0].callSubLoaders();
				CategorySelector.addRow(null,true);
				$.each(Portal.SelectLoader.instances,function(i,o){
					o.loaderOptions.autoCallSubLoaders = true;
				});
			}
			else {
				CategorySelector.addRow(null,true,{
					onLoadingComplete:function(obj){
						CategorySelector.initialize(obj,initDatas);
					},
					autoCallSubLoaders:false
				});
			}
		}
	}
}