/** 
 * @version 1.0.5
 */

var Rollover = {
	config: {
		offsetX: 10, // Styles buffer i.e. borders, padding
		offsetY: 10, // Styles buffer i.e. borders, padding
		offsetW: 9, // Styles from the image to the outside border
		offsetH: 9 // Styles from the image to the outside border
	},

	status: {
		draggable: null,
		zoomed: false // Stops a double zoom happening if the image is clicked twice in quick succession
	},

	init: function() {
		var rollovers = document.getElementsByTagName("img");

		for (var i = 0, ix = rollovers.length; i < ix; i++) {
			var image = rollovers[i],
				params = image.className;

			if (image.className.indexOf("collect") != -1) {
				var wrapper, container, copy, scissors;

				wrapper = document.createElement("span");
				wrapper.className = params; // Copy the classes to help style it
				container = image.parentNode;
				copy = image.cloneNode(true);
				wrapper.appendChild(copy);

				scissors = document.createElement("span");
				scissors.className = "scissors";

				wrapper.appendChild(scissors);
				container.replaceChild(wrapper, image);

				YAHOO.util.Event.addListener(copy, "mouseover", Rollover.show);
			}
		}
	},

	destroy: function() {
		var rollover = document.getElementById("rollover");
		if (rollover) {
			// Clean up listeners
			YAHOO.util.Event.purgeElement(rollover, true);
			YAHOO.util.Event.removeListener(window, "resize", Rollover.resize);
			
			var purge = function (d) {
				var a = d.attributes, i, l, n;
				
				a = d.childNodes;
				if (a) {
					l = a.length;
					for (i = 0; i < l; i += 1) {
						purge(d.childNodes[i]);
					}
				}
			};

			purge(rollover);

			document.body.removeChild(rollover);
			Rollover.status.zoomed = false;
			e = null;

			var draggable = document.getElementById("rollover-draggable");
			if (draggable) {
				document.body.removeChild(draggable);
			}
		}
	},

	show: function(e) {
		// Kill any existing rollover
		Rollover.destroy();	

		var colours = [],
			alt = this.getAttribute("alt"),
			Dom = YAHOO.util.Dom,
			config = Rollover.config,
			coord = Dom.getXY(this),
			instance = this;


		rollover = document.createElement("div");
		rollover.id = "rollover";

		var canvas = document.createElement("div");
		canvas.className = "canvas";

		var detail = document.createElement("div");
		detail.className = "detail";

		var header = document.createElement("div");
		header.className = "header";

		var imageData = Rollover.getImageData(this);

		// Header
		header.innerHTML = [
			"<a href=\"#\" class=\"" + this.className + "\" onclick=\"return Rollover.zoom.call(this);\">",	
			"<img alt=\"" + alt + "\" src=\"" + this.src + "\"id=\"rollover-image\"/>",	
			"<span class=\"scissors\"></span>",
			"</a>",
			"<p class=\"add\">",
			"<a href=\"#\" onclick=\"return YAHOO.dulux.co.uk.doScrapbookAddImage('" + imageData.code + "\', this);\">Add to my scrapbook</a>",
			"</p>"
		].join("");

		// Join all the HTML elements together and put on the page
		detail.appendChild(header);
		canvas.appendChild(detail);
		rollover.appendChild(canvas);
		document.body.appendChild(rollover);

		// Apply event to hide it
		YAHOO.util.Event.addListener(rollover, "mouseout", Rollover.hide, rollover);
		YAHOO.util.Event.addListener(window, "resize", Rollover.resize, {config: config, rollover: rollover, coord: coord}, instance);


		// Now position the rollover
		var imageClip = Rollover.getSize(this);

		Dom.setX(rollover, coord[0] - config.offsetX);
		Dom.setY(rollover, coord[1] - config.offsetY);
		Dom.setStyle(detail, "width", imageClip.w + "px");
	
		if (!Dom.hasClass(this, "nodrag")) {		
			// Create the draggable picture
			var draggable = document.createElement("div");
			draggable.id = "rollover-draggable";
			document.body.appendChild(draggable);

			//if (!Rollover.status.draggable) {
				Rollover.status.draggable = new YAHOO.dulux.co.uk.DDCollectImage("rollover-image", "pictures", { 
					dragElId: "dragPicture", 
					centerFrame: true, 
					resizeFrame: false 
				});
			//}
		}

		// Lastly, hide any of the "old" rollovers on the page that might not disappear correctly.
		// The same code that does this for thie scripts "rollover" is in base.js.
		var rollovers = document.getElementById("rollovers");
		if (rollovers) {
			rollovers.style.display = "none";
		}
	},

	/**
	 * Positions the rollover when the browser window is resized.
	 */
	resize: function(e, a) {
		var Dom = YAHOO.util.Dom;
		var coord = Dom.getXY(this);
		Dom.setX(a.rollover, coord[0] - a.config.offsetX);
		Dom.setY(a.rollover, coord[1] - a.config.offsetY);
	},

	/**
	 * Removes the rollover HTML and strips the event listeners.
	 * @event
	 * @param {HTMLObject} e Event object.
	 */
	hide: function(e) {		
		// Ensure mouseout only on the outer container
		e = e || window.event;
		var el = (window.event) ? e.srcElement : e.target;

		if (el.nodeName.toLowerCase() !== "div") { return; }

		var tag = (e.relatedTarget) ? e.relatedTarget : e.toElement;
		
		while (tag && tag !== el && tag.nodeName.toLowerCase() !== "body") {
			tag = tag.parentNode
		}

		if (tag === el) { return; }

		Rollover.destroy();	
	},

	/**
	 * Determines the size of an HTML element and it's position on the viewport.
	 * @param {String|HTMLObject} e HTML element or string Id.
	 * @returns {ObjectLiteral} Element information: x, y, w, h.
	 */
	getSize: function(e) {
		var clip = YAHOO.util.Dom.getRegion(e);
		return {
			x: clip.left,
			y: clip.top,
			w: (clip.right - clip.left),
			h: (clip.bottom - clip.top)
		};
	},

	/**
	 * Create the zoom effect and if the correct paramters are stored in the ALT tag, it will generate a list of colours.
	 * To create a list of colours the following syntax must be used on the <IMG> ALT tag: Colours used: putting_green, page_citrus_6
	 */
	zoom: function() {
		// If the zoom is already open, don't carry on zooming
		if (Rollover.status.zoomed) { return; }

		var rollover = document.getElementById("rollover"),
			detail = rollover.getElementsByTagName("div")[1],
			image = rollover.getElementsByTagName("img")[0],
			easing = YAHOO.util.Easing.easeOut,
			speed = .2,
			offsetX = 0,
			offsetY = 0,
			newImageWidth = 0,
			newImageHeight = 0;

		var imageSize = Rollover.getSize(image);
			imageWidth = imageSize.w;
			imageHeight = imageSize.h;

		switch(imageWidth) {
			case 72:  
				// Remove the styles from the dimensions i.e. padding, borders
				offsetX = 82 - Rollover.config.offsetW; 
				offsetY = 82 - Rollover.config.offsetH; 
				newImageWidth = 236;
				newImageHeight = 236;
			break;
			case 154: 
				// Remove the styles from the dimensions i.e. padding, borders
				offsetX = 50 - Rollover.config.offsetW;
				offsetY = 50 - Rollover.config.offsetH; 
				newImageWidth = 236;
				newImageHeight = 236;
			break;
				default: 
				// If the image size is not one we expect
				var scale = 0;

				newImageHeight = imageHeight + 82; // 82 is 72 + 10 = the next size up (equiv. to 236 sizes for rectangular images)
				scale = newImageHeight / imageHeight;
				newImageWidth = Math.round(imageWidth * scale);	
				
				offsetY = (newImageHeight - imageHeight) / 2;
				offsetX = (newImageWidth - imageWidth) / 2;
			break;
		}

		var callback = function() {
			// Change the image 
			image.src = image.src.replace(/_72|_154/, "_236");
			if (image.src.indexOf("_236.jpg") === -1) {
				image.src = image.src.replace(".jpg", "_x.jpg");
			}
			var marker = "colours used: ";

			// Make sure that the image has a colour list
			var splitter = image.alt.toLowerCase().indexOf(marker);
			if (splitter < 0) { return; }

			// Add in the navigation
			var colours = image.alt.substring(splitter + marker.length).split(", ");

			// Colours sub navigation
			var colourSubNavItems = [
				"<ul>",
				"<li class=\"first-child\"><a href=\"/colour/{0}\">See colour schemes</a></li>",
				"<li><a href=\"/servlet/ShoppingBasketHandler?action=add&amp;ItemType=colour&amp;ItemID={0}\">Order a colour sample </a></li>",
				"<li class=\"last-child\"><a href=\"/servlet/ColourAvailabilityHandler?name={0}\">See products in this colour </a></li>",
				"</ul>"
			];

			// Build the colours 
			var coloursList = document.createElement("ul");

			for (var i = 0, ix = colours.length; i < ix; i++) {
				var colourId = Rollover.toColourId(colours[i]);
				var coloursItem = document.createElement("li");	

				var coloursItemHeader = [
					"<h6>",
					"<span style=\"background: url(/web/images/swatch/" + colourId + ".jpg);\"></span>",
					"<a href=\"#\">" + colours[i] + "</a>",
					"</h6>"
				];

				coloursItem.innerHTML = coloursItemHeader.join("") + colourSubNavItems.join("").replace(/\{0\}/g, colourId);

				coloursList.appendChild(coloursItem);
			}

			var content = document.createElement("div");
			content.className = "content";

			content.appendChild(coloursList);
			detail.appendChild(content);

			// Add toggle to the colours
			var headers = content.getElementsByTagName("h6");

			for (var j = 0, jx = headers.length; j < jx; j++) {
				headers[j].onclick = Rollover.toggleColours;
			}

			// Hide the content to it can be revealed in a nice transition
			var contentH = Rollover.getSize(content).h;			

			content.style.height = "0";
			content.style.overflow = "hidden";
			
			var contentAnim = new YAHOO.util.Anim(content, {   
				height: {to: contentH}
			}, speed, easing);

			contentAnim.onComplete.subscribe(function() {
				 content.style.height = "auto";
				 content.style.overflow = "visible";
			});

			contentAnim.animate();
		};

		var imageAnim = new YAHOO.util.Anim(image, {   
				width: {to: newImageWidth},
				height: {to: newImageHeight}
			}, speed, easing);
			
		imageAnim.onComplete.subscribe(callback);
		
		var detailAnim = new YAHOO.util.Anim(detail, {   
				width: {to: newImageWidth}
			}, speed, easing);

		var rolloverAnim = new YAHOO.util.Anim(rollover, {   
				left: {by: -offsetX},
				top: {by: -offsetY}
			}, speed, easing);

		imageAnim.animate();
		detailAnim.animate();  
		rolloverAnim.animate();

		// Set the status so we know that the zoom
		Rollover.status.zoomed = true;

		return false;
	},
	/**
	 * Toggle the visibility of the colour names sub navigation.
	 */
	toggleColours: function() {
		var sub = this.nextSibling;
		if (sub) {
			if (sub.style.display == "block") {
				sub.style.display = "none";
			} else {
				// Hide all the other sub nav
				var content = sub.parentNode.parentNode;
				var items = content.getElementsByTagName("ul");

				for (var i = 0, ix = items.length; i < ix; i++) {
					items[i].style.display = "none";
				}

				sub.style.display = "block";
			}
		}

		return false;
	},	
	/**
	 * Breaks apart an image path to determine the image code and image size if it has one.
	 * @param {String|HTMLObject} e Image object or image path string.
	 * @returns {ObjectLiteral} Image code, and size. If there is no size it returns NULL: code, size.
	 */
	getImageData: function(e) {
		var src = e, 
			image, size, index, code;

		// If the paramenter is a HTMLObject image, get the ALT tag
		if (typeof e == "object") {
			src = e.getAttribute("src");
		}
		
		src	  = src.toLowerCase();
		image = src.substring(src.lastIndexOf("/") + 1); // Remove the file path
		size  = image.substring(image.lastIndexOf("_") + 1, image.indexOf(".jpg")); // Get the image size (if it has one)
		index = image.indexOf(size) - 1; // By default get the position of the size to trim the image name to get the code

		// Check to see that the size is actually a number and not an accidental string that matches the strin criteria
		if (!/^\d+$/.test(size)) {
			size  = null;
			index = image.indexOf(".jpg");
		}
		code = image.substring(0, index);

		return {
			code: code,
			size: size
		};
	},
	/**
	 * Convert a colour name to a colour code used for images.
	 * @param {String} s Colour name
	 * @returns {String} Colour code, underscored, lowercase.
	 */
	toColourId: function(s) {
		return s.toLowerCase().replace(/^\s+|\s+$/g, "").replace(/\s/g, "_");
	}
};

