/*
 * sIFR
 */
sIFR.replace(gazette, {
	  selector: '#customize h2',
	  css: '.sIFR-root { font-style: italic; color: #333333; font-size: 17px;}',
	  wmode: 'transparent',
	  preserveSingleWhitespace: true,
	  tuneWidth: 8
});


var Customizer = Class.create({
	
	initialize: function(element) {
		this.element = $(element);
		
		this.options = Object.extend({
			designs: [],
			width: 300,
			zIndex: 1,
			duration: 0.5,
			price: 0,
			units: 'cm',
			urls: {
				add: Katoenenzo.options.webroot + 'shoppingcart/ajax/add',
				cart: Katoenenzo.options.webroot + 'shoppingcart',
				coupon: Katoenenzo.options.webroot + 'shoppingcart/ajax/coupon'
			}
		}, arguments[1] || {});
		
		this.zIndex = this.options.zIndex;
		this.preloadDesigns();
		
		
	},
	
	preloadDesigns: function() {
		this.designs = this.element.down('.designs');

		
		var preloaded = 0;
		this.max = {
			height: 0
		};
		
		this.options.designs.each(function(design) {
			var id = design.id,
			    src = design.image;
			
			var preload = new Image();
			preload.onload = function() {
				preloaded++;
				
				this.designs.insert(new Element('div', {
					className: 'design',
					id: 'design_' + id
				}).setStyle({
					backgroundImage: "url('" + preload.src + "')",
					zIndex: this.zIndex
				}).setOpacity(0));
				
				// maximale dimensies
				//max.width = Math.max(max.widht, preload.width);
				this.max.height = Math.max(this.max.height, preload.height);
				
				if (preloaded == this.options.designs.length) {
					// als er maar 2 designs zijn (1 + noimage) is 1 de geselecteerde
					
					if (this.options.designs.length == 2) {
						this._selectedDesign = this.options.designs[0].id;
						this.showDesign(this._selectedDesign);
					}
					
					this.start();
				}
				
				preload.onload = Prototype.emptyFunction;
			}.bind(this);
			preload.src = design.image;
		}.bind(this));
	},
	
	start: function() {
		// stoffen
		this.fabrics = [];
		this.element.select('.fabrics').each(function(element) {
			this.fabrics.push(new FabricGroup(element, {
				fabrics: this.options.fabrics,
				Customizer: this
			}));	
		}.bind(this));
		this.updateFabric();
		
		// geen wrapper de hoogte
		this.designs.setStyle({ height: this.max.height + 'px' });
		
		// geef elke kledingstuk dezelfde dimensies
		this.designs.select('.design').invoke('setStyle', {
			width: this.options.width + 'px',
			height: this.max.height + 'px'
		});
		
		if (this.options.combinations.length > 0) {
		  this.showRandomCombination();
		}
		else {
			// er valt niets te customizen, maak alle designs visible
			this.designs.down('.design').setOpacity(1);
		}
		// prepare options
		this.element.select('div.option').each(function(option) {
			var title = option.getAttribute('title');
			option._title = title;
			option.writeAttribute('title', null);
		});

		this.markRandomSize();
		
		this.startCalculating();
		this.calculate();
		
		this.startObserving();
		
		// measure myself
		$w('#measureMyself').each(function(i) {
			var item = this.element.down(i);
			
			item.show = function() {
				this.setStyle('position:relative;visibility:visible;top:auto;left:auto;');
				return this;
			};
			item.hide = function() {
				this.setStyle('position:absolute;visibility:hidden;top:-9999px;left:-9999px;');
				return this;
			};
			item.visible = function() {
				return parseInt(this.getStyle('top')) != -9999;
			};
			item.toggle = function() {
				this[this.visible() ? 'hide' : 'show']();
			};
		}.bind(this));
		$('toggleMeasureMyself').observe('click', function(event) {
			event.stop();
			$('measureMyself').toggle();
		});
		
		// show & hide de loader
		$('loadingCustomizations').hide();
		this.element.setStyle('position:relative;visibility:visible;top:auto;left:auto;');
	},
	
	startObserving: function() {
		var options = this.element.down('.options');
		if (options) {
			options.observe('click', this.delegateSelections.bindAsEventListener(this));
		}
		
		// stof
		if (this.hasFabrics)
			this.element.down('.fabrics').observe('click', this.delegateFabrics.bindAsEventListener(this));
		
		// geselecteerde maat
		this.element.down('.size').observe('click', this.delegateSize.bindAsEventListener(this));
		
		// opmeten
		this.element.select('.measure input').invoke('observe', 'keyup', this.updateMeasurements.bindAsEventListener(this));
		
		// add to cart
		$('addToShoppingCart').observe('click', this.addToShoppingCart.bindAsEventListener(this));
		
		//apply coupon
		var couponBtn = $('coupon-btn');
		if(couponBtn)
			couponBtn.observe('click', this.handleApplyCouponClick.bindAsEventListener(this));
	},
	
	/*
	 * Cart
	 * Post Cart Object en breng user naar de winkelwagen
	 */
	addToShoppingCart: function(event) {
		event.stop();
		
		var calculate = this.getCulculateObject();
		
		var parameters = {
			'clothingid': this.options.id,
			'designid': this._selectedDesign,
			'options': this.getSelectedOptionsString(),
			'size': this.getSize(', '),
			'fabrics': this.getSelectedFabricString(),
			'price': calculate.totalInclVAT
		};
		
		//extra data for coupon
		if(this.coupon) {
			parameters.market_price = calculate.marketPrice;
			parameters.coupon_code = this.coupon.code;
			parameters.coupon_value = this.coupon.value + (this.coupon.type == 'percentage' ? '%' : 'EURO');
		}else{
			parameters.market_price = calculate.totalInclVAT; //same
			parameters.coupon_code = null;
			parameters.coupon_value = null;
		}
		
		new Ajax.Request(this.options.urls.add, {
			parameters: parameters,
			onComplete: function() {
				window.location.href = this.options.urls.cart;
			}.bind(this)
		});
	},
	
	/**
	 * handle apply coupon click
	 */
	handleApplyCouponClick: function(evt) {
		
		evt.stop();
		
		var couponCode = $('coupon-code').value;
		
		if(couponCode.empty()) return;
		
		//same coupon
		if(this.coupon && (this.coupon.code == couponCode.trim().toUpperCase()) ) {
			return;
		}
		
		//send request
		var params = {
			code:couponCode,
			clineid:this.options.clineid
		};
		new Ajax.Request(this.options.urls.coupon,{
			parameters:params,
			onSuccess: this.handleCouponSuccess.bind(this),
			onFailure: this.handleCouponFailure.bind(this)
		});
		
	},
	
	/**
	 * handles ajax coupon success
	 */
	handleCouponSuccess:function(xhr) {
		var data = xhr.responseText.evalJSON(true);
		if(data.statusCode <= 0) {
			this.handleCouponFailure(xhr);
			return;
		}
		var coupon = data.coupon;
		this.applyCoupon(coupon);
		$('coupon-msg').update(data.msg);
		new Effect.Highlight('coupon-msg');
	},
	
	/**
	 *Handler for Coupon Ajax Failure or invalid coupon
	 */
	handleCouponFailure:function(xhr) {
		var data = xhr.responseText.evalJSON(true);
		if(data.statusCode <=0) {
			$('coupon-msg').update(data.errormsg);
		}else{
			$('coupon-msg').update('Request error');
		}
		
		new Effect.Highlight('coupon-msg');
	},
	
	/**
	 * Applys discount to item
	 */
	applyCoupon: function(coupon) {
		
		if(!coupon) return;
		
		//coupon in use now
		if(this.coupon && (this.coupon.code == coupon.code)) {
			return ;
		}
		//update coupon
		this.coupon = coupon;
		
		this.calculate();
		
	},
	/*
	 * Measurements
	 */
	updateMeasurements: function() {
		var measurements = this.getMeasurements(),
			keys = Object.keys(measurements);
		
		if (keys.length) {
			this.element.select('div.size .selected').invoke('removeClassName', 'selected');
		}
		else {
			this.markRandomSize();
		}
	},

	getMeasurements: function(event) {
		var measurements = {};
		
		this.element.select('.measure label').each(function(label) {
			var value = $(label.getAttribute('for')).value.strip();
			if (value.length) {
				measurements[label.innerHTML] = parseFloat(value.replace(',', '.')) || 0;
			}
		});
		
		return measurements;
	},
	
	getMeasurementString: function() {
		var measurements = this.getMeasurements(),
			keys = Object.keys(measurements),
			arr = [],
			seperator = arguments[0] || '|';
		
		if (keys.length) {
			keys.each(function(key) {
				arr.push(key + ': ' + measurements[key] + this.options.units);
			}.bind(this));
		}
		
		return arr.join(seperator);
	},
	
	
	
	/*
	 * Retrieve functions, used by cart and calculate
	 */
	getSize: function() {
		var selectedSize = this.element.down('div.size .selected'),
			seperator = arguments[0] || '|';
		
		if (selectedSize) {
			return selectedSize.down('.identity').innerHTML;
		}
		else {
			return this.getMeasurementString(seperator);
		}
	},
	
	getSelectedFabricString: function() {
		var collect = [];
		this.element.select('.fabrics .selected').reverse().each(function(fabric){
			var order = fabric.id.substr(6,1);
			collect[order] = ((/_([0-9]+)*$/.exec(fabric.id) || [null, null])[1]);
		});
		return collect.join('|');
	},
	
	getSelectedOptionsString: function() {
		var collect = [];
		this.element.select('.options a.selected').each(function(selection) {
			var option = selection.up('.option'),
				optionNumber = ((/_([0-9]+)*$/.exec(option.id) || [null, null])[1]);
			
			var selectionNumber = ((/_([0-9]+)*$/.exec(selection.id) || [null, null])[1]);
			
			collect.push(optionNumber + ':' + selectionNumber);
		});
		return collect.join('|');
	},
	
	
	
	/*
	 * Event delegation 
	 */
	
	delegateSelections: function(event) {
		var element = event.findElement('.selection');
		if (element) {
			event.stop();
			this.markSelection(element);
			
			var selectionid = (/_([0-9]+)*$/.exec(element.id) || [null,null])[1];
			
			var combination = this.getCombination();
			this.showDesign(combination.designid);
		}
	},
	
	delegateFabrics: function(event) {
		var element = event.findElement('.fabric');
		
		if (element) {
			event.stop();
			this.selectFabric(element);
		}
	},
	
	delegateSize: function(event) {
		var element = event.findElement('.sizes ul.size');
		
		if (element) {
			this.selectSize(element);
		}
	},
	
	
	
	markRandomSize: function() {
		var sizes = this.element.select('.sizes ul.size');
			
		var randomSize = sizes[Math.floor(Math.random()*sizes.length)];
		this.selectSize(randomSize);
	},
	
	showRandomCombination: function() {
		var randomCombination = this.options.combinations[Math.floor(Math.random()*this.options.combinations.length)],
		    combination = randomCombination.combination,
		    designid = randomCombination.designid;
		
		this.markSelectionByCombination(combination);
		this.showDesign(designid);		
	},
	
	markSelectionByCombination: function(combination) {
		var ids = combination.split('.');
		ids.each(function(id) {
			this.markSelection('selection_' + id);
		}.bind(this));
	},
	
	markSelection: function(element) {
		var element = $(element);
		element.addClassName('selected')
		       .siblings().invoke('removeClassName', 'selected');
	},
	
	getCombination: function() {
		var combination = [];
		this.element.select('div.option a.selected').each(function(selected) {
			combination.push(parseInt((/_([0-9]+)*$/.exec(selected.id) || [0, 0])[1]));
		});
		combination = combination.sort(function(a, b) { return (a - b)}).join('.');
		
		
		return this.options.combinations.find(function(s) {
			return s.combination == combination;
		});
	},
	
	showDesign: function(number) {
		this._selectedDesign = number;
		var element = $('design_' + number);

		if (!element) return;
		
		if (this._showEffect) { 
			if (this._showEffect.element == element) return;
			this._showEffect.cancel();
		};

		this.zIndex++;
		element.setOpacity(0).setStyle({ zIndex: this.zIndex });
		this._showEffect = new Effect.Appear(element, { duration: this.options.duration });
	},
	
	/*
	 * Size
	 */
	selectSize: function(element) {
		var element = $(element);
		element.up('div.size').select('ul.size').invoke('removeClassName', 'selected');
		element.addClassName('selected');		       
	},


	
	/*
	 * Prijs berekening
	 */
	
	startCalculating: function() {
		$w('selectSize markSelection updateMeasurements').each(function(fn) {
			
			this[fn] = this[fn].wrap(function(proceed, event) {
				proceed(event);
				this.calculate();
			}.bind(this));
		}.bind(this));
	},
	
	/*
	 * Calculate
	 */
	
	getCulculateObject: function() {
		var base = this.options.price,
			VAT = this.options.VAT / 100;
		
		var extra = 0,
			extraString = [];
		this.element.select('div.option a.selected').each(function(selected) {
			var id = (parseInt((/_([0-9]+)*$/.exec(selected.id) || [0, 0])[1])),
				item = this.options.selections.find(function(s) { return s.id == id });
		
			extraString.push(selected.up('.option')._title.capitalize() + ': ' + selected.down('.title').innerHTML);
			extra += (item.price || 0);
		}.bind(this));
		extraString = extraString.join(', ');
		
		var totalInclVAT = (base + extra), // + send
			totalExclVAT = totalInclVAT / (1 + VAT),
			totalVAT = totalInclVAT - totalExclVAT;
		
		var marketPrice = totalInclVAT;
		var discountValue = 0;
		if(this.coupon) {
			if(this.coupon.type == 'percentage') {
				discountValue = (this.coupon.value * totalInclVAT) / 100;
			}else if(this.coupon.type == 'fixed') {
				discountValue = this.coupon.value;
			}
			totalInclVAT -= discountValue;
		}
		
		//alert(discountValue);
		//alert(totalInclVAT);
		
		return {
			base: (base).toFixed(2),
			extra: (extra).toFixed(2),
			extraString: extraString,
			totalInclVAT: (base + extra - discountValue).toFixed(2),
			marketPrice: (base + extra).toFixed(2),
			totalExclVAT: (marketPrice / (1 + VAT)).toFixed(2),
			totalVAT: (marketPrice - totalExclVAT).toFixed(2),
			VAT: parseFloat(this.options.VAT)
		};
	},
	
	calculate: function() {
		var element = this.element.down("div.price");
		
		var calc = this.getCulculateObject();
		
		var extraElement = this.element.down('.extra');
		if (calc.extraString) {
			extraElement.show()
						.down('.title').update(calc.extraString);
		}
		else {
			extraElement.hide();
		}
		
		element.down('.totalItem').update("&euro; " + calc.totalExclVAT);
		element.down('.totalExclVAT .amount').update("&euro; " + calc.totalExclVAT);
		element.down('.VAT .amount').update("&euro; " + calc.totalVAT);
		if(this.coupon) {
			element.down('.totalInclVAT .amount').update("&euro; " + calc.marketPrice);
			element.down('.couponValue').show();
			var cval = (this.coupon.type == 'fixed') ? ('&euro; ' + this.coupon.value) : (this.coupon.value + "%");
			element.down('.couponValue .amount').update('- ' + cval);
			element.down('.newTotalInclVAT').show();
			element.down('.newTotalInclVAT .amount').update("&euro; " + calc.totalInclVAT);
		}else{
			//element.down('.couponValue').hide();
			//element.down('.newTotalInclVAT').hide();
			element.down('.totalInclVAT .amount').update("&euro; " + calc.totalInclVAT);
		}
		
		// maat
		element.down('.maat').update(this.getSize(', '));
	},
	
	updateFabric: function() {
		var stoffen = [];

		this.fabrics.each(function(fabric, i) {
			var prefix = this.fabrics.length > 1 ? i+1 + ': ' : '';
			stoffen.push(prefix + fabric.getSelection());
		}.bind(this));
		this.element.down('.stof').update(stoffen.join(', '));
	}
	
});

var FabricGroup = Class.create({
	initialize: function(element) {
		this.element = element;
		
		this.options = Object.extend({
			overlayOpacity: 0.35,
			fabrics: [],
			iconDimensions: {
				width: 590,
				height: 100
			},
			Customizer: {}
		}, arguments[1] || {});
		
		this.selectedFabric = this.element.down('.selectedFabric');
		this.element.down('.overlay').setOpacity(0);
		
		this.selectRandom();
		
		this.startObserving();
		
	},
	
	startObserving: function() {
		this.selectedFabric.observe(Katoenenzo.useEvent['mouseover'], Katoenenzo.capture(this.toggleFabricZoom.bindAsEventListener(this)))
		.observe(Katoenenzo.useEvent['mouseout'], Katoenenzo.capture(this.toggleFabricZoom.bindAsEventListener(this)))
		.observe('click', this.clickFabricZoom.bindAsEventListener(this));
		
		this.element.observe('click', this.delegateClick.bindAsEventListener(this));
	},
	
	clickFabricZoom: function(event) {
		event.stop();
		Lightview.show(this._selectedFabric);
	},
	
	toggleFabricZoom: function(event) {
		// cancel running effect
		if (this._toggleFabricZoom) this._toggleFabricZoom.cancel();

		var opacity = (event.type == Katoenenzo.useEvent['mouseover']) ? this.options.overlayOpacity : 0;
		var ext = {};
		// hiding
		if (opacity > 0) {
			ext.afterFinish = Element.show.curry(this.element.down('.selectedFabric .icon'));
		}
		// showing
		else {
			this.element.down('.icon').hide();			
		}
		
		this._toggleFabricZoom = new Effect.Opacity(this.element.down('.selectedFabric .overlay'), Object.extend(ext, {
			to: opacity,
			duration: 0.15
		}));		
	},
	
	delegateClick: function(event) {
		var element = event.findElement('.fabric');
		
		if (element) {
			event.stop();
			this.select(element);
		}
	},
	
	select: function(element) {
		var element = $(element);
		element.addClassName('selected').siblings().invoke('removeClassName', 'selected');
		
		
		
		var number = (/_([0-9]+)*$/.exec(element.id) || [null, null])[1],
			fabric = (this.options.fabrics.find(function(fabric) { return fabric.id == number }) || {}),
		    image = fabric.href;
		
		
		this.setZoomThumbnail(image);
		
		this._selectedFabric = fabric;
		this.options.Customizer.updateFabric();
	},
	
	setZoomThumbnail: function(image) {
		this.element.down('.selectedFabric .thumbnail').setStyle({
			backgroundImage: 'url("' + Katoenenzo.options.phpThumbUrl + '?src=' + image + '&w=' + this.options.iconDimensions.width +
			'&h=' + this.options.iconDimensions.height + '&zc=1")'
		});
	},
	
	selectRandom: function() {
		var fabrics = this.element.select('.fabric');
		
		var randomFabric = fabrics[Math.floor(Math.random() * fabrics.length)];
		this.select(randomFabric);
	},
	
	getSelection: function() {
		return this.element.down('.selected').getAttribute('title');
	}
	
});
