var FBSM=window.FBSM;
if(typeof FBSM=='undefined'){FBSM=new Object();FBSM.C=new Object();FBSM.PD=new Object();FBSM.U=new Object();FBSM.SC=new Object();FBSM.W=new Object();FBSM.WC=new Object();FBSM.F=new Object();FBSM.TFG=new Object();FBSM.R=new Object();}

$(document).ready(function (){
	$(".productFitmentSelect").click(function(){$(this).siblings('.productFitmentList').toggle();});
});

FBSM.PD.show_info = function(elemId){
	var elem = $('#' + elemId);
	if(elem && elem[0]) elem[0].click();
}
FBSM.PD.ShowLeftNavAsset = function(serviceUrl,assetTitle){
	try{
		FBSM.PD.PopulateAssetPopup(assetTitle, 'Loading...');
		$.ajax({
			type: "GET",
			url: serviceUrl,
			data: "assetTitle=" + assetTitle,
			dataType: "html",
			success: function(assetValue){ $('#leftNavAssetContent').html(assetValue); },
			error: function(http,msg,err){ throw new Error('Ajax failed.'); }
		});
		scroll(0,0);
	}catch(e){
		var url = (serviceUrl) ? serviceUrl : '';
		var title = (assetTitle) ? assetTitle : '';
		var sig = 'ShowLeftNavAsset(' + url + ',' + title + ')';
		FBSM.U.Log('error','Failed to show asset.',{ signature:sig, error:e });
	}
}
FBSM.PD.PopulateAssetPopup = function(assetTitle, assetValue){
	$('#leftNavAssetTitle').text(assetTitle);
	$('#leftNavAssetContent').html(assetValue);
	leftNavAssetPopup.Show();
}
// Generates a string representation of given object
FBSM.U.PrintObject = function(obj) {
	if(typeof obj == 'function') return '';
	if(typeof obj == 'string') return "'" + obj + "'";
	if(typeof obj == 'number' || typeof obj == 'boolean') return '' + obj;
	var print = '';
	if(obj){
		print += '{ ';
		var empty = true;
		for(var child in obj){
			empty = false;
			print += child + ':' + FBSM.U.PrintObject(obj[child]) + ', ';
		}
		if(!empty){
			var commaIndex = print.lastIndexOf(',');
			var newPrint = print.substring(0,commaIndex) + print.substring(commaIndex + 1,print.length);
			print = newPrint;
		}
		print += '}';
	}
	return print;
}
FBSM.U.GetType = function(x){
	// null
	if(x == null) return 'null';
	// try typeof
	var t = typeof x;
	if(t != 'object') return t;
	// try toString
	var c = Object.prototype.toString.apply(x);
	c = c.substring(8,c.length-1);
	if(c != 'Object') return c;
	// try generic
	if(x.constructor == Object) return c;
	// try user-defined
	if('classname' in x.constructor.prototype && typeof x.constructor.prototype.classname == 'string')
		return x.constructor.prototype.classname;
	return '<unknown type>';
}
// Populates given html structure with values
// structureId: DOM identifier of destination structure container
// fieldMap: maps elements with values (i.e., { id0:val1, id1:val1, ... }
FBSM.U.PopulateStructure = function(structureId, fieldMap){
	if(typeof fieldMap == 'object'){
		for(var id in fieldMap){
			var field = $('#'+containerId).find('#'+id);
			if(field) field.html(fieldMap[id]);
		}
	}
}
// Trims to last word end (and to nothing if no word end exists)
// parameters:
// src: string to trim
// return value: trimmed string
FBSM.U.TrimToWord = function(src,len){
	if(typeof src == 'string'){
		var source = src;
		if(len != null && len < source.length) source = src.substr(0,len);
		var lastSpace = source.lastIndexOf(' ');
		return (lastSpace >= 0) ? source.substring(0,lastSpace) : '';
	}
	else return src;
}
// Trims to last sentence end (and to nothing if no sentence end exists)
// parameters:
// src: string to trim
// return value: trimmed string
FBSM.U.TrimToSentence = function(src,len){
	if(typeof src == 'string'){
		var source = src;
		if(len != null && len < source.length) source = src.substr(0,len);
		var lastIndex = source.lastIndexOfAny('.?!');
		return (lastIndex >= 0) ? source.substring(0,lastIndex) : '';
	}
	else return src;
}
FBSM.U.GetFunctionName = function(theFunction){
	if(theFunction.name) return theFunction.name; 
	var definition = theFunction.toString();
	var name = definition.substring(definition.indexOf('function') + 8,definition.indexOf('('));
	if(name) return name;
	return "anonymous";
}
FBSM.U.GetSignature = function(theFunction){
	var signature = FBSM.U.GetFunctionName(theFunction);
	signature += "(";
	for(var x=0; x<theFunction.arguments.length; x++)	{
		var nextArgument = theFunction.arguments[x];
		if(nextArgument.length>30) nextArgument = nextArgument.substring(0, 30) + "...";
		signature += "'" + nextArgument + "'";
		if(x<theFunction.arguments.length - 1) signature += ", ";
	}
	signature += ")";
	return signature;
}
FBSM.U.StackTrace = function(leafFunction){
	var stackTraceMessage = "Stack trace: <br/>\n";
	var nextCaller = leafFunction;
	while(nextCaller) {
		stackTraceMessage += FBSM.U.GetSignature(nextCaller) + "<br>\n";
		nextCaller = nextCaller.caller;
	}
	stackTraceMessage += "<br>\n\n";
}
// Sends a one-way request; most cross browser-compatible implementation
FBSM.U.SendOneWayRequest = function(requestUrl){
	var handlerImage=new Image(1,1);
	var uniqueSignature = Math.random().toString().replace('.','');
	var uniqueParam = '&differ=' + escape(uniqueSignature);
	handlerImage.src=requestUrl + uniqueParam;
	handlerImage.onload=function() { FBSM.U.RequestImageOnloadHandler(); }
}
// Helper to FBSM.U.SendOneWayRequest
FBSM.U.RequestImageOnloadHandler = function(){ return; }
// Logs information to server
// parameters:
// type: the type of log, like 'error' or 'debug'
// message: string information to log
// context: object containing context of log call
FBSM.U.Log = function(type,message,context){
	var contextStr = FBSM.U.PrintObject(context);
	FBSM.U.SendOneWayRequest(loggingUrl + '?type=' + type + '&message=' + message + '&context=' + escape(contextStr));
}
// Creates a double-view of content, a trimmed and verbose
// parameters:
// element: jQuery of content container
// size: Trim size
// trim: trimming method (i.e., TrimToWord, TrimToSentence)
// return value: none
FBSM.U.GenerateTrimmedView = function(element,size,trim){
	// Determine if element qualifies for trimming
	var text = element.text();
	if(text.length > size){
		var content = element.html();
		// Build the 2 views
		var trimId = element[0].id + 'TrimView';
		var verboseId = element[0].id + 'VerboseView';
		element.html('<div id="' + trimId + '"></div><div id="' + verboseId + '"></div>');
		var trimView = $('#' + trimId);
		var verboseView = $('#' + verboseId);
		// Fill verbose view with less link
		var lessLink = '&nbsp;.&nbsp;.&nbsp;.<a href="#" onclick="$(\'#' + verboseId + '\').hide(); $(\'#' + trimId + '\').show(); return false;">[Back]</a>';
		verboseView.html(content + lessLink);
		// Generate trimmed view with more link
		// Fill trimmed view
		trimView.html(content);
		FBSM.U.TruncateHTML(trimView[0],size,trim);
		var moreLink = '&nbsp;.&nbsp;.&nbsp;.<a href="#" onclick="$(\'#' + trimId + '\').hide(); $(\'#' + verboseId + '\').show(); return false;">[More]</a>';
		trimView.append(moreLink);
		// Set view
		verboseView.hide();
		trimView.show();
	}
}
// Truncates html to given length. The truncation is based on length of rendered text, not markup.
// The assumption is that truncation has
// parameters:
// elem: element to truncate
// trimMethod: trimmer (i.e., TrimToWord, TrimToSentence,...)
// return value: none
FBSM.U.TruncateHTML = function(elem,len,trimMethod){
	if(elem && len >= 0){
		var text = $(elem).text();
		if(text.length > len){
			var trim = (trimMethod) ? trimMethod : function(src,len){ return src.substr(0,len); }
			FBSM.U._truncateHTML(elem,len,trim);
		}
	}
}
// [Helper Method] Truncates element to given length (by rendered length)
// parameters:
// elem: DOM element as target for truncation
// len: truncation point
// trim: trimmer method (i.e., TrimToWord, TrimToSentence,...)
// return value:
// assumptions:
// 1) elem is not null
// 2) len is nonnegative
// 3) truncation is warranted
FBSM.U._truncateHTML = function(node,len,trim){
	if(node.nodeType == 3){
		var text = node.nodeValue;
		if(text.length > len){
			node.nodeValue = trim(text,len);
			return { truncated:true, len:len };
		}else{
			return { truncated:false, len:text.length };
		}
	}else if(node.nodeType == 1){
		var truncated = false;
		var textLength = 0;
		if(node.hasChildNodes()){
			var toBeRemoved = [];
			for(var index = 0; index < node.childNodes.length; index++){
				if(truncated){
					toBeRemoved.push(node.childNodes[index]);
				}else{
					var truncResult = FBSM.U._truncateHTML(node.childNodes[index],len - textLength,trim);
					if(truncResult.truncated){
						truncated = true;
					}else{
						textLength += truncResult.len;
					}
				}
			}
			for(var i = 0; i < toBeRemoved.length; i++){
				node.removeChild(toBeRemoved[i]);
			}
		}
		return { truncated:truncated, len:textLength };
	}
}
// Attaches given unique value to the id's of all child elements of given element
// parameters:
// element: jquery element, focus of uniquefication
// unique: value to be attached to end of id's to create uniqueness
// inclusive: flag indicating whether to adjust target element id as well
FBSM.U.Uniquefy = function(element,unique,inclusive){
	element.find('*[id]').each(function(i){ $(this).attr('id',this.id + unique); });
	if(inclusive) element.attr('id',element[0].id + unique);
}
// Attaches given unique value to the end of the values of an id map
// parameters:
// idMap: associative array object whose values need to be uniquefied
// unique: value to be attached to end of values to create uniqueness
FBSM.U.UniquefyMap = function(idMap,unique){
	var uniquefied = {};
	if(idMap) for(var elem in idMap) uniquefied[elem] = idMap[elem] += unique;
	return uniquefied;
}
// Makes a popup container out of given element and assigns given html to element
FBSM.Popup = function(elem,html){
	try{
		this._visible = false;
		this._content = (typeof elem == 'string') ? $('#' + elem) : $(elem);
		this._initialize(html);
	}catch(e){
		throw new Error('Popup constructor failed. [elem: ' + elem + ', html: ' + html + ', inner: { name:' + e.name + ', message:' + e.message + ']');
	}
}
FBSM.Popup.prototype = {
	_initialize: function(html){
		if(this._content){
			this._content.wrap('<span style="position:relative;z-index:900;"></span>');
			this._content.css({ "position":"absolute","top":"10px","left":"10px" });
			if(html) this._content.html(html);
			this._content.hide();
		}
	},
	Show:function(){
		if(!this._visible){
			this._content.fadeIn(this.Speed);
			this._visible = true;
		}
	},
	Hide:function(){
		if(this._visible){
			this._content.fadeOut(this.Speed);
			this._visible = false;
		}
	},
	IsVisible:function(){
		return this._visible;
	},
	Toggle:function(){
		if(this._visible){
			this.Hide();
		}else{
			this.Show();
		}
	},
	Move:function(left,top){
		this._content.css({ left:left + 'px', top:top + 'px' });
	},
	MoveTo:function(elem,pos){
		if(elem && pos){
			if(this._content){
				var parentOffset = this._content.parent().offset();
				var elemOffset = elem.offset();
				var elemWidth = elem.width();
				var margin = 5;
				var left = elemOffset.left-parentOffset.left;
				var top = elemOffset.top-parentOffset.top;
				if(pos == 'right'){
					this.Move(left+elemWidth + margin,top);
				}else if(pos == 'left'){
					var width = this._content.width();
					this.Move(left-width - margin - 25,top);
				}else if(pos == 'center'){
					this.Move(0, top);
				}
			}
		}
	},
	Populate:function(mapper,map){
		if(mapper && 'Populate' in mapper) mapper.Populate(this._content[0].id,map);
	},
	Style:function(name,value){
		if(this._content) this._content.css(name,value);
	},
	Speed:'normal'
};
// Iterator wrapper around an array (cyclical)
FBSM.Iterator = function(array){
	this._array = null;
	this.Set(array);
};
FBSM.Iterator.prototype = {
	Set:function(array){
		if((array instanceof Array) || (a && typeof a == 'object' && 'length' in a)){
			this._array = array;
			this._index = -1;
		}else{
			throw new Error('FBSM.Iterator.Set(): Invalid argument.');
		}
	},
	// Gets next element in collection
	Next:function(){
		this._index = (this._index + 1) % this._array.length;
		return this._array[this._index];
	},
	// Gets the first element in collection
	First:function(){
		this._index = 0;
		return this._array[this._index];
	},
	// Gets current element in collection
	Current:function(){
		if(this._index == -1) this._index++;
		return this._array[this._currentIndex];
	}
}
// Facilitates the mapping of aggregate content into a complex structure
// idMap: { contentName0:elementId0, contentName1:elementName1, ... }
FBSM.Mapper = function(idMap){ this._idMap = idMap; }
FBSM.Mapper.prototype = {
	// Injects content into associated elements of given complex structure normalized against current id map state.
	Populate:function(containerId,contentMap){
		if(typeof containerId == 'string'){
			var container = $('#'+containerId);
			if(this._idMap && container && contentMap){
				for(var id in this._idMap){
					var target = '#'+this._idMap[id];
					var field = container.find(target);
					if(field && contentMap[id]){
						if(field[0] && field[0].nodeName && field[0].nodeName.toLowerCase() == 'input'){
							if('value' in field[0]) field[0].value = contentMap[id];
						}else{
							field.html(contentMap[id]);
						}
					}
				}
			}
		}else{
			throw new Error('FBSM.Mapper.Populate(): Cannot populate with given parameters.');
		}
	},
	// Registers an association to current id map.
	Add:function(elementId,contentName){
		if(elementId && typeof elementId == 'string' && contentName && typeof content == 'string'){
			this._idMap[elementId] = contentName;
		}else{
			throw new Error('FBSM.Mapper.Add(): Invalid id/name for addition.');
		}
	},
	// IdMap property
	SetIdMap:function(idMap){ this._idMap = idMap; }
};
// Content mapper with pre- and post- fill events (fading animation as default)
//  idMap: { contentName0:elementId0, contentName1:elementName1, ... }
//  OnPreFill: custom pre-population event handler
//  OnPostFill: custom post-polulation event handler
FBSM.AnimatedMapper = function(idMap){
	this._mapper = new FBSM.Mapper(idMap);
	this._container = null;
	this._contentMap = null;
};
FBSM.AnimatedMapper.prototype = {
	Populate:function(containerId,contentMap,doAnimation){
		if(typeof containerId == 'string'){
			this._container = $('#'+containerId);
			this._contentMap = contentMap;
			if(this._container && this._contentMap){
				if(doAnimation == false){
					this._mapper.Populate(containerId,contentMap);
				}else{
					this.OnPreFill();
				}
			}
		}else{
			throw new Error('FBSM.ContentMapper.Populate(): Cannot populate with given parameters.');
		}
	},
	OnPreFill:function(){
		if('fadeOut' in this._container){
			var mapper = this;
			this._container.fadeOut('fast', function(){ mapper._populate(); } );
		}
	},
	_populate:function(){
		this._mapper.Populate(this._container[0].id,this._contentMap);
		this.OnPostFill();
	},
	OnPostFill:function(){ if('fadeIn' in this._container) this._container.fadeIn('fast'); }
};
// Manages the sales view.
// sales: Iterator
// mapper: ContentMapper
// containerId: string
FBSM.SalesManager = function(sales, map, containerId){
	if(sales && map && typeof containerId == 'string'){
		this._sales = sales;
		this._map = map;
		this._containerId = containerId;
	}else{
		throw new Error('Invalid SalesManager constructor arguments.');
	}
}
FBSM.SalesManager.prototype = {
	ShowFirst: function(){ this._map.Populate(this._containerId,this._sales.First(),false); },
	ShowNext:function(containerID){ this._map.Populate(this._containerId,this._sales.Next()); }
};
// TabManager implements tabbing functionality
// Parameters:
// activeClass: css of active tab (jQuery-style)
// inactiveClass: css of inactive tab (jQuery-style)
// contentSelector: jquery xpath used in finding content elements (jQuery-style)
// tabSelector: jquery xpath used to find tab elements (jQuery-style)
// Constraints:
// 1) Number of content elements MUST equal number of tab elements
// 2) Content and tab selectors can be null during instantiation, but if so,
// Bind() must be called in order for manager to function effectively
FBSM.TabManager = function(activeCss,inactiveCss,contentSelector,tabSelector){
	this._activeCss = activeCss;
	this._inactiveCss = inactiveCss;
	this._contents = null;
	this._tabs = null;
	this._current = 0;
	this.Bind(contentSelector,tabSelector);
}
FBSM.TabManager.prototype = {
	Bind:function(contentSelector,tabSelector){
		var mgr = this;
		if(contentSelector && tabSelector){
			mgr._contents = [];
			mgr._tabs = [];
			$(contentSelector).each(function(i){ mgr._contents[i] = $(this); });
			$(tabSelector).each(function(i){
				mgr._tabs[i] = $(this);
				$(this).bind('click',function(){
					mgr._tabs[mgr._current].removeClass(mgr._activeCss);
					mgr._tabs[mgr._current].addClass(mgr._inactiveCss);
					mgr._contents[mgr._current].hide();
					$(this).removeClass(mgr._inactiveCss);
					$(this).addClass(mgr._activeCss);
					mgr._contents[i].show();
					mgr._current = i;
					//Do form start call here
					if($(this).html().toLowerCase().indexOf("request")!=-1) {
						FBSM.C.loadCustomJavascriptParameters("ecomm_request_quote_start","o");
					}
					if($(this).html().toLowerCase().indexOf("friend")!=-1) {
						FBSM.C.loadCustomJavascriptParameters("ecomm_send_to_friend_start","o");
					}
				});
			});
			for(var i=0; i<mgr._tabs.length; i++) {
				if(mgr._tabs[i][0].className==mgr._activeCss) {
					mgr._tabs[mgr._current].removeClass(mgr._activeCss);
					mgr._tabs[mgr._current].addClass(mgr._inactiveCss);
					mgr._contents[mgr._current].hide();
					mgr._tabs[i].removeClass(mgr._inactiveCss);
					mgr._tabs[i].addClass(mgr._activeCss);
					mgr._contents[i].show();
					mgr._current = i;
					//Do form start call here
					if(mgr._tabs[i].html().toLowerCase().indexOf("request")!=-1) {
						FBSM.C.loadCustomJavascriptParameters("ecomm_request_quote_start","o");
					}
					if(mgr._tabs[i].html().toLowerCase().indexOf("friend")!=-1) {
						FBSM.C.loadCustomJavascriptParameters("ecomm_send_to_friend_start","o");
					}
					break;
				}
			}
		}
	}
};
FBSM.PD.Form = function(formType,url,err,ty,main,form,itemIdField,asset,popup,countryURL, regionId, email, confEmail){
	this._formType = formType;
	this._url = url;
	this._err = err;
	this._ty = ty;
	this._main = main;
	this._form = form;
	this._item = itemIdField;
	this._asset = asset;
	this._popup = popup;
	this._countryUrl = countryURL;
	this._regionId = regionId;
	this._email = email;
	this._confEmail = confEmail;
}
FBSM.PD.Form.prototype = {
	ThankYou:function(){
		$(this._err).hide('fast');
		$(this._main).hide('fast');
		$(this._ty).show('normal');
		$(this._form)[0].reset();
	},
	ClearErrors:function(){ $(this._err).hide('fast'); },
	ToForm:function(){
		$(this._err).empty();
		$(this._err).hide('fast');
		$(this._ty).hide('fast');
		$(this._main).show('normal');
		if(this._popup) this._popup.Hide();
	},
	Hide:function(){ if(this._popup) this._popup.Hide(); },
	Show:function(){
		if(this._popup){
			$(this._form)[0].reset();
			$(this._err).empty();
			$(this._err).hide();
			$(this._ty).hide();
			$(this._main).show();
			this._popup.Show();
		}
	},
	CountrySelect:function(country){
		//use country to get new regions
		var form = this;
		var countryUrl = this._countryUrl;
		var regionId = this._regionId;
		$.ajax({
			type:'POST',
			url:countryUrl,
			data: "country_name=" + country,
			dataType: "html",
			success: function(res){
				var regionSelect = $(regionId);
				res = res.replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<string xmlns=\"http://50below.com/\">", "");
				res = res.replace("</string>", "");
				res = res.replace(/&gt;/g, ">");
				res = res.replace(/&lt;/g, "<");
				regionSelect.html(res);
				regionSelect[0].options[0].selected=true;
			},
			error:function(http,msg,err){ throw new Error('Ajax failed.'); }
		});
	},
	Submit:function(){
		var emailAddress = $(this._email);
		emailAddress = (emailAddress.length>0) ? emailAddress[0].value : null;
		var confEmailAddress = $(this._confEmail);
		confEmailAddress = (confEmailAddress.length>0) ? confEmailAddress[0].value : null;
		if(emailAddress==confEmailAddress) {
			var data = $(this._form).serialize();
			data += this._parse();
			this._submit(data);
		} else {
			alert("Email addresses do not match, please verify that they are correct and submit the form again.");
		}
	},
	_submit:function(data){
		var form = this;
		var serviceUrl = this._url;
		$.ajax({
			type:'POST',
			url:serviceUrl,
			data:data,
			dataType:'xml',
			success:function(xml){
				var response = $.xmlToJSON(xml);
				if(response){
					if(response.success == 'true' || xml.documentElement.getAttribute('success') == 'true'){
						if(response.isValid == 'false'){
							// Process validation failure
							form.OnValidationError(response);
						}else{
							// Process success
							form.OnSuccess(xml);
						}
					}else{
						// Process submission failure
						form.OnSubmitError(response);
					}
				}
			},
			error:form.OnAjaxError
		});
	},
	_parse:function(){
		var parsed = '';
		var itemId = null;
		var productData = null;
		var itemField = $(this._item)[0];
		
		if(itemField){
			itemId = itemField.value;
			productData = productDetailOptionList[itemId];
		}
		
		parsed += '&manufacturer=' + productDetails.productOwner;
		if(this._formType == 'ef'){
			var url = window.location.href;
			if(!url) url = document.URLUnencoded;
			parsed += '&productDetailUrl=' + escape(url);
			if(productData){
				parsed += '&itemId=' + itemId;
				if(productData.name!='') {
					parsed += '&itemName=' + encodeURIComponent(productData.name);
				} else {
					parsed += '&itemName=' + encodeURIComponent(productDetails.name);
				}
				parsed += '&partNumber=' + encodeURIComponent(productData.partNumber);
				parsed += '&model=' + encodeURIComponent(productData.description);
			}else{
				parsed += '&itemId=' + encodeURIComponent(productDetails.productId);
				parsed += '&itemName=' + encodeURIComponent(productDetails.name);
			}
		}else{
			if(productData){
				if(productData.name!='') {
					parsed += '&product=' + encodeURIComponent(productData.name);
				} else {
					parsed += '&product=' + encodeURIComponent(productDetails.name);
				}
				parsed += '&product=' + encodeURIComponent(productData.name);
				parsed += '&model=' + encodeURIComponent(productData.description);
				parsed += '&partNumber=' + encodeURIComponent(productData.partNumber);
				parsed += '&modelGroup=' + encodeURIComponent(productData.group);
			}
			else{
				parsed += '&product=' + encodeURIComponent(productDetails.name);
			}
		}
		return parsed;
	},
	OnSuccess:function(xml){
		if(xml){
			var asset = $(this._asset);
			if(asset && xml && xml.documentElement && xml.documentElement.hasChildNodes()){
				for(var i = 0; i < xml.documentElement.childNodes.length; i++) {
					var assetNode = xml.documentElement.childNodes[i];
					if(assetNode.nodeType == 3 && assetNode.nodeName == '#text' && assetNode.data.trim() != ""){
						asset.text(assetNode.data);
						break;
					}
					if(assetNode.nodeType == 1) {
						asset.text((assetNode.childNodes.length > 0) ? assetNode.firstChild.data : assetNode.data);
						break;
					}
				}
			}
			this.ThankYou();
			FBSM.C.loadCustomJavascriptParameters("form_submit","o");
		}else{
			throw new Error("Undefined ajax xml response.");
		}
	},
	OnValidationError:function(data){
		var errors = $(this._err);
		if(errors && errors[0]){
			errors.empty();
			var error = data.validationResults[0].validationError[0];
			errors.html('<div class="ecomm_systemMessageErrorTitle">' + error.name + '</div>' + '<div class="ecomm_systemMessageErrorText">' + error.errorMessage + '</div>');
			errors.css('color','#ff0000');
			errors.show('normal');
		}
	},
	OnSubmitError:function(response){
		var errors = $(this._err);
		if(errors && errors[0]){
			errors.empty();
			errors.html('<div class="ecomm_systemMessageErrorTitle">Processing Error</div>' + '<div class="ecomm_systemMessageErrorText">' + response.exception[0].message + '</div>');
			errors.css('color','#ff0000');
			errors.show('normal');
		}
	},
	OnAjaxError:function(obj,msg,err){
		throw new Error('AjaxError: httpObj=' + obj + ', msg=' + msg + ', err=' + err);
	}
};

FBSM.PD.toggleViewThumbs=function(showAll){
	$("#productImageThumbs").attr("class",((showAll) ? 'contactSheet' : 'scrolling'));
	$("#viewAll").toggleIf(!showAll);
	$("#hideAll").toggleIf(showAll);
}
FBSM.PD.show_full=function(image, imgsource){
	$('#LargeLink').attr("href",image);
	$('#Large').attr("src",image);
	$('#photoSource').html(imgsource);
}
FBSM.PD.show_fullImage=function(imagea, imagesrc, imgsource){
	$('#LargeLink').attr("href",imagea);
	$('#Large').attr("src",imagesrc);
	$('#photoSource').html(imgsource);
}


//------------------------------ Client-Code ---------------------------------------//
var requestServiceUrl;
var emailAFriendServiceUrl;
var loggingUrl;
var productDetails;
var productDetailTabManager;
var leftNavAssetPopup;
var productDetailOptionList;
var emailAFriendPopup;
var requestAQuotePopup;
var pdfm;
try{
	productDetailTabManager = new FBSM.TabManager('activeTab','');
	$(function(){
		// Left nav popup
		leftNavAssetPopup = new FBSM.Popup('leftnavAssetPopup');
		// Tabbing
		productDetailTabManager.Bind('.tabbedContent','#infoList li');
		// Tab content trunctation
		var n = $('.tabbedContent').size();
		$('.tabbedContent').each(function(i){
			// Process all but the last 2 content areas
			if(i < n - 2){
				FBSM.U.GenerateTrimmedView($(this),1000,FBSM.U.TrimToWord);
				return true;
			}
		});
		// Option Group Select
		$('#optionSelect').bind('change',function(){
			if(this.selectedIndex) window.location = this.options[this.selectedIndex].value;
		});
		// Buy Now
		$('.ecomm_addToCartButton').each(function(i){
			if(this.id.indexOf('itemAddToCart_') >= 0){
				$(this).click(function(){
					var optionId = this.id.replace('itemAddToCart_','');
					var qtyField = $('#itemQty_' + optionId);
					if(qtyField && qtyField[0] && qtyField[0].value == "") qtyField[0].value = '1';
					if(window.location.href.indexOf("&vxid=")>-1) {
						$(this).after("<input type=\"hidden\" name=\"vxid\" value=\"1\"/>");
					}
					this.form.submit();
				});
			} else if(this.id.indexOf('addToCart_') >= 0) {
				$(this).click(function(){
					var hasQuantity = false;
					$('.ecomm_productDetailOptionsQuantityTextField').each(function(){if(this.value!=""){hasQuantity = true; return false;}});
					if(!hasQuantity){alert("Please specify a quantity."); return false;}
				});
			}
		});
		// Form Popups
		emailAFriendPopup = new FBSM.Popup('ecms_sendToAFriendForm_pop');
		emailAFriendPopup.Speed = 'normal';
		emailAFriendPopup.Style("width","520px");
		emailAFriendPopup.Style("padding","10px");
		emailAFriendPopup.Style("border","solid 2px #000000");
		emailAFriendPopup.Style("background-color","#ffffff");
		requestAQuotePopup = new FBSM.Popup('ecms_requestQuoteForm_Pop');
		requestAQuotePopup.Speed = 'normal';
		requestAQuotePopup.Style("width","520px");
		requestAQuotePopup.Style("padding","10px");
		requestAQuotePopup.Style("border","solid 2px #000000");
		requestAQuotePopup.Style("background-color","#ffffff");
		pdfm = {
			ef:new FBSM.PD.Form('ef',emailAFriendServiceUrl,'#efErrorMsg','#efThankYouMsg','#ecms_sendToAFriendForm','#efForm','#efItemId',null,null,countrySelectUrl,null,null,null),
			rq:new FBSM.PD.Form('rq',requestServiceUrl,'#rqErrorMsg','#rqThankYouMsg','#ecms_requestQuoteForm','#rqForm','#rqItemId','#rqThankYouAsset',null,countrySelectUrl,'#defaultElements_rqSlctRegion','#defaultElements_rqTxtEmail','#defaultElements_rqTxtConfirmEmail'),
			efPop:new FBSM.PD.Form('ef',emailAFriendServiceUrl,'#efPopErrorMsg','#efPopThankYouMsg','#efPopFormContainer','#efPopupForm','#efPopupItemId',null,emailAFriendPopup,countrySelectUrl,null,null,null),
			rqPop:new FBSM.PD.Form('rq',requestServiceUrl,'#rqPopErrorMsg','#rqPopThankYouMsg','#rqPopFormContainer','#rqPopupForm','#rqPopupItemId','#rqPopThankYouAsset',requestAQuotePopup,countrySelectUrl,'#defaultElements_rqSlctPopRegion','#defaultElements_rqTxtPopEmail','#defaultElements_rqTxtPopConfirmEmail')
		};
		$('.singleProductGroup').find(':button').each(function(i){
			if(this.id && this.id.indexOf('itemRequestAQuote_') >= 0){
				$(this).click(function(){
					try{
						var productId = this.id.replace('itemRequestAQuote_','');
						var pdInfoIdMap = { id:'rqPopupItemId', group:'productHeader_modelGroup',description:'productHeader_model',partNumber:'productHeader_partNumber' };
						var mapper = new FBSM.Mapper(pdInfoIdMap);
						productId = ((productId<0) ? productId * -1 : productId);
						emailAFriendPopup.Hide();
						var tmpOptionList = productDetailOptionList[productId];
						tmpOptionList['description'] = tmpOptionList['description'].replace(/&lt;/gi, '<');
						tmpOptionList['description'] = tmpOptionList['description'].replace(/&gt;/gi, '>');
						tmpOptionList['description'] = tmpOptionList['description'].replace(/<[a-z\/][^>]*>/gi, '');
						if(tmpOptionList['description'].length > 27) tmpOptionList['description'] = tmpOptionList['description'].substring(0,27) + "...";
						if(tmpOptionList['group'].length > 27) tmpOptionList['group'] = tmpOptionList['group'].substring(0,27) + "...";
						requestAQuotePopup.Populate(mapper,tmpOptionList);
						requestAQuotePopup.MoveTo($(this),'center');
						pdfm.rqPop.Show();
						FBSM.C.loadCustomJavascriptParameters("ecomm_request_quote_start","o");
						$('#rqItemId')[0].value = productId;
						$('#rqPopupItemId')[0].value = productId;
						return false;
					}catch(e){
						var id = this.id;
						FBSM.U.Log('error','Error on click.',{ error:e, elemId:id });
						return false;
					}
				});
			}
		});
		$('.singleProductGroup a').each(function(i){
			if(this.id){
				if(this.id.indexOf('itemEmailAFriend_') >= 0){
					$(this).click(function(){
						try{
							var productId = this.id.replace('itemEmailAFriend_','');
							var pdInfoIdMap = { id:'efPopupItemId', group:'productHeader_modelGroup',description:'productHeader_model',partNumber:'productHeader_partNumber' };
							var mapper = new FBSM.Mapper(pdInfoIdMap);
							productId = ((productId<0) ? productId * -1 : productId);
							requestAQuotePopup.Hide();
							var tmpOptionList = productDetailOptionList[productId];
							tmpOptionList['description'] = tmpOptionList['description'].replace(/&lt;/gi, '<');
							tmpOptionList['description'] = tmpOptionList['description'].replace(/&gt;/gi, '>');
							tmpOptionList['description'] = tmpOptionList['description'].replace(/<[a-z\/][^>]*>/gi, '');
							if(tmpOptionList['description'].length > 27) tmpOptionList['description'] = tmpOptionList['description'].substring(0,27) + "...";
							if(tmpOptionList['group'].length > 27) tmpOptionList['group'] = tmpOptionList['group'].substring(0,27) + "...";
							emailAFriendPopup.Populate(mapper, tmpOptionList);
							emailAFriendPopup.MoveTo($(this),'center');
							pdfm.efPop.Show();
							FBSM.C.loadCustomJavascriptParameters("ecomm_send_to_friend_start","o");
							$('#efPopupItemId')[0].value = productId;
							$('#efItemId')[0].value = productId;
							return false;
						}catch(e){
							var id = this.id;
							FBSM.U.Log('error','Error on click.',{ error:e, elemId:id });
							return false;
						}
					});
				}else if(this.id.indexOf('contactUs_') >= 0){
					$(this).click(function(){
						try{
							var productId = this.id.replace('contactUs_','');
							var pdInfoIdMap = { id:'rqPopupItemId', group:'productHeader_modelGroup',description:'productHeader_model',partNumber:'productHeader_partNumber' };
							var mapper = new FBSM.Mapper(pdInfoIdMap);
							productId = ((productId<0) ? productId * -1 : productId);
							emailAFriendPopup.Hide();
							var tmpOptionList = productDetailOptionList[productId];
							tmpOptionList['description'] = tmpOptionList['description'].replace(/&lt;/gi, '<');
							tmpOptionList['description'] = tmpOptionList['description'].replace(/&gt;/gi, '>');
							tmpOptionList['description'] = tmpOptionList['description'].replace(/<[a-z\/][^>]*>/gi, '');
							if(tmpOptionList['description'].length > 27) tmpOptionList['description'] = tmpOptionList['description'].substring(0,27) + "...";
							if(tmpOptionList['group'].length > 27) tmpOptionList['group'] = tmpOptionList['group'].substring(0,27) + "...";
							requestAQuotePopup.Populate(mapper,tmpOptionList);
							requestAQuotePopup.MoveTo($(this),'center');
							pdfm.rqPop.Show();
							FBSM.C.loadCustomJavascriptParameters("ecomm_request_quote_start","o");
							$('#rqItemId')[0].value = productId;
							$('#rqPopupItemId')[0].value = productId;
							return false;
						}catch(e){
							var id = this.id;
							FBSM.U.Log('error','Error on click.',{ error:e, elemId:id });
							return false;
						}
					});
				}
			}
		});
	});
}catch(e){
	FBSM.U.Log('error','Error occurred during run client run-time script.',{ error:e });
}
/* Extend JQuery - XmlToJSON*/
if($){$.extend({xmlToJSON:function(h){try{if(!h){return null;}var i={};i.typeOf="JSXBObject";var j=(h.nodeType==9)?h.documentElement:h;if(h.nodeType==3||h.nodeType==4){return h.nodeValue;}function setObjects(a,b){var c;var d;var e;var f="";if(!b){return null;}if(!b.hasChildNodes()){return null;}var g=b.childNodes.length-1;if(b.attributes.length>0){setAttributes(a,b);}a._children=[];a.Text="";var n=0;do{d=b.childNodes[n];switch(d.nodeType){case 1:c=formatName(d.tagName);if(f!=c){a._children.push(c);}if(!a[c]){a[c]=[];}e={};a[c].push(e);if(d.attributes.length>0){setAttributes(e,d);}if(!a[c].contains){setHelpers(a[c]);}f=c;if(d.hasChildNodes()){setObjects(e,d);}break;case 3:a.Text+=$.trim(d.nodeValue);break;case 4:a.Text+=(d.text)?$.trim(d.text):$.trim(d.nodeValue);break;}}while(n++<g)};function setHelpers(g){g.getNodeByAttribute=function(a,b){if(this.length>0){var c;var d=this.length-1;try{do{c=this[d];if(c[a]==b){return c;}}while(d--)}catch(e){return false;}return false}};g.contains=function(a,b){if(this.length>0){var c=this.length-1;try{do{if(this[c][a]==b){return true;}}while(c--)}catch(e){return false;}return false;}};g.indexOf=function(a,b){var c=-1;if(this.length>0){var d=this.length-1;try{do{if(this[d][a]==b){c=d;}}while(d--)}catch(e){return-1;}return c;}};g.SortByAttribute=function(e,f){if(this.length){function getValue(a,b){var c=a[b];c=(k(c))?parseFloat(c):c;return c;}function sortFn(a,b){var c=0;var d,tB;d=getValue(a,e);tB=getValue(b,e);if(d<tB){c=-1;}else if(tB<d){c=1;}if(f){c=(f.toUpperCase()=="DESC")?(0-c):c;}return c;}this.sort(sortFn);}};g.SortByValue=function(e){if(this.length){function getValue(a){var b=a.Text;b=(k(b))?parseFloat(b):b;return b;}function sortFn(a,b){var c=0;var d,tB;d=getValue(a);tB=getValue(b);if(d<tB){c=-1;}else if(tB<d){c=1;}if(e){c=(e.toUpperCase()=="DESC")?(0-c):c;}return c;}this.sort(sortFn);}};g.SortByNode=function(e,f){if(this.length){function getValue(a,b){var c=a[b][0].Text;c=(k(c))?parseFloat(c):c;return c;}function sortFn(a,b){var c=0;var d,tB;d=getValue(a,e);tB=getValue(b,e);if(d<tB){c=-1;}else if(tB<d){c=1;}if(f){c=(f.toUpperCase()=="DESC")?(0-c):c;}return c;}this.sort(sortFn);}};};function setAttributes(b,c){if(c.attributes.length>0){var a=c.attributes.length-1;var d;b._attributes=[];do{d=String(formatName(c.attributes[a].name));b._attributes.push(d);b[d]=$.trim(c.attributes[a].value);}while(a--)}};function formatName(a){var b=/-/g;var c=String(a).replace(b,"_");return c;};var k=function(s){var a="";if(s&&typeof s=="string"){a=s;}var b=/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/;return b.test(a);};setObjects(i,j);h=null;j=null;return i;}catch(e){return null;}}});$.extend({textToXML:function(a){try{var b=($.browser.msie)?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser();b.async=false;}catch(e){throw new Error("XML Parser could not be instantiated");}var c;try{if($.browser.msie){c=(b.loadXML(a))?b:false;}else{c=b.parseFromString(a,"text/xml");}}catch(e){throw new Error("Error parsing XML string");}return c;}})}else{alert("jQuery library is not present");}