var Site = new Class({
	
	initialize: function () {
		this.product = {
			'basePrice': 0,
			'baseCode': '',
			'currentPrice': 0,
			'options': [],
			'imageURL': 'http://dummyimage.com/200x300/ccc/fff',
			'url': '/configurator/'
		};
		this.helpers=new Helpers();
	    this.workingPrice=new Array();
        this.workingCode=new Array();
        this.newCode=new Array();
        
        // if the productcode is populated into the hidden field
		if ($('product')) {
			
			// foreach of the radio buttons
			$('product').getElements('input').each(function (e) { 
				
				// add an event 
				
				// if element is primary use, onclick (ie-bug)
				if(e.get('name')=='primaryOption') {
					var ev='click';
				}
				else {
					var ev='change';
				}
				e.addEvent(ev,
				function (e) {
					// clear configurator
					this.clearConfigurator();
					this.getProductOptions($(e.target), 'product');
				}.bind(this));
				
			}.bind(this));
		}
		this.setupProduct();
		this.setupBanners();
		this.additionPrice();
	},
	
	clearConfigurator: function(){
		$('product').getElements('select').each(function (el) { el.dispose(); });
		$('product').getElements('input[type=checkbox]').each(function (el) { el.dispose(); });
		$('productDescription').getElements('div.option').each(function (el) { el.dispose(); });
	},
	
	setupBanners: function () {
		if ($('ngg-gallery')) {
			this.helpers.animateElement('ngg-gallery', 'fade', 'bottom').start();
		}
	},
	
	setupProduct: function () {
		if (!$('price')) {
			return;
		}
	},
	
	additionPrice: function () {
		//alert($$('.productAddition').length);
		$$('.productAddition').each(function (el) {
			el.addEvent('change', function (e) {
				var currentPrice = parseFloat($('currentPrice').get('value'));
				var elem = $(e.target);
				var price = eval(elem.get('name'));
				if (elem.get('checked')) {
					this.workingPrice[elem.name] = price;
				}
				else {
					this.workingPrice[elem.name] = parseFloat(0);
				}
				var response = {
					'name': '',
					'price': 0,
					'code': '',
					'image': ''
				};
	           
				this.update(response, null, 'product');
			}.bind(this));
		}.bind(this));
	},
	
	remove: function(el, force) {
		// for each option within the select
		var options = el.getElements('option');
		for(var i=0; i<options.length; i++) {
			
			//if it's not the selected index and an index is selected...
			
			if((i!=el.selectedIndex || force)) {
				// and there is an existing description for the option
				if($('productDescription').getElement('div[class*=additionaloption'+options[i].value+']')) {
					// ... delete it.
					$('productDescription').getElements('div[class*=additionaloption'+options[i].value+']').dispose();
				}
				
				// existing product option additions
				if($('additionalTitle'))
				{
					$('additionalTitle').getElements('input[name*='+options[i].value+']').each(function (el) {
						var str=String(8)+String(el.get('value'));
						this.workingPrice[str]=parseFloat(0);
						this.updatePrice();
						el.getParent().dispose();
						
					}.bind(this));
				}
				
				// existing product option options
				if($('product').getElement('select[name*='+options[i].value+']'))
				{
					$('product').getElements('select[name*='+options[i].value+']').each(function (el) {
						var childName=this.remove(el,true);
						el.dispose();
					}.bind(this));
				}
				
			}
			else {
				var name=options[i].value;
			}
		}
		return name;
	},
	
	getProductOptions: function(element, pType) {	
		// if the element being clicked already has "option options" or "option additions" displayed...
		if($('product').getElement('select[name='+element.name+']'))
			{	           
				var removeChildren = function(){
					
					var el = $('product').getElement('select[name='+element.name+']');
		
                    var childName=this.remove(el,true);
              
				}.bind(this);

			}
		
		// if the products value has been set
		if (element.value != 0) {
			// show loading graphic
			$('loader').style.display="block";
			
			// request data (product options) for this product
			var requestObject = new Request.JSON ({
				url: this.product.url+pType+'/'+element.value,
				async : false,
				encoding : 'utf-8',
				onComplete: function () {
					$('loader').style.display="none";
				},
				onSuccess : function(responseJSON, responseText) {
					// if successful, process the data
					this.process('product', responseJSON, pType, element);
				}.bind(this),
				onFailure : function() {}
			});
			
			requestObject.post({
				"requestType" : "getOption",
				"option" : element.value
			});
		}
		else {
			// if the product has no value, set defaults
			var response = {
				'name': '',
				'price': 0,
				'code': '',
				'image': ''
			};
            
			this.workingPrice[element.name]=parseFloat(0);
           
			this.update(response, null, pType);
		}
		
		// first time through, force the change event
		if(pType=='product')
			{
				$('product').getElements('select').each(function(el){
					el.fireEvent('change', {target: el});
				}.bind(this));
			}
	},
    
    calculatePrice: function (){
        var total=0;
        
        for(var x in this.workingPrice) {
            if($type(this.workingPrice[x])=='number') {
                total+=parseFloat(this.workingPrice[x]);
            }
        }
        
        return total;
    },
    
    getProductCode: function (){
        var code=this.product.baseCode;
        if(this.newCode.length > 0)
        	{
        		var code=new Array();
	        	 for(var x in this.newCode) {
	                 if(this.newCode[x]!='*')
	                	 {
	                	 	code[x]=this.newCode[x];
	                	 }
	                 else if(this.workingCode[x]!='*')
                 		{
	                	 	code[x]=this.workingCode[x];
	                	 }
	                 else
	                 	{
	                	 	code[x]=this.product.baseCode[x];
	                	 }
	             }
        	}
        
        return code;
    },
	
	process: function (element, responseJSON, pType, parent) {
    	
    	// if it is the base product, add the big image on the left
    	if(pType=='product' && responseJSON.image){
			$('image').getElement('img').setProperties({
			    src: responseJSON.image,
			    alt: responseJSON.title
			});
    	}
    	
		var parentElement=parent;
		parent=parent.name;
		if (!responseJSON || responseJSON == 'undefined') {
			return false;
		}
		
		var element = $('product');
        // create a select box for each option  
		
		if (pType == 'product' && responseJSON.price) {
			this.product.basePrice = responseJSON.price;
            // convert base code to array of characters
			this.product.baseCode=responseJSON.code.split('');
		}
		else {
			this.newCode = responseJSON.code.split('');
			
			/*if(responseJSON.multiplier!=0) {
				this.workingPrice[parent]=(this.product.basePrice*responseJSON.multiplier)-this.product.basePrice;
			}
			else {*/
				this.workingPrice[parent] = parseFloat(responseJSON.price);
		}
		
		var selectArray = this.createOptionOptions(responseJSON);
		
		var checkArray = this.createOptionAdditions(responseJSON);
		
		this.update(responseJSON, selectArray, null, checkArray);
	},
	
	createOptionOptions: function (responseJSON){
		
		var selectArray=new Array();
		
		if (responseJSON.options.length > 0) {
			var i = 0;
			
			// for each of the menu items
			$each(responseJSON.options, function(menuGroup) {
				
				if(responseJSON.type=='additional') {
					var identifier=responseJSON.optionId+'-'+i;
				}
				else {
					var identifier=i;
				}
				
				// create the select box, add event
				var select = new Element('select', {'name': identifier})
					.addEvent('change', function (e) {
						this.getProductOptions($(e.target), 'option');
					}.bind(this));
				
				// populate select with values
				$each(menuGroup, function(value) {
                    if (value.id != 0) {
						new Element('option', {
							'value': value.id
							}).set('html', value.title)
								.inject(select);
					}
				}.bind(this));
				select.store('response', responseJSON);
				selectArray.push(select);
				i++;
			}.bind(this));
		
		}
		
		return selectArray;
		
	},
	
	addDescription: function(responseJSON,origName){
		if(!responseJSON.name){
			responseJSON.name=responseJSON.id;
			responseJSON.type='additionaloption';
		}
			
		var title= responseJSON.title;
		var desc = new Element('div', {
			'class': 'option '+ responseJSON.type+origName,
			title: title, id:'r'+responseJSON.name
		}).set('html', '<div class="rightText">'+responseJSON.description+'</div>');
		
		if(responseJSON.type!='option'){
			// if the product has an image... else make one
			if(!responseJSON.image) {
				var src =this.product.imageURL+'&text=' + /*currentCode*/ responseJSON.code;
			}
			else {
				var src = responseJSON.image;
			}
			var img = new Element('img',{id:'img'+name,alt: responseJSON.title, width:75,height:75});
			img.src=src;
			img.injectTop(desc);
		}
		
		//new Element('h3').set('html', '<hr/>'+responseJSON.type + ' ' + responseJSON.title).injectTop(desc);
		new Element('h3').set('html', '<hr/>' + ' ' + responseJSON.title).injectTop(desc);
		desc.inject($('productDescription'));
	},
	
	removeAdditionDescription: function(checkbox){
		if($('productDescription').getElements('div#r'+checkbox.value)) {
			// ... delete it.
			$('productDescription').getElement('div#r'+checkbox.value).dispose();
		}
	},
	
	createOptionAdditions: function (responseJSON){
		
		var checkArray=new Array();
		
		if (responseJSON.additions.length > 0) {
			var i = 0;
			
			// for each of the additions
			$each(responseJSON.additions, function(menuGroup) {
				
				if(responseJSON.type=='additional') {
					var identifier=responseJSON.optionId+'-'+i;
				}
				else {
					var identifier=i;
				}
				// create the check box, add event
				var intstr=parseInt("8"+menuGroup.id); // 8 to allow for many options before additions
				var label = new Element('label', {'name': menuGroup.id+'-'+identifier }).set('html', ' '+menuGroup.title);
				var check = new Element('input', {'name': menuGroup.id+'-'+identifier, 'type': 'checkbox', 'value': menuGroup.id, 'class':responseJSON.optionId}).addEvent('click',function(e){
						// add price, if checked
						
						if($(e.target).checked){
							this.workingPrice[intstr] = parseFloat(menuGroup.price);
							this.addDescription($(e.target).retrieve('response'),$(e.target).retrieve('parentId'));
						}
						else{
							this.workingPrice[intstr]=0;
							this.removeAdditionDescription($(e.target));
						}
						this.updatePrice();
				}.bind(this));
				check.injectTop(label)
				
				check.store('response', menuGroup);
				check.store('parentId', responseJSON.optionId);
				
				// if the addition has dependencies, store then in the checkbox
				if(menuGroup.dependency.length>0){
					check.store('dependency',menuGroup.dependency.toString());
				}
				
				checkArray.push(label);
				i++;
			}.bind(this));
		
		}
		
		return checkArray;
		
	},
    
   dump: function(arr,level) {
        var dumped_text = "";
        if(!level) level = 0;
        
        //The padding given at the beginning of the line.
        var level_padding = "";
        for(var j=0;j<level+1;j++) level_padding += "    ";
        
        if(typeof(arr) == 'object') { //Array/Hashes/Objects 
            for(var item in arr) {
                var value = arr[item];
                
                if(typeof(value) == 'object') { //If it is an array,
                    dumped_text += level_padding + "'" + item + "' ...\n";
                    dumped_text += dump(value,level+1);
                } else {
                    dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                }
            }
        } else { //Stings/Chars/Numbers etc.
            dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
        }
        return dumped_text;
    },
    
    /*additional: function () {
    	var additional = $('additional');
    	$('product').getElements('select').each(function (el) {
    		if (el.get('name').substr(0, 5) == 'option') {
    			
    		}
    	});
    },*/
    
    updatePrice: function(){
    	var currentPrice = (parseFloat(this.product.basePrice)+parseFloat(this.calculatePrice())).toFixed(2);
    	$('price').getElements('span')[0].set('html', '&pound;'+currentPrice);
    },
	
	update: function(responseJSON, select, pType, check) {
    	
        this.updatePrice();
        
		this.workingCode = this.getProductCode();
		
		$('productCode').set('value',this.workingCode.join('') );
        
        $('code').getElements('span')[0].set('html', this.workingCode);

		var dispose = false;
		
		var name='';
		
		var disposingParent='';
		// every time there is an update, test every select box
		
		// loop through and delete where needed or update current price and code
		// for each of the select boxes...
		$('product').getElements('select').each(function (el) {
			if (dispose) {
				if(el.get('name').indexOf(disposingParent)!=-1) {
					var childName=this.remove(el,true);
					el.dispose();
				}
				
			} else {
                //if there is response text and response text stored in the select element
				if (responseJSON && el.retrieve('response')) {
					
					var response = el.retrieve('response');
					
					name=this.remove(el,false);
				}
				if (el.get('value') == 0 && responseJSON) {
					//get the min value of this select box
                    /*var options = el.getElements('option');
                    var minValue= options[1].value;*/
                    
                    dispose = true;
                    disposingParent=el.get('name');
				}
			}
		}.bind(this));
		
		//first selection, create option in sidebar
		if (responseJSON != null && responseJSON.type) {
			
			this.addDescription(responseJSON,responseJSON.name);
            
			if(responseJSON.type == 'option') {
				if(responseJSON.shaftLengths!='') {
					if (!$('shaftLength')) {
						var fS = new Element ('fieldset',{'id':'shaftLength', 'class':'newOption'}).set('html','<h4>Please select a shaft length in metres:</h4>');
						fS.inject($('shaftRotor'));
					}
					else {
						$('shaftLength').getElements('label').each(function (el) {
							el.dispose();
						});
					}
	                
	                $each(responseJSON.shaftLengths, function(arr) {
		                var lab = new Element('label', {}).set('html', '<span>'+arr.length+'m</span>');    
		                var rad = new Element('input', {'type':'radio', 'value': arr.length, 'name':'shaftLength' }).injectTop(lab);
		                lab.inject($('shaftLength'));
	                });
				}
				else {
					if($('shaftLength'))
						$('shaftLength').dispose();
				}
				if(responseJSON.rotors!='')
				{
					if (!$('rotor')) {
						var fS = new Element ('fieldset',{'id':'rotor', 'class':'newOption'}).set('html','<h4>Please select a rotor (n.0 = nozzle diameter in mm):</h4>');
		                fS.inject($('shaftRotor'));
					}
					else {
						$('rotor').getElements('label').each(function (el) {
							el.dispose();
						});
					}
	                $each(responseJSON.rotors, function(arr) {
		                var lab = new Element('label', {}).set('html', '<span>'+arr.rotor+'</span>');    
		                var rad = new Element('input', {'type':'radio', 'value': arr.rotor, 'name':'rotor' }).injectTop(lab);
		                lab.inject($('rotor'));
	                });
				}
				else {
					if($('rotor'))
						$('rotor').dispose();
				}
			}
		}
		
		this.insertElements(select,responseJSON,'option');
		this.insertElements(check,responseJSON,'addition');
		this.checkDependencies();
		
		// ditch titles, if there is no content
		if($('optionTitle').getElements('select').length==0) {
			$('optionTitle').dispose();
		}
		if($('additionalTitle') && $('additionalTitle').getElements('input').length==0) {
			$('additionalTitle').dispose();
		}
	},
	
	checkDependencies: function(){
		
		// for each checkbox...
		if($('additionalTitle')){
			$('additionalTitle').getElements('input').each(function(el){
				var keep=false;
				
				// if it has dependencies...
				if(el.retrieve('dependency')){
					var dependencyCodes=el.retrieve('dependency').split(',');
					
					// for each dependency...
					for(var x in dependencyCodes){
						if(typeof dependencyCodes[x]=='string')
							
							// test to see if it matches the current code.
							keep=this.testCode(dependencyCodes[x]);
							
							// if it does, break the loop and leave intact...
							if(keep===true)
								{
									break;
								}
					}
					
					// if it gets to the end without finding a match, ditch it.
					if(keep===false){
						// if the element is checked, fire the click event to clear all options and descriptions
						if(el.checked==true)
							el.fireEvent('click');
							
						el.getParent().hide();
					}
					else
					{
						el.getParent().show();
					}
				}
			}.bind(this));
		}
		
	},
	
	testCode: function(code){
		code=code.replace("([|])", "");
		
		var splitCode=code.split('');
		
		// if the code has characters specified, which are different to the format of the current code, return false. Otherwise, it should be shown - true
		var keep=true;
		
		for(var x in splitCode){
			
			if(splitCode[x]!='*' && splitCode[x]!=this.workingCode[x])
				keep=false;
			
		}
		
		return keep;
	},
	
	insertElements: function(elements,responseJSON,type){
		if (elements) {
			
			if(responseJSON.type=='option') {
				if(!$('optionTitle')) {
					var optionTitle = new Element ('div',{'id':'optionTitle','class':'innerTitle'}).set('html','<h3><strong>Options</strong></h3>');
					optionTitle.inject($('product'));
				}
				$each(elements, function(sel) {
					sel.inject($('optionTitle'));
				});
			}
			else if(responseJSON.type=='additional') {
				if(!$('additionalTitle')) {
					var additionalTitle = new Element ('div',{'id':'additionalTitle','class':'innerTitle'}).set('html','<h3><strong>Additions</strong></h3>');
					additionalTitle.inject($('product'));
				}
				$each(elements, function(sel) {
					if(type=='addition')
						sel.inject($('additionalTitle'));
					else
						sel.inject($('optionTitle'));
				});
			}
		}
	}

});

window.addEvent('domready', function () {
	var site = new Site();
});

