OptionDependent = Class.create();
OptionDependent.prototype = {
	oIds : [],
	oldV : [],	
	oldO : [],
	childrenVals : [],
	indByValue : [],
	valsByOption : [],
	optionByValue : [],
	univValsByOption : [],
	childOIdsByO : [],
	previousIds : [],
	childrenByOption : [],	
	initialize : function(config){
		this.config = config;	
		this.load();	
		var l = this.oIds.length;	
		for (var i=0;i<l;i++){
			var ll = this.valsByOption[this.oIds[i]].length;
			while (ll--){
				if (this.childrenVals.indexOf(this.valsByOption[this.oIds[i]][ll]) == -1){
					if (!this.univValsByOption[this.oIds[i]])
						this.univValsByOption[this.oIds[i]] = [];
					this.univValsByOption[this.oIds[i]].push(this.valsByOption[this.oIds[i]][ll]);
				}
			}
			var ids = this.getChildrenOptionIds(this.oIds[i]);
			if (ids.length > 0)
					this.childOIdsByO[this.oIds[i]] = ids;			
		}
		while (l--)	
			if (this.childOIdsByO[this.oIds[l]])
				this.reloadOptions(this.oIds[l], [], []);		
	},	
	load : function(){
		var c = 0;
		$$('.product-custom-option').each(function(element){
			 var optionId = 0;
			 element.name.sub(/[0-9]+/, function(match){
				  optionId = parseInt(match[0]);
			 });
			 
			 if (!this.oldO[optionId]){
				this.oldO[optionId] = {};
				this.oldO[optionId].visible = true; 
				this.valsByOption[optionId] = [];
				this.oIds.push(optionId);
				var c = 0;				
			}

			 if (element.type == 'radio' || element.type == 'checkbox') {	
			 
				if (c == 0) 
					this.oldO[optionId].firstelement = element;
					
				if (element.value != ''){
					var valueId = parseInt(element.value);					
					this.indByValue[valueId] = c;
					if (this.config[valueId]){
						if (this.config[valueId][0].length > 0){						
							if (!this.childOIdsByO[optionId])
								this.childOIdsByO[optionId] = [];
							this.childOIdsByO[optionId] = this.childOIdsByO[optionId].concat(this.config[valueId][0]);							
						}	
						if (this.config[valueId][1]){							
							this.childrenVals = this.childrenVals.concat(this.config[valueId][1]);								
							if (!this.childrenByOption[optionId])
								this.childrenByOption[optionId] = [];
							this.childrenByOption[optionId] = this.childrenByOption[optionId].concat(this.config[valueId][1]);
						}
					}	
					this.valsByOption[optionId].push(valueId);
					this.optionByValue[valueId] = optionId;
					this.oldV[valueId] = {};					
					this.oldV[valueId].element = element;
					this.oldV[valueId].visible= true;
				}
				
				if (element.type == 'radio'){
					element.observe('click', this.reloadChildrenTypeRadio.bind(this, optionId, element.value));		
				} else {
					element.observe('click', this.reloadChildrenTypeCheckbox.bind(this, optionId));	
				}	
			} else if(element.hasClassName('datetime-picker')) {
				if (!this.oldO[optionId].element)
					this.oldO[optionId].element = element;		
			} else if(element.type == 'select-one' || element.type == 'select-multiple') {	
			
				this.oldO[optionId].element = element;
				var options = $A(element.options);
				for (var i = 0, len = options.length; i < len; ++i){
					if (options[i].value != ''){
						var valueId = parseInt(options[i].value);						
						this.indByValue[valueId] = i;
						if (this.config[valueId]){
							if (this.config[valueId][0].length > 0){						
								if (!this.childOIdsByO[optionId])
									this.childOIdsByO[optionId] = [];
								this.childOIdsByO[optionId] = this.childOIdsByO[optionId].concat(this.config[valueId][0]);							
							}
							if (this.config[valueId][1]){							
								this.childrenVals = this.childrenVals.concat(this.config[valueId][1]);								
								if (!this.childrenByOption[optionId])
									this.childrenByOption[optionId] = [];
								this.childrenByOption[optionId] = this.childrenByOption[optionId].concat(this.config[valueId][1]);
							}
						}
						this.valsByOption[optionId].push(valueId);
						this.optionByValue[valueId] = optionId;						
						this.oldV[valueId] = {};
						this.oldV[valueId].visible = true;
						this.oldV[valueId].name = options[i].text;						
					}	
				}
				
				if	(element.type == 'select-one'){
					element.observe('change', this.reloadChildrenTypeSelectOne.bind(this, element, optionId));
				} else {
					element.observe('change', this.reloadChildrenTypeSelectMultiple.bind(this, element, optionId));					
				}
				
			} else {	
				this.oldO[optionId].element = element;			
			}
			
			c++;
		}.bind(this));
	},
	getChildrenOptionIds : function(id){
		if (this.previousIds[id])
			return [];
		this.previousIds[id] = true;
		if (!this.childrenByOption[id] && !this.childOIdsByO[id])
			return [];		
		var optionIds = [];
		if (this.childOIdsByO[id]){
			this.childOIdsByO[id] = this.uniq(this.childOIdsByO[id]);
			optionIds = optionIds.concat(this.childOIdsByO[id]);
		}
		if (this.childrenByOption[id]){		
			var ids = this.uniq(this.childrenByOption[id]);		
			var l = ids.length;
			while (l--)
				if (optionIds.indexOf(this.optionByValue[ids[l]]) == -1)
					optionIds.push(this.optionByValue[ids[l]]);
		}
		var l = optionIds.length;
		while (l--){
			var ids = this.getChildrenOptionIds(optionIds[l]);
			if (ids.length > 0){
					this.childOIdsByO[optionIds[l]] = ids;
					optionIds = optionIds.concat(ids);
			}		
		}
		return optionIds;		
	},	
	showOption : function(id, element){
		if (!this.oldO[id].visible){
		  var dd = element.up('dd');
		  dd.show();
		  dd.previous().show();
		  this.oldO[id].visible = true;
		}  
	},
	hideOption : function(id){
		if (this.oldO[id].visible){
		  var element = this.oldO[id].element ? this.oldO[id].element : this.oldO[id].firstelement;
			if (element.hasClassName('datetime-picker')){
				element.selectedIndex = 0; 
			} else if (element.type == 'text' || element.type == 'textarea') {
				element.value = '';
			}	
		  var dd = element.up('dd');
		  dd.hide();
		  dd.previous().hide();
		  this.oldO[id].visible = false;
		}  
	},
	showValue : function(id, valueId, element){
	  if (element){			  
			element.up('li').show();	
			this.showOption(id, element);				
		} else {
			var ind = this.oldO[id].element.options.length;
			this.oldO[id].element.options[ind] = new Option(this.oldV[valueId].name, valueId);
			this.indByValue[valueId] = ind;
			this.showOption(id, this.oldO[id].element);				
		}	
		this.oldV[valueId].visible = true;
	},
	resetValue : function(id, valueId, element){
	  if (element){
		   if (element.checked)	  
				element.checked = false;
		} else {
			var ind = this.indByValue[valueId];
			if (this.oldO[id].element.options[ind].selected){
				if (this.oldO[id].element.type == 'select-one')
					this.oldO[id].element.selectedIndex = 0;
				else 
					this.oldO[id].element.options[ind].selected = false;
			}
		}	
	},
	hideValue : function(id, valueId, element){
		
	  this.resetValue(id, valueId, element);
	  
	  if (element){		  
			element.up('li').hide();			
		} else {
			var ind = this.indByValue[valueId];		
			this.oldO[id].element.options[ind] = null;
			this.indByValue[valueId] = null;
		}	
		
		this.oldV[valueId].visible = false;
	},		
	reloadValues : function(id, ids){
		var element = null;
		var hasHidden = false;
		var l = this.valsByOption[id].length;
		for (var i=0;i<l;i++){ 			
			if (ids.indexOf(this.valsByOption[id][i]) != -1){
				if (this.oldV[this.valsByOption[id][i]].element)
					element = this.oldV[this.valsByOption[id][i]].element;				
				if (!this.oldV[this.valsByOption[id][i]].visible)
					this.showValue(id, this.valsByOption[id][i], element);
				else 
					this.resetValue(id, this.valsByOption[id][i], element);
			}
		}
		while (l--){ 
			if (ids.indexOf(this.valsByOption[id][l]) == -1 && this.oldV[this.valsByOption[id][l]].visible){			
				if (this.oldV[this.valsByOption[id][l]].element)
					element = this.oldV[this.valsByOption[id][l]].element;						
				this.hideValue(id, this.valsByOption[id][l], element);
				hasHidden = true;
			}		
		}
		if (!element && hasHidden){
			l = this.oldO[id].element.options.length;
			for (i=0;i<l;i++)
				this.indByValue[this.oldO[id].element.options[i].value] = i;
		}	
	},
	reloadOptions : function(id, optionIds, valueIds){
		var a = [];
		var l = valueIds.length;
		while (l--){
			if (!a[this.optionByValue[valueIds[l]]])
				a[this.optionByValue[valueIds[l]]] = [];				
			a[this.optionByValue[valueIds[l]]].push(valueIds[l]);
		}

		l = this.childOIdsByO[id].length;
		while (l--){
			if (a[this.childOIdsByO[id][l]]){
				if (this.univValsByOption[this.childOIdsByO[id][l]])
					a[this.childOIdsByO[id][l]] =	a[this.childOIdsByO[id][l]].concat(this.univValsByOption[this.childOIdsByO[id][l]]);					
				this.reloadValues(this.childOIdsByO[id][l], a[this.childOIdsByO[id][l]]);					
			} else if(this.univValsByOption[this.childOIdsByO[id][l]]) {			
				this.reloadValues(this.childOIdsByO[id][l], this.univValsByOption[this.childOIdsByO[id][l]]);
			} else if (optionIds.indexOf(this.childOIdsByO[id][l]) != -1){
				this.showOption(this.childOIdsByO[id][l], this.oldO[this.childOIdsByO[id][l]].element);					
			} else {
				this.reloadValues(this.childOIdsByO[id][l], []);		
				this.hideOption(this.childOIdsByO[id][l]);					
			}	
		}	
	}, 
	reloadChildrenTypeRadio : function(optionId, valueId){
		if (this.childOIdsByO[optionId]){		
			 if (!this.config[valueId]){
				this.reloadOptions(optionId, [], []);
			} else {	
				this.reloadOptions(optionId, this.config[valueId][0], this.config[valueId][1]);	
			}
			opConfig.reloadPrice();
		}
	},
	reloadChildrenTypeCheckbox : function(optionId){
		if (this.childOIdsByO[optionId]){		
			var optionIds = [];
			var valueIds = [];		
			var l = this.valsByOption[optionId].length;
			while (l--){	
				if (this.oldV[this.valsByOption[optionId][l]].element.checked && this.config[this.valsByOption[optionId][l]]){
					if (this.config[this.valsByOption[optionId][l]][0].length > 0)				
						optionIds = optionIds.concat(this.config[this.valsByOption[optionId][l]][0]);	
					if (this.config[this.valsByOption[optionId][l]][1].length > 0)
						valueIds = valueIds.concat(this.config[this.valsByOption[optionId][l]][1]);												
				}
			}				
			this.reloadOptions(optionId, this.uniq(optionIds), this.uniq(valueIds));
			opConfig.reloadPrice();
		}
	},
	reloadChildrenTypeSelectOne : function(element, optionId){
		var valueId = element.value;  		
		if (this.childOIdsByO[optionId]){		
			if (valueId == '' || !this.config[valueId]){
				this.reloadOptions(optionId, [], []);
			} else {	
				this.reloadOptions(optionId, this.config[valueId][0], this.config[valueId][1]);	
			}
			opConfig.reloadPrice();
		}
	},
	reloadChildrenTypeSelectMultiple : function(element, optionId){
		if (this.childOIdsByO[optionId]){
			var options = $A(element.options);
			var optionIds = [];
			var valueIds = [];			
			var l = options.length;
			while (l--){																			
				if (options[l].selected && this.config[options[l].value]){
					if (this.config[options[l].value][0].length > 0)				
						optionIds = optionIds.concat(this.config[options[l].value][0]);	
					if (this.config[options[l].value][1].length > 0)
						valueIds = valueIds.concat(this.config[options[l].value][1]);											
				}		
			}		
			this.reloadOptions(optionId, this.uniq(optionIds), this.uniq(valueIds));
			opConfig.reloadPrice();
		}
	},	
	uniq : function(a){
		var l=a.length,b=[],c=[];
		while (l--)
			if (c[a[l]] == undefined) b[b.length] = c[a[l]] = a[l];
		return b;
	}  
}
