/**
* Nivea for Men
* Configurator
*
* $Id$
*
*/


/**
* @revisit: This looks quite unused - remove? 
*/
var settings;

/**
* Global var holding the configurator's initial settings.
* The actual values are set within the FTL. Flash can
* access the var using getInitialSettings().
*/
var initialSettings = [];



/**
* Class Category
*/
var Category = Class.create({
	
	initialize: function(id, name, products) {
	
		// console.log("new Category(%s, %s, %o)", id, name, products);
	
		this.id = id;
		this.name = name;
		this.products = products;
		this.enabled = false;
		this.highlight = false;
		
		var el = this.element = $('category' + id);
		var link;
		
		// console.log("#category" + id + " = ", this.element);
		
		if (el !== null) {
			link = el.down('a');
			if (link !== null) {
				// console.log("Binding click handler to %s", link);
				link.observe('click', function(ev) {
					this.toggle();
					var rel = link.readAttribute('rel');
					if (rel !== null) {
						// console.log("Tracking %s", rel);
						CounterPixel.track(rel);
					}
					ev.stop();
				}.bind(this));
			}
			this.counter = el.down('span.count');
		}
	},
	
	toggle: function(highlight) {
		
		// highlight === !!highlight
		if (typeof highlight != 'boolean') {
			this.highlight = !this.highlight;
		} else {
			this.highlight = highlight;
		}
		
		var numItems = 0;
		// console.log("Toggle: ", this); 
		// checks for existence of instance var before access
		if (this.counter) numItems = parseInt(this.counter.innerHTML, 10);
		
		if (numItems == 0) {
			this.element.addClassName('emptyResult');
			
			if (this.highlight) {
				this.element.down('div.messageEmptyResult').style.display = 'block';
			}
			else {
				this.element.down('div.messageEmptyResult').style.display = 'none';
			}			
		} else {
			this.element.down('div.messageEmptyResult').style.display = 'none';
			this.element.removeClassName('emptyResult');
		}
		
		this.element[(this.highlight ? 'add' : 'remove') + 'ClassName']('highlight');			
	},
	
	update: function(newSettings) {
		// console.log("newSettings: %o", newSettings);
		var id = this.id;
		var setting = newSettings.find(function(s) {return s.category == id});
		
		// invokes update() method on all the products
		this.products.invoke('update', setting);
		
		var count = 0;
		this.products.each(function(product) {
			if (product.show) count++;
		})
		
		// updates counter element if set
		if (this.counter) this.counter.innerHTML = count;
		
		this.toggle((typeof setting != 'undefined') && setting.highlight);
	}
});

/**
* Class Product
*/
var Product = Class.create({
	
	initialize: function(id, applications, skinTypes, extraNeeds) {
		this.id = id;
		this.applications = applications;
		this.skinTypes = skinTypes;
		this.extraNeeds = extraNeeds;
		this.element = $('product' + id);
		// console.log("Element for id %s = %s", id, this.element);
		this.show = true;
	},
	
	update: function(newSettings) {
		this.show = (typeof newSettings != 'undefined') && this.matches(newSettings) && newSettings.enabled;
		
		// return to prevent errors if the element is not actually set in the page
		// (e.g. in the print version, where things are a bit different)
		// if (this.element === null) return;
		// console.log("Element = %s", this.element);
		
		if (this.show) {
			this.element.select('.extraNeedFlag').each(function(needEl) {
				var id = needEl.identify();
				var prefix = 'product-' + this.id + '-extraNeed-';
				var extraNeedName = id.sub(prefix, '');
				if (newSettings.extraNeeds.indexOf(extraNeedName) >= 0) {
					needEl.show();
				} else {
					needEl.hide();
				}
			}.bind(this));
			this.element.show();
		}
		else {
			if (this.element !== null) this.element.hide();
		}
	},
		
	matches: function(newSettings) {
		if (newSettings.application == '' 
			|| newSettings.application == 'all' 
			|| this.applications.indexOf(newSettings.application) >= 0) {
			
			if (newSettings.skinType == '' 
				|| newSettings.skinType == 'all' 
				|| this.skinTypes.indexOf(newSettings.skinType) >= 0) {
				
				return true;
			}
		}
		
		if (newSettings.extraNeeds.length == 0) {
			return false;
		}
		
		var extraNeeds = this.extraNeeds;
		
		return newSettings.extraNeeds.any(function(need) {
			return extraNeeds.indexOf(need) >= 0;
		});
	}
});

/**
* Switches to view w/large images
*
* @param ev Event
*/
function showLargeImages(ev) {
	$('resizeSmall').removeClassName('selected');
	$('resizeLarge').addClassName('selected');
	CounterPixel.track($('resizeLarge').firstDescendant().readAttribute('rel').substr(5));
	$('products').removeClassName('small');
	$('products').addClassName('large');
	ev.stop();
}

/**
* Switches to view w/small images
*
* @param ev Event
*/
function showSmallImages(ev) {
	$('resizeLarge').removeClassName('selected');
	$('resizeSmall').addClassName('selected');
	CounterPixel.track($('resizeSmall').firstDescendant().readAttribute('rel').substr(5));
	$('products').removeClassName('large');
	$('products').addClassName('small');
	ev.stop();
}

function updateFlashCss(enabled) {
	if ($('intro').hasClassName('with-flash')) {
		if (enabled) {
			$('intro-flashcontent-container').setStyle({
				marginLeft: '0',
				marginTop: '0'
			});
			$('intro-flashcontent-col').setStyle({
				paddingLeft: '10px'
			});
			$('intro-title-block').setStyle({
				marginLeft: '0'
			});
			$('before-intro-flashcontent-col').setStyle({
				width: '392px'
			});
		} else {
			$('intro-flashcontent-container').setStyle({
				marginLeft: '-40px',
				marginTop: '-1px'
			});
			$('intro-flashcontent-col').setStyle({
				paddingLeft: '0'
			});
			$('intro-title-block').setStyle({
				marginLeft: '10px'
			});
			$('before-intro-flashcontent-col').setStyle({
				width: '382px'
			});
		}
	}
}

/**
* Updates products' visibility from given settings
*
* @param newSettings
*/
function updateSelection(newSettings) {
	// console.log("settings %o", newSettings);
	categories.invoke('update', newSettings);
	var enabled = categories.any(function(cat) {
		var setting = newSettings.find(function(s) {return s.category == cat.id});
		return setting.enabled;
	});
	if (enabled) {
		// $("intro").hide();
		$$('#intro').each(Element.hide);		
		$('products').setStyle({ display : 'block' });		
	} else {
		$('products').setStyle({ display : 'none' });
		$$('#intro').each(Element.show);
		//CounterPixel.track("/products/configurator/reset.nopv");
	}
	updateFlashCss(enabled);
	settings = newSettings;
}

function trackUI(target){
	CounterPixel.track("/products/configurator/interaction_panels.nopv");
}

/**
* Writes the current configurator settings to the session (via Ajax),
* then redirects to print version of the configurator page
*
* @param url URL the settings are sent to
* @param configuratorUrl URL of the configurator's print version
*/
function openPrintVersion(url, configuratorUrl) {
	var settingsStr = Object.toJSON(settings);
	// console.log("url: %s", url);
	
	var visibleProducts = "";
	var first = true;
	categories.each(function(category) {
		category.products.each(function(product) {
			if (product.show) {
				if (!first) {
					visibleProducts += ",";
				}
				visibleProducts += product.id;
				first = false;
			}
		})
	});
	var visibleProductsStr = Object.toJSON(visibleProducts);
	
	new Ajax.Request(url,
		{
			/**
			* @revisit: Shouldn't this be a POST request given the
			* fact we're writing something to the session?
			*/ 
			method: 'get',
			parameters: {settings: settingsStr, visibleProducts: visibleProductsStr},
			onComplete: function(transport) {
				// console.log('settings saved in session, text: %s', transport.responseText);
				eval(transport.responseText);
				if (typeof(key) != 'undefined') {
					// console.log('location: %s', configuratorUrl + '?print=true&key=' + key);
					window.location.href = configuratorUrl + '?print=true&key=' + key;
				}
			},
			onFailure: function(transport) {
				// console.log('error: saving settings in session');
			}
		}
	);
	
	/**
	* @revisit: This will always return false as the request is sent asynchronously, won't it?
	*/
	return false;
}

/**
* Writes the current configurator settings to the session (via Ajax),
* then redirects to print version of the configurator page
*
* @param url
* @param tellAFriendUrl
*/
function openTellAFriend(url, tellAFriendUrl) {
	var settingsStr = Object.toJSON(settings);
	//console.log("url: %s", url);	
	new Ajax.Request(url,
		{
			method: 'get',
			parameters: {settings: settingsStr},
			onComplete: function(transport) {
				// console.log('settings saved in db, text: %s', transport.responseText);
				eval(transport.responseText);
				if (typeof(key) != "undefined") {
					// console.log("location: %s", tellAFriendUrl + "?token=" + key);
					window.location.href = tellAFriendUrl + "?token=" + key;
				}
			},
			onFailure: function(transport) {
				// console.log('error: saving settings in db');
			}
		}
	);
	return false;
}

/**
* Returns initial settings var (for use w/Flash)
*
* @return Array settings array/object
*/
function getInitialSettings() {
	return initialSettings;
}
