argos.check("widgets");
argos.require("widgets.popup");


argos.widgets.quickinfo = new (function() {

	// PRIVATE PROPERTIES
	var _quickInfo = this;
	var _quickInfoClass = "quickInfo";
	var _quickInfoTitle = "Quick view"; 
	var _page = "";
	var _mercadoresult = "";
	var _clippedContent = false;
	var _lastClicked = "";
	var _securePage = argos.page.isSecurePage();



	// CLASS-like objects
	function Product(el, selector) {
		var holder = el.find(selector["holder"]);
		var a = el.find(selector["link"]);
		var title = (selector["title"]) ? el.find(selector["title"]).text() : a.text();
		var href = (a.length > 0) ? a.attr("href") : "";
		var quickLink = new QuickLink(_formatHref(href), title);
		holder.append(quickLink.element);

   		// handles the show/hide for quicklinks
  		holder.hover(function(){
  				if($(this).attr("id") != "clothing"){
   				quickLink.element.show();
   				}
	   		},
			function(){
   				quickLink.element.hide();
   		});

		this.element = el;
		this.quickLink = quickLink;
		this.title = title;
	}

	function QuickLink(href, title) {
		var _ql = this;
		var element = null;
		var l = document.createElement("a");
		var s = document.createElement("span");
		var t = document.createTextNode("Quick view");
		
		s.appendChild(t);
		l.appendChild(s);
		l.className = "quickinfo";
		l.title = "Quick view of " + title;
		l.href = href;
		element = $(l);

		element.click(function() {
			// This done as public so that we can overwrite with custom IE bug-fix version.
			var el = $(this);
			var x = $("#outerwrap").offset().left + 325;
			var y = $("#header").height();
			var href = el.attr("href");
			var product = href.replace(/.*\/([0-9]*)\.htm/, "$1");

			// Clear any existing content, hide, add header, then open.
			// Content gets added on AJAX complete.
			_quickInfo.popup.element
					.hide()
					.empty()
					.addClass(_quickInfoClass)
					.append(_createHeader())
					.append("<div class=\"content\"></div>");

			// Re-open the cleared popup. 					
			_quickInfo.popup.positionNear(el, x, y, 0);
			_quickInfo.popup.open("show",500);
			_quickInfo.popup.loading(true);
		
			$.ajax({
				beforeSend : function() {
					_lastClicked = product;
				},
				url : href,
				dataType : "html",
				error : function() {
					var errorMsg = "<p class=\"error\">Sorry, we've been unable to retrieve the requested Quick view information.</p>";
					_quickInfo.popup.element.contents(".content").append(errorMsg);
					_quickInfo.popup.loading(false);
				},
				complete : function(XMLHttpRequest, textStatus) {
					// Testing revealed double content when first Ajax completed after second. 
					// This meant both contents were appended to last opened popup.
					// _lastClicked check makes sure the last selected is only loaded.
					// This can be tested by uncommenting the setTimout randmon delay.
					var responseText = _ql.preLoadHtmlAdjustments(XMLHttpRequest.responseText);
					if(_lastClicked == product) {
						if(responseText.length > 0) {
							_loadContent($(responseText));
						}

						_initiateRicherContent();
					}
				}
			});


			// Omniture actions.
			_quickInfo.omniture.update(el);
			_quickInfo.omniture.send();
			_quickInfo.omniture.reset(el);

			return false;
		});


		this.element = element;
		this.preLoadHtmlAdjustments = function(html) {
			// Allows for alterations before loading content.
			// By default, this does nothing.
			// Initially included to provide IE workarounds.
			return html; 
		}
	}


	// PUBLIC METHODS (exposed so they can easily intentionally be overwritten by other scripts)
	this.init = function(activateOnThesePages) {
		// (int)spacer: Use for desired space between popup and viewport base.
		// (int)minHheaderPos: Use to consider a cut-off point for top (e.g. don't position over site navigation).
		var activate = arguments.length > 0 ? false : true;
		for(var i=0; i<activateOnThesePages.length; i++) {
			if(document.body.className.indexOf(activateOnThesePages[i]) >= 0) {
				activate = true;
				_page = activateOnThesePages[i];
				break;
			}
		}
		if(activate) {
			_quickInfo.popup = argos.widgets.popups.create("quickInfoPopup");
			_setUpProducts();
			$(".viewselector .action").click(_quickInfo.popup.close); // make sure QuickInfo closes on gallery/list view switching.
		}
	}
	
	
	this.postLoadAddition = function(element) {
            var product = new Product(element,{
                  "holder" : ".actions",
                  "link" : ".image a",
                  "title" : ".title a"
            });
            product.quickLink.element.hide();         
	}
	
	// Gets current product properties for external use (e.g. argos.richercontent)
	this.product = 	function() {
		var more = $(".more", this.popup.node);
		var title = $(".details .title", this.popup.node).text();
		return {
			number : more.length > 0 ? more.attr("href").replace(/^.*partNumber\/(\d*)\.htm$/, "$1") : "",
			pdp : more.attr("href"), // url
			shortDescription : title, // currently shares title value.
			title : title
		};
	}
	
	

	// PRIVATE METHODS
	function _initiateRicherContent() {
		argos.richercontent.init(_quickInfo.popup.element, "quickinfo");
	}

	function _createHeader() {
		var html = "  <div class=\"header\">";
		html    += "    <h2>" + _quickInfoTitle + "</h2>";
		html    += "  </div>";
		return html;
	}

	function _setUpProducts() {
		// Due to differences in .product and .hero element HTML, we need 
		// to use more than one selector. Passing in to avoid cluttering 
		// code in Product() by using multiple jQuery selectors.

		// "holder" : element where we insert QuickInfo button.
		// "link" : element where we get the QuickInfo href (before altering for QuickInfo use)
		// "title" : element where we get the title text (attr used on QuickInfo button).

		// TODO: Find nicer way of coping with different .product layouts. 

		// Find and set up products on lister + search pages.
		jQuery("body.browselister .product, body.search .product").each(function(){
			var product = new Product($(this),{
				"holder" : "li.productimg, dd.actions",
				"link" : ".producttitle a:first, dd.image a",
				"title" : ""
			});
	   		product.quickLink.element.hide();
		});
		// Find and set up hero products.
		jQuery(".hero").each(function(){
			var product = new Product($(this),{
				"holder" : ".hero",
				"link" : "h4 > a",
				"title" : ""
			});
	   		product.quickLink.element.hide();
		});
		// Find and set up products on new PDP and SOP.
		jQuery("body.productdetails .product:not(.product_selector), body.offerdetails .product:not(.product_selector), body.reservationflow .product:not(.product_selector)").each(function(){
			var product = new Product($(this),{
				"holder" : ".actions",
				"link" : ".title a",
				"title" : ".title a"
			});
	   		product.quickLink.element.hide();
		});
	}

	function _formatHref(href) {
		// URL needs QuickView for rewrite and trim out rest for efficient caching.
		var re = /(.*)[\/]Product[\/](partNumber\/[0-9]*)([\/]*.*)/i;
		href = (href) ? href.replace(re, "$1/QuickView/$2.htm"): "";
		return _securePage ? href.replace("http://", "https://") : href;
	}

	function _loadContent(content) {
		var image = content.find(".image img");  
		var information = content.find(".details .information");
		
		// Clean HTML before we run any height calculations.
		information.html(argos.utils.cleanHtml(information));
					
		if(image.length > 0) {
			// Need to hide the content before we do our calculations. After that, reveal the content 
			// with fadeIn effect. Note: visibility:hidden causes errors in calculations with IE.
			_quickInfo.popup.element.contents(".content").append(content.css({"position":"absolute", "left":"-2000px"}));
			
			// Need to fire calculations after the main image has loaded to get decent height.
			image.load(function() {
				_postImageLoad(content);
			});

			image.error(function() {
				// In case we cannot get the image.
				image.css({
					"display" : "block",
					"height" : ((image.attr("height") > 0) ? image.attr("height") : 200) + "px"
				});
				_postImageLoad(content);
			});

			if(image.complete) image.load(); // Opera is one browser that doesn't fire load event when image is cached.
		}
		else {
			_quickInfo.popup.element.contents(".content").append(content);
			_quickInfo.popup.loading(false);
		}
	}
	
	function _manipulatePopupContent() {
		var content = _quickInfo.popup.element.contents(".content");
		var image = content.contents().find(".image");
		var details = content.contents().find(".details");
		var information = details.contents(".information");
		var availableHeight = image.height() - (details.outerHeight(true) - information.height());
		var finalContent = null;

		// Note: IMG  element (inside ".image") should always be loaded to give correct .image height.
		// Without height, 'difference' gives false reading and usually results in no details shown.

		if(availableHeight > 0) {
			finalContent = _verticallyClipContent(information.children(), availableHeight);
			information.empty().append(finalContent); 
		}
	}

	function _verticallyClipContent(elements, height) {
		var content = $("<div></div>");
		var clone = null;
		var h = 0;
		for(var i=0; i<elements.length; i++) { 
			var element = elements.eq(i);
   			if(element.outerHeight(true) < height) {
   				content.append(element.clone());
   				height -= element.outerHeight(true);
   			}
   			else {
				_clippedContent = true; // quickfix: set flag used elsewhere.
   				clone = element.clone();
   				clone = clone.empty();
				element.children().each(function() { 
					h += $(this).outerHeight(true);
				});
   				if(h > 0 && (element.outerHeight(true) - h) < height) {
					height -= clone.outerHeight(true);
   					content.append(clone.append(_verticallyClipContent(element.children(), height)));
   				}
				break;
   			}
		}
		return content.contents();
	}

	function _postImageLoad(content) {
		_manipulatePopupContent();

		// Setting display:none because jQuery (annoyingly) messes with this on fadeIN/OUT effects.
		content.css({"display":"none","position":"relative","left":"0px"}).fadeIn(function() {
           	_quickInfo.popup.loading(false);
			_quickInfo.popup.postLoadPositionAdjustment($("#header").height());
		});
	}




	//======= argos.widgets.quickinfo IE fixes =====================================
	// Throw in any fixes for IE6 bugs (note: delete this code when dropping support for IE versions).
	if(jQuery.browser.msie && Math.floor(jQuery.browser.version) <= 6) {
		var oldArgosQuickInfoInit = _quickInfo.init;

		_quickInfo.init = function() {			
			oldArgosQuickInfoInit(_quickInfo.approvedPages);
			$("span.quickinfo").hover(
				function() {
					$(this).addClass("quickinfo_hover");
				},
				function() {
					$(this).removeClass("quickinfo_hover");
				}
			);
		};
	}

	if (_securePage && $.browser.msie) {
		QuickLink.preLoadHtmlAdjustments = function(html) {
			var re = new RegExp("src=(\"|')http:", "mig");
			return html.replace(re,"src=$1https:");	
		}
	}
	//= END = argos.widgets.quickinfo IE fixes =====================================


});




//======= Custom Omniture tagging for QuickInfo ================================
argos.widgets.quickinfo.omniture = {
	
// capture parent page omniture values.
	capture : function() {
	argos.widgets.quickinfo.omniture.pageName = s.pageName;
	argos.widgets.quickinfo.omniture.prop4 = s.prop4;
	argos.widgets.quickinfo.omniture.channel = s.channel;
	argos.widgets.quickinfo.omniture.prop7 = (s.prop7) ? s.prop7 : "";
	//console.debug("capture: \n" + s.prop4 + "\n" + s.channel + "\n" + s.prop7);
	},

// update omniture values for quickinfo.		
	update : function(el) {
    var pdpQuickviewGroup = $(el).parents(".pdpRelatedInformation").attr("id");    
    if(pdpQuickviewGroup){  
    	if(pdpQuickviewGroup =="pdpEssentialExtras"){
   			s.pageName = "ar:product:essentialextras:quickinfo:";
   		}else if (pdpQuickviewGroup =="pdpAdditionalItems"){
   			s.pageName = "ar:product:you:may:also:like:quickinfo:";
   		}else if(pdpQuickviewGroup =="pdpPromotions"){
   			s.pageName = "ar:product:specialoffers:quickinfo:";   		
   		}else if (pdpQuickviewGroup =="pdpAlternativeProducts"){
   			s.pageName = "ar:product:alternatives:quickinfo:";   		
   		}
	    s.prop4 = s.pageName;
    }else{
	s.prop4 = s.pageName + "quickinfo:";
    }
	s.channel = s.channel + "quickinfo:";
	//s.prop7 = s.prop7; not updating this now.
	//console.debug("update: \n" + s.prop4 + "\n" + s.channel + "\n" + s.prop7);
	},
	
// reset omniture quickinfo values back to parent page values.
	reset : function(el) {
	//Reset pageName here if quick view lightbox is launched on PDP
	var pdpQuickviewGroup = $(el).parents(".pdpRelatedInformation").attr("id");    
    if(pdpQuickviewGroup){  
    	s.pageName=argos.widgets.quickinfo.omniture.pageName;
    }
    //
	s.prop4 = argos.widgets.quickinfo.omniture.prop4;
	s.channel = argos.widgets.quickinfo.omniture.channel;
	s.prop7 = argos.widgets.quickinfo.omniture.prop7;
	//console.debug("reset: \n" + s.prop4 + "\n" + s.channel + "\n" + s.prop7);	
	},

// wrap the omniture send code so that we can nicely call it in our events.
	send : function() {
	// s_code and s are Global omniture variables.
	s.linkTrackVars="prop4,prop7";//removed space 
	s.tl(window, 'o', "QuickInfoClick");
	//console.debug("send: \n" + s_code);
}

};
//= END = Custom Omniture tagging ==============================================


$(document).ready(function(){
	// Initiate QuickInfo.

	// For some reason IE6 doesn't recognise the page unless they're in variable first.
	argos.widgets.quickinfo.approvedPages =['browselister','search','productdetails', 'offerdetails', 'reservationflow'];
	argos.widgets.quickinfo.init(argos.widgets.quickinfo.approvedPages);
	argos.widgets.quickinfo.omniture.capture();
});


