/* Minification failed. Returning unminified contents.
(16,8): run-time error CSS1031: Expected selector, found '='
(16,8): run-time error CSS1025: Expected comma or open brace, found '='
(18,13): run-time error CSS1031: Expected selector, found '='
(18,13): run-time error CSS1025: Expected comma or open brace, found '='
(34,34): run-time error CSS1031: Expected selector, found '='
(34,34): run-time error CSS1025: Expected comma or open brace, found '='
(42,32): run-time error CSS1031: Expected selector, found '='
(42,32): run-time error CSS1025: Expected comma or open brace, found '='
(50,36): run-time error CSS1031: Expected selector, found '='
(50,36): run-time error CSS1025: Expected comma or open brace, found '='
(61,46): run-time error CSS1031: Expected selector, found '='
(61,46): run-time error CSS1025: Expected comma or open brace, found '='
(71,44): run-time error CSS1031: Expected selector, found '='
(71,44): run-time error CSS1025: Expected comma or open brace, found '='
(95,42): run-time error CSS1031: Expected selector, found '='
(95,42): run-time error CSS1025: Expected comma or open brace, found '='
(111,40): run-time error CSS1031: Expected selector, found '='
(111,40): run-time error CSS1025: Expected comma or open brace, found '='
(136,38): run-time error CSS1031: Expected selector, found '='
(136,38): run-time error CSS1025: Expected comma or open brace, found '='
(157,18): run-time error CSS1031: Expected selector, found '='
(157,18): run-time error CSS1025: Expected comma or open brace, found '='
(243,8): run-time error CSS1031: Expected selector, found '='
(243,8): run-time error CSS1025: Expected comma or open brace, found '='
(245,13): run-time error CSS1031: Expected selector, found '='
(245,13): run-time error CSS1025: Expected comma or open brace, found '='
(276,44): run-time error CSS1031: Expected selector, found '='
(276,44): run-time error CSS1025: Expected comma or open brace, found '='
(290,36): run-time error CSS1031: Expected selector, found '='
(290,36): run-time error CSS1025: Expected comma or open brace, found '='
(302,35): run-time error CSS1031: Expected selector, found '='
(302,35): run-time error CSS1025: Expected comma or open brace, found '='
(309,45): run-time error CSS1031: Expected selector, found '='
(309,45): run-time error CSS1025: Expected comma or open brace, found '='
(341,48): run-time error CSS1031: Expected selector, found '='
(341,48): run-time error CSS1025: Expected comma or open brace, found '='
(360,47): run-time error CSS1031: Expected selector, found '='
(360,47): run-time error CSS1025: Expected comma or open brace, found '='
(370,46): run-time error CSS1031: Expected selector, found '='
(370,46): run-time error CSS1025: Expected comma or open brace, found '='
(439,49): run-time error CSS1031: Expected selector, found '='
(439,49): run-time error CSS1025: Expected comma or open brace, found '='
(456,45): run-time error CSS1031: Expected selector, found '='
(456,45): run-time error CSS1025: Expected comma or open brace, found '='
(485,47): run-time error CSS1031: Expected selector, found '='
(485,47): run-time error CSS1025: Expected comma or open brace, found '='
(523,19): run-time error CSS1031: Expected selector, found '='
(523,19): run-time error CSS1025: Expected comma or open brace, found '='
(535,14): run-time error CSS1031: Expected selector, found '='
(535,14): run-time error CSS1025: Expected comma or open brace, found '='
(546,1): run-time error CSS1019: Unexpected token, found '$'
(546,2): run-time error CSS1019: Unexpected token, found '('
(546,11): run-time error CSS1031: Expected selector, found ')'
(546,11): run-time error CSS1025: Expected comma or open brace, found ')'
(552,2): run-time error CSS1019: Unexpected token, found ')'
(556,14): run-time error CSS1031: Expected selector, found '='
(556,14): run-time error CSS1025: Expected comma or open brace, found '='
(558,17): run-time error CSS1031: Expected selector, found '='
(558,17): run-time error CSS1025: Expected comma or open brace, found '='
(593,52): run-time error CSS1031: Expected selector, found '='
(593,52): run-time error CSS1025: Expected comma or open brace, found '='
(630,46): run-time error CSS1031: Expected selector, found '='
(630,46): run-time error CSS1025: Expected comma or open brace, found '='
(676,45): run-time error CSS1031: Expected selector, found '='
(676,45): run-time error CSS1025: Expected comma or open brace, found '='
(731,41): run-time error CSS1031: Expected selector, found '='
(731,41): run-time error CSS1025: Expected comma or open brace, found '='
(753,49): run-time error CSS1031: Expected selector, found '='
(753,49): run-time error CSS1025: Expected comma or open brace, found '='
(778,39): run-time error CSS1031: Expected selector, found '='
(778,39): run-time error CSS1025: Expected comma or open brace, found '='
(792,41): run-time error CSS1031: Expected selector, found '='
(792,41): run-time error CSS1025: Expected comma or open brace, found '='
(806,39): run-time error CSS1031: Expected selector, found '='
(806,39): run-time error CSS1025: Expected comma or open brace, found '='
(822,50): run-time error CSS1031: Expected selector, found '='
(822,50): run-time error CSS1025: Expected comma or open brace, found '='
(845,49): run-time error CSS1031: Expected selector, found '='
(845,49): run-time error CSS1025: Expected comma or open brace, found '='
(901,45): run-time error CSS1031: Expected selector, found '='
(901,45): run-time error CSS1025: Expected comma or open brace, found '='
(939,46): run-time error CSS1031: Expected selector, found '='
(939,46): run-time error CSS1025: Expected comma or open brace, found '='
(967,37): run-time error CSS1031: Expected selector, found '='
(967,37): run-time error CSS1025: Expected comma or open brace, found '='
(986,45): run-time error CSS1031: Expected selector, found '='
(986,45): run-time error CSS1025: Expected comma or open brace, found '='
(1001,43): run-time error CSS1031: Expected selector, found '='
(1001,43): run-time error CSS1025: Expected comma or open brace, found '='
(1072,26): run-time error CSS1031: Expected selector, found '='
(1072,26): run-time error CSS1025: Expected comma or open brace, found '='
(1086,48): run-time error CSS1031: Expected selector, found '='
(1086,48): run-time error CSS1025: Expected comma or open brace, found '='
(1109,44): run-time error CSS1031: Expected selector, found '='
(1109,44): run-time error CSS1025: Expected comma or open brace, found '='
(1123,30): run-time error CSS1031: Expected selector, found '='
(1123,30): run-time error CSS1025: Expected comma or open brace, found '='
(1139,48): run-time error CSS1031: Expected selector, found '='
(1139,48): run-time error CSS1025: Expected comma or open brace, found '='
(1158,47): run-time error CSS1031: Expected selector, found '='
(1158,47): run-time error CSS1025: Expected comma or open brace, found '='
(1180,1): run-time error CSS1019: Unexpected token, found '$'
(1180,2): run-time error CSS1019: Unexpected token, found '('
(1180,11): run-time error CSS1031: Expected selector, found ')'
(1180,11): run-time error CSS1025: Expected comma or open brace, found ')'
(1182,2): run-time error CSS1019: Unexpected token, found ')'
(1185,14): run-time error CSS1031: Expected selector, found '='
(1185,14): run-time error CSS1025: Expected comma or open brace, found '='
(1187,17): run-time error CSS1031: Expected selector, found '='
(1187,17): run-time error CSS1025: Expected comma or open brace, found '='
(1199,64): run-time error CSS1031: Expected selector, found '='
(1199,64): run-time error CSS1025: Expected comma or open brace, found '='
(1243,55): run-time error CSS1031: Expected selector, found '='
(1243,55): run-time error CSS1025: Expected comma or open brace, found '='
(1251,42): run-time error CSS1031: Expected selector, found '='
(1251,42): run-time error CSS1025: Expected comma or open brace, found '='
(1262,51): run-time error CSS1031: Expected selector, found '='
(1262,51): run-time error CSS1025: Expected comma or open brace, found '='
(1276,45): run-time error CSS1031: Expected selector, found '='
(1276,45): run-time error CSS1025: Expected comma or open brace, found '='
(1322,48): run-time error CSS1031: Expected selector, found '='
(1322,48): run-time error CSS1025: Expected comma or open brace, found '='
(1523,45): run-time error CSS1031: Expected selector, found '='
(1523,45): run-time error CSS1025: Expected comma or open brace, found '='
(1585,49): run-time error CSS1031: Expected selector, found '='
(1585,49): run-time error CSS1025: Expected comma or open brace, found '='
(1595,45): run-time error CSS1031: Expected selector, found '='
(1595,45): run-time error CSS1025: Expected comma or open brace, found '='
(1599,54): run-time error CSS1031: Expected selector, found '='
(1599,54): run-time error CSS1025: Expected comma or open brace, found '='
(1613,67): run-time error CSS1031: Expected selector, found '='
(1613,67): run-time error CSS1025: Expected comma or open brace, found '='
(1626,49): run-time error CSS1031: Expected selector, found '='
(1626,49): run-time error CSS1025: Expected comma or open brace, found '='
(1647,69): run-time error CSS1031: Expected selector, found '='
(1647,69): run-time error CSS1025: Expected comma or open brace, found '='
(1664,75): run-time error CSS1031: Expected selector, found '='
(1664,75): run-time error CSS1025: Expected comma or open brace, found '='
(1819,65): run-time error CSS1031: Expected selector, found '='
(1819,65): run-time error CSS1025: Expected comma or open brace, found '='
(1918,58): run-time error CSS1031: Expected selector, found '='
(1918,58): run-time error CSS1025: Expected comma or open brace, found '='
(1935,51): run-time error CSS1031: Expected selector, found '='
(1935,51): run-time error CSS1025: Expected comma or open brace, found '='
(1966,75): run-time error CSS1031: Expected selector, found '='
(1966,75): run-time error CSS1025: Expected comma or open brace, found '='
(2064,11): run-time error CSS1031: Expected selector, found '='
(2064,11): run-time error CSS1025: Expected comma or open brace, found '='
(2066,17): run-time error CSS1031: Expected selector, found '='
(2066,17): run-time error CSS1025: Expected comma or open brace, found '='
(2109,51): run-time error CSS1031: Expected selector, found '='
(2109,51): run-time error CSS1025: Expected comma or open brace, found '='
(2126,52): run-time error CSS1031: Expected selector, found '='
(2126,52): run-time error CSS1025: Expected comma or open brace, found '='
(2144,41): run-time error CSS1031: Expected selector, found '='
(2144,41): run-time error CSS1025: Expected comma or open brace, found '='
(2151,41): run-time error CSS1031: Expected selector, found '='
(2151,41): run-time error CSS1025: Expected comma or open brace, found '='
(2158,53): run-time error CSS1031: Expected selector, found '='
(2158,53): run-time error CSS1025: Expected comma or open brace, found '='
(2164,52): run-time error CSS1031: Expected selector, found '='
(2164,52): run-time error CSS1025: Expected comma or open brace, found '='
(2172,1): run-time error CSS1019: Unexpected token, found '$'
(2172,2): run-time error CSS1019: Unexpected token, found '('
(2172,11): run-time error CSS1031: Expected selector, found ')'
(2172,11): run-time error CSS1025: Expected comma or open brace, found ')'
(2174,2): run-time error CSS1019: Unexpected token, found ')'
(2176,1): run-time error CSS1019: Unexpected token, found '$'
(2176,2): run-time error CSS1019: Unexpected token, found '('
(2176,9): run-time error CSS1031: Expected selector, found ')'
(2176,9): run-time error CSS1025: Expected comma or open brace, found ')'
(2185,2): run-time error CSS1019: Unexpected token, found ')'
(2199,14): run-time error CSS1031: Expected selector, found '='
(2199,14): run-time error CSS1025: Expected comma or open brace, found '='
(2201,23): run-time error CSS1031: Expected selector, found '='
(2201,23): run-time error CSS1025: Expected comma or open brace, found '='
(2220,62): run-time error CSS1031: Expected selector, found '='
(2220,62): run-time error CSS1025: Expected comma or open brace, found '='
(2251,51): run-time error CSS1031: Expected selector, found '='
(2251,51): run-time error CSS1025: Expected comma or open brace, found '='
(2287,44): run-time error CSS1031: Expected selector, found '='
(2287,44): run-time error CSS1025: Expected comma or open brace, found '='
(2346,43): run-time error CSS1031: Expected selector, found '='
(2346,43): run-time error CSS1025: Expected comma or open brace, found '='
(2593,1): run-time error CSS1019: Unexpected token, found '$'
(2593,2): run-time error CSS1019: Unexpected token, found '('
(2593,11): run-time error CSS1031: Expected selector, found ')'
(2593,11): run-time error CSS1025: Expected comma or open brace, found ')'
(2595,2): run-time error CSS1019: Unexpected token, found ')'
 */
/**
 *	File: 			\assets\js\tripplite.wishlist.js
 *	Created By: 	Francisco Carmona
 *	Created Date: 	05/03/2017
 *	Requirements:
 *	Description:	JavaScript file to handle wishlist items via local storage
 *
 * 	Change Log:
 * 	Developer			Date		Comments
 *  -------------------	----------	----------------------------------------------------------------------------------------------- *
 *	Francisco Carmona	10/10/17	Added keywords property to Wishlist.Item object
 *  Vic Wen             02/25/2020  Removed in favor of MyAccount.ListManager
 */

/* Create the tripplite wishlist name space ----------------------------------------------- */
var tl = namespace("tl");

tl.Wishlist = function(){ // JS class with constructor to handle wishlist class
	var objSelf = this;

    this.localStorageKey = "tl.wishlist";
	this.wishlistItems = {};
	this.itemNew = function(wishlistParams){ return tl.Wishlist.Item(wishlistParams); };

	// Get jQuery references to the key fields in our page.
	this.DOMRefs = {
		wishlist: $(".wishlist")
	};

    this.loadFromLocalStorage(); // Update with values from local storage
};


tl.Wishlist.prototype.deleteItem = function(itemId) {
	var objSelf = this;

	if (objSelf.wishlistItems.hasOwnProperty(itemId)) {
		delete objSelf.wishlistItems[itemId];
	}
};

tl.Wishlist.prototype.saveItem = function(objWishlistItem) {
	var objSelf = this;

	if (objWishlistItem.hasOwnProperty("itemId")) {
		objSelf.wishlistItems[objWishlistItem.itemId()] = objWishlistItem;
	}
};

tl.Wishlist.prototype.getItemCount = function() {
	var objSelf = this;
	var wishlistCount = 0;

	for(var itemId in objSelf.wishlistItems){
		wishlistCount += Number( objSelf.wishlistItems[itemId].quantity() );
	}

	return wishlistCount;
};

tl.Wishlist.prototype.deleteFromLocalStorage = function() {
	var objSelf = this;

	if( tl.utilities.supportsLocalStorage() ){
		if( localStorage.getItem( objSelf.localStorageKey ) ){
			localStorage.removeItem( objSelf.localStorageKey );
		}
	}
};

tl.Wishlist.prototype.loadFromLocalStorage = function() {
	var objSelf = this;

	if( window.localStorage.hasOwnProperty(objSelf.localStorageKey) ){
		var objWishlistItems = JSON.parse( window.localStorage[objSelf.localStorageKey] );

		for(var itemId in objWishlistItems){
			objSelf.saveItem(
				objSelf.itemNew({
					itemId		  : objWishlistItems[itemId].itemId,
					partNumber	  : objWishlistItems[itemId].partNumber,
					productNumber : objWishlistItems[itemId].productNumber,
					description	  : objWishlistItems[itemId].description,
					quantity	  : objWishlistItems[itemId].quantity,
					imageFile	  : objWishlistItems[itemId].imageFile,
					keywords	  : objWishlistItems[itemId].keywords,
					dateCreated	  : objWishlistItems[itemId].dateCreated,
					dateModified  : objWishlistItems[itemId].dateModified
				})
			);
		}
	}
};

tl.Wishlist.prototype.saveToLocalStorage = function() {
	var objSelf = this;

	if( tl.utilities.supportsLocalStorage() ){
		// Start with blank object
		var objWishlistItems = {};

		// Complex objects need to be serialized. Web storage takes simple key:value (string) pairs.
		for(var itemId in objSelf.wishlistItems){
			objWishlistItems[itemId] = objSelf.wishlistItems[itemId].memento();
		}

		window.localStorage[objSelf.localStorageKey] = JSON.stringify(objWishlistItems);
	}
};

tl.Wishlist.prototype.saveWishlistItem = function(elWishlistItem, objUtilities, msgConfirm) {
	var objSelf = this;
	var itemId = elWishlistItem.attr("data-itemId");
	var imageFile = elWishlistItem.attr("data-imageFile");
	var qty = objSelf.wishlistItems.hasOwnProperty(itemId)
		? parseInt(elWishlistItem.attr("data-quantity")) + parseInt(objSelf.wishlistItems[itemId].quantity())
		: parseInt(elWishlistItem.attr("data-quantity"));

	objSelf.saveItem(
		objSelf.itemNew({
			itemId: itemId,
			partNumber: elWishlistItem.attr("data-partNumber"),
			productNumber: elWishlistItem.attr("data-productNumber"),
			description: elWishlistItem.attr("data-description"),
			quantity: qty,
			imageFile: elWishlistItem.attr("data-imageFile"),
			keywords: elWishlistItem.attr("data-keywords")
		})
	);

	objSelf.saveToLocalStorage();

	elWishlistItem.parent().parent().find(".itemImage").find(".fav").addClass("selected");
};

tl.Wishlist.prototype.updateFavIcons = function() {
	var objSelf = this;
	var wishListItems = objSelf.wishlistItems;

	if (Object.keys(wishListItems).length)
	{
		for (var itemId in wishListItems) {
			var wishlistItem = wishListItems[itemId].memento();
			var divId = "#model_" + (wishlistItem.itemId);
			var favId = "#fav_" + (wishlistItem.itemId);

			$(divId).find(".itemImage").find(".fav").addClass("selected");
			$(favId).addClass("selected");
		}
	}
};

/********************************************************
WISHLIST ITEM FUNCTIONS
*********************************************************/
/* Wishlist Item constructor */
tl.Wishlist.Item = function(wishlistParams) {
	// Private Section
	var localStorageKey = "tl.wishlist";

	var _itemId        = wishlistParams.itemId             || "";
	var _partNumber    = wishlistParams.partNumber         || "";
	var _productNumber = wishlistParams.productNumber      || "";
	var _description   = wishlistParams.description        || "";
	var _imageFile     = wishlistParams.imageFile          || "";
	var _keywords      = wishlistParams.keywords           || "";
	var _quantity      = parseInt(wishlistParams.quantity) || 0;
	var _dateCreated   = wishlistParams.dateCreated        || new Date();
	var _dateModified  = wishlistParams.dateModified       || new Date();

	var _history = {
		itemId:        _itemId,
		partNumber:    _partNumber,
		productNumber: _productNumber,
		description:   _description,
		imageFile:     _imageFile,
		keywords:      _keywords,
		quantity:      _quantity,
		dateCreated:   _dateCreated,
		dateModified:  _dateModified
	};

	// Public Section
	return{
		// Functions are setter when values passed in, otherwise acts as getter
		itemId:        function(setVal) { return _itemId        = setVal           || _itemId;        },
		partNumber:    function(setVal) { return _partNumber    = setVal           || _partNumber;    },
		productNumber: function(setVal) { return _productNumber = setVal           || _productNumber; },
		description:   function(setVal) { return _description   = setVal           || _description;   },
		imageFile:     function(setVal) { return _imageFile     = setVal           || _imageFile;     },
		keywords:      function(setVal) { return _keywords      = setVal           || _keywords;      },
		quantity:      function(setVal) { return _quantity      = parseInt(setVal) || _quantity;      },
		dateCreated:   function(setVal) { return _dateCreated   = setVal           || _dateCreated;   },
		dateModified:  function(setVal) { return _dateModified  = setVal           || _dateModified;  },

		memento:      function(){ // Return objects private members instance
			return {
				itemId:        _itemId,
				partNumber:    _partNumber,
				productNumber: _productNumber,
				description:   _description,
				imageFile:     _imageFile,
				keywords:      _keywords,
				quantity:      _quantity,
				dateCreated:   _dateCreated,
				dateModified:  _dateModified
			};
		},

		getHistory: function(){
			return _history;
		},

		setHistory: function(objWishlistItem){
			var objItem = objWishlistItem || this.memento();

			_history.itemId        = objItem.itemId;
			_history.partNumber    = objItem.partNumber;
			_history.productNumber = objItem.productNumber;
			_history.description   = objItem.description;
			_history.imageFile     = objItem.imageFile;
			_history.keywords      = objItem.keywords;
			_history.quantity      = parseInt(objItem.quantity);
			_history.dateCreated   = objItem.dateCreated;
			_history.dateModified  = objItem.dateModified;
		},

		reset: function(objWishlistItem){ // Set internal wish list item to defaults
			var objItem = objWishlistItem || _history;

			this.itemId( objItem.itemId );
			this.partNumber( objItem.partNumber );
			this.productNumber( objItem.productNumber);
			this.description( objItem.description);
			this.imageFile( objItem.imageFile);
			this.keywords( objItem.keywords);
			this.quantity( objItem.quantity );
			this.dateCreated( objItem.dateCreated );
			this.dateModified( objItem.dateModified );
		}
	};
};
var tl = namespace("tl");

tl.Products = function(){
	this.DOMRefs = {
		msgCompareListEmpty: $("#msgCompareListEmpty"),
		compareListPanel: $("#compareListPanel"),
		compareListHead: $("#compareListHead"),
		compareListHide: $("#compareListHide"),
		compareListNow: $("#compareListNow"),
		compareListNowSticky: $(".compareListNowSticky"),
		compareListClear: $("#compareListClear"),
		modelList: $("#modelList"),
		pgid: $("#pgid"),
		productGroupID: $("#productGroupID"),
		rbAddToCompare: $("#rbAddToCompare"),
		rbAddedToCompare: $("#rbAddedToCompare"),
		rbCompare: $("#rbCompare"),
		rbMaxCompare: $("#rbMaxCompare"),
		rbSelectAtLeastTwo: $("#rbSelectAtLeastTwo")
	};

	this.storageKeys = {
		selectedModels: "tl.products.selectedModels"
	};

	// Update state of compare list panel
	this.updateCompareListState();

	// Attach Event Handlers
	this.attachCompareListEvents();
};

/* Determines if supplied model ID is selected */
tl.Products.prototype.inSelectedModelsList = function(modelId){
	var objSelf = this;

	if (window.localStorage.getItem(objSelf.storageKeys.selectedModels)){
		var selectedList = JSON.parse(window.localStorage.getItem(objSelf.storageKeys.selectedModels)) || [];

		if (objSelf.modelExists(selectedList, modelId)){
			return true;
		}
	}
	return false;
};

/* Determines if selectedModels list has space for another item */
tl.Products.prototype.listHasSpace = function(){
	var objSelf = this;
	var selectedList = JSON.parse(window.localStorage.getItem(objSelf.storageKeys.selectedModels)) || [];

	if (selectedList.length < 4){
		return true;
	}

	return false;
};

/* Determines if supplied model ID already exists in array */
tl.Products.prototype.modelExists = function(arr, modelId){
	return arr.some(function(el) {
		return el.modelId === modelId;
	});
};

/* Adds a supplied model ID to the selected models list */
tl.Products.prototype.selectedModelsListAdd = function(modelId, modelImage){
	var objSelf = this;
	var selectedList = JSON.parse(window.localStorage.getItem(objSelf.storageKeys.selectedModels)) || [];
	var modelImg = modelImage;

	if (typeof modelImg != "undefined" && modelImg){
		// Mostly valid image
	} else {
		modelImg = "//assets.tripplite.com/core-site-images/placeholder.png";
	}

	var compareObject = {
		"modelId": modelId,
		"modelImage": modelImg
	};

	if (selectedList.length < 5){
		if (!objSelf.modelExists(selectedList, modelId)){
			// Add compareObject to selectedList
			selectedList.push(compareObject);

			// Update local storage
			window.localStorage.setItem(objSelf.storageKeys.selectedModels, JSON.stringify(selectedList));
		}
	} else {
		alert( objSelf.DOMRefs.rbMaxCompare.val() );
	}

	objSelf.updateCompareListState();
};

/* Remove a supplied model id from the selected product list */
tl.Products.prototype.selectedModelsListRemove = function(modelId){
	var objSelf = this;
	var selectedList = JSON.parse(window.localStorage.getItem(objSelf.storageKeys.selectedModels)) || [];
	var indexModelID = selectedList.findIndex(function(x){
		return x.modelId === modelId;
	});

	if (indexModelID >= 0){
		// Remove model from selected models array
		selectedList.splice(indexModelID, 1);

		// Update local storage selected models list
		window.localStorage.setItem(objSelf.storageKeys.selectedModels, JSON.stringify(selectedList));

		objSelf.updateCompareListState();
	}
};

/* Clear all models from selected model list */
tl.Products.prototype.selectedModelsListClear = function(){
	var objSelf = this;
	if (window.localStorage.getItem(objSelf.storageKeys.selectedModels)){
		window.localStorage.removeItem(objSelf.storageKeys.selectedModels);
	}

	objSelf.updateCompareListState();
};

/* Update display state of compare list */
tl.Products.prototype.updateCompareListState = function(){
	var objSelf = this;
	var models = objSelf.selectedModelsListGet();
	var imgString = "";

	// Remove handlers
	$(".compareThumbnail").off("click");

	// Take the model list (models) and populate the appropriate image placeholder(s) (e.g., compareListImage01, compareListImage02, etc)
	if (models.modelCount){
		for (var i = 0; i < models.modelCount; i++){
			//
			var titleMsg = "click to remove " + models.modelIDs[i].modelId;
			var activeItem = "#compareListImage0" + i;

			// Update image
			$(activeItem).attr({
				"src": models.modelIDs[i].modelImage,
				"title": titleMsg,
				"alt": models.modelIDs[i].modelId
			});

			// Attach handlers
			var compareItemId = "#compareListImage0" + i;

			$(compareItemId).on("click", function(event){
				event.preventDefault();

				var modelId = $(this).attr("alt");
				var modelToRemove = "#model_" + modelId;

				// Remove from list
				objSelf.selectedModelsListRemove(modelId);

				// Update icons
				objSelf.DOMRefs.modelList.find(modelToRemove).find(".checkedIcon").css("visibility", "hidden");
				objSelf.DOMRefs.modelList.find(modelToRemove).find(".plusIcon").css("visibility", "visible");

				// Update text
				objSelf.DOMRefs.modelList.find(modelToRemove).find(".addToCompare").text( objSelf.DOMRefs.rbCompare.val() );
			});
		}

		// Add back any placeholder images if necessary
		if (models.modelCount < 4)
		{
			var loopLength = 4 - models.modelCount;
			var startFrom = models.modelCount;

			for (var j = 0; j < loopLength; j++){
				var activeItem = "#compareListImage0" + startFrom;

				$(activeItem).attr({
					"src": "//assets.tripplite.com/core-site-images/trans.gif",
					"title": "",
					"alt": ""
				});

				startFrom++;
			}
		}

		// Show compare list panel at bottom of browser window
		objSelf.DOMRefs.compareListPanel.show().animate({ bottom: "-20px" }, 300);
	} else {
		objSelf.DOMRefs.compareListPanel.show().animate({ bottom: "-200px" }, 300);
	}
};

tl.Products.prototype.selectedModelsListCompare = function(){
	var objSelf = this;
	var models = objSelf.selectedModelsListGet();

	if (!models.modelCount){
		// No selected or visible models in list.
		alert(objSelf.DOMRefs.msgCompareListEmpty.val());
	} else if (models.modelCount == 1){
		// Need at least two models
		alert(objSelf.DOMRefs.rbSelectAtLeastTwo.val());
	} else {
		// Avoid exceeding max url length
		window.location.href = "/products/products-compare/mids/" + models.modelList;
	}
};

/* Get count and IDs of selected models */
tl.Products.prototype.selectedModelsListGet = function(){
	var objSelf = this;
	var selectedModels = JSON.parse(window.localStorage.getItem(objSelf.storageKeys.selectedModels)) || [];
	var objSelectedModels = {
		modelCount: selectedModels.length,
		modelIDs: selectedModels,
		modelList: Array.prototype.map.call(selectedModels, function(item) { return item.modelId; }).join(",")
	};

	// Only update structure if we have models in local storage list
	if (selectedModels.length && Array.isArray(selectedModels)){
		// getCleanProductNumberMultiple() will return original value when no match found
		tl.utilities.getCleanProductNumberMultiple(selectedModels, function(returnValues){
			if (returnValues.length){
				var cleanProductNumbers = [];

				for (var key in returnValues){
					cleanProductNumbers.push(returnValues[key], returnValues[value]);
				}

				objSelectedModels.modelIDs = cleanProductNumbers.join(","); // Create a comma-delimited list of model IDs
			}
		});
	}

	return objSelectedModels;
};

/* Events associated with product compare list */
tl.Products.prototype.attachCompareListEvents = function(){
	var objSelf = this;

	// Open compare page
	objSelf.DOMRefs.compareListNow.click(function(event){
		event.preventDefault();
		objSelf.selectedModelsListCompare();
	});

	objSelf.DOMRefs.compareListNowSticky.click(function(event){
		event.preventDefault();
		objSelf.selectedModelsListCompare();
	});

	// Clear compare list
	objSelf.DOMRefs.compareListClear.click(function(event){
		event.preventDefault();
		objSelf.selectedModelsListClear();

		// Update icons
		objSelf.DOMRefs.modelList.find(".checkedIcon").css("visibility", "hidden");
		objSelf.DOMRefs.modelList.find(".plusIcon").css("visibility", "visible");

		// Update text
		objSelf.DOMRefs.modelList.find(".addToCompare").text( objSelf.DOMRefs.rbCompare.val() );

		window.localStorage.removeItem(objSelf.storageKeys.selectedModels);
		objSelf.DOMRefs.compareListPanel.show().animate({ bottom: "-200px" }, 300);
	});

	// Hide compare list
	objSelf.DOMRefs.compareListHide.click(function(event){
		event.preventDefault();
		objSelf.DOMRefs.compareListPanel.show().animate({ bottom: "-200px" }, 300);
	});
};

// Check Prices gtm function
tl.gtmCheckPrices = function(modelNumber, productLine){
	var mNum = modelNumber;
	var pLine = productLine;
	window.dataLayer = window.dataLayer || [];
	window.dataLayer.push({
		"event": "gtm.checkPrices.click",
		"modelNumber": mNum,
		"productLine": pLine
	});
};

// Buy Now gtm function
tl.gtmBuyNow = function(modelNumber, sellerName){
	var mNum = modelNumber;
	var sName = sellerName;
	window.dataLayer = window.dataLayer || [];
	window.dataLayer.push({
		"event": "gtm.buyNow.click",
		"modelNumber": mNum,
		"reseller": sName
	});
};

$(document).ready(function(){
	objProductSection = new tl.Products();
	$(".compareLink").on("click", function(e){
		e.preventDefault();
		objProductSection.selectedModelsListCompare();
	});
});
// jshint esversion: 2015
// jshint multistr:true

var products = namespace('tl.products');

products.MyList = function(){
	var objSelf = this;
	this.listItemNew = function(itemParams){ return new products.MyList.UserListItem(itemParams); };
	this.userListNew = function(listParams){ return new products.MyList.UserList(listParams);     };
	this.userLists = []; // All lists related to current web user (by webUserId)
	this.currentList = {};
	this.objWishlist = new tl.Wishlist();
	this.listItemsLimit = 250;
	this.isUserAuthenticated = false;

	// Get jQuery references to the key fields in our page.
	this.DOMRefs = {
		addListModal: $('#addListModal'),
		addListNameInput: $('#addListNameInput'),
		btnAddListName: $('#addListModal a.btn'),
		//btnNewList: $('.btnNewList'), // TOOD: Should be cleaned up (removed) after we refactor List Manager
		btnViewList: $('#view-list'),
		confirmAddToListModal: $('#confirmAddToListModal'),
		confirmAddToListModalListName: $('#confirmAddToListModalListName'),
		confirmAddToListModalMessage: $('#confirmAddToListModalMessage'),
		confirmAddToListModalPartNumber: $('#confirmAddToListModalPartNumber'),
		confirmAddToListModalPartNumberImage: $('#confirmAddToListModalPartNumberImage'),
		mainColumn: $('#main-column'),
		mid: $('#mid'),
		userLists: $('.user-lists')
	};

	// this.currentListId = parseInt( this.DOMRefs.currentListId.val() ) || 0;
	this.currentListId = 0;

	this.setUserListsFromDb();
	this.attachButtonEvents();
	this.attachModalEvents();
};

products.MyList.prototype.addLocalStorageFavorites = function(){
	var objSelf = this;
	var favoritesList = objSelf.getListByName("Favorites");

	// EXAMPLE: JS Promises Nesting
	// New favorites. If there is an existing "Favorites", we do nothing with local storage transfer
	if(favoritesList.id == 0){
		// Builds new JS List based on backend save results
		return objSelf.saveNewListByName("Favorites")
			.then(function(){
				// Check if we have local storage favs entries
				if( Object.keys(objSelf.objWishlist.wishlistItems).length ){
					var listItems = {};

					// Add all the items from local storage
					for(var itemId in objSelf.objWishlist.wishlistItems){
						var partNumber = objSelf.objWishlist.wishlistItems[itemId].partNumber();
						var qty = objSelf.objWishlist.wishlistItems[itemId].quantity() || 1;

						listItems[partNumber] = qty;
					}

					favoritesList = objSelf.getListByName("Favorites");

					objSelf.saveMultipleListItems(favoritesList.id, listItems);

					// Delete local storage entry
					objSelf.objWishlist.deleteFromLocalStorage();
				}
			});
	}

	return new Promise(function(resolve, reject){
		resolve(true);
	});
};

products.MyList.prototype.attachButtonEvents = function(){
	var objSelf = this;

	// TODO: Should be cleaned up (removed) after we refactor List Manager
	$(document).on('click', '.btnNewList', function(event){
		event.preventDefault();

		var caller = $(this);
		var userLists = caller.parents('ul').find('.user-lists');
		var partNumber = userLists.attr('data-partnumber');

		objSelf.DOMRefs.addListModal.find('.alert-message').remove(); // Remove existing messages
		objSelf.DOMRefs.addListNameInput.val('');
		objSelf.DOMRefs.btnAddListName.attr('data-partnumber', partNumber); // Save caller's part number
		objSelf.DOMRefs.btnAddListName.removeAttr('disabled');              // Enable Save button
	});

	objSelf.DOMRefs.mainColumn.on('click', '.btnAddItem', function(event){
		event.preventDefault();
		var addItemLink = $(this);

		var listId = addItemLink.attr('data-listId');
		var listName = addItemLink.text();
		var partNumber = addItemLink.parent().parent().attr("data-partNumber");
		var productNumber = addItemLink.parent().parent().attr("data-productNumber");
		var partNumberImage = addItemLink.parent().parent().attr("data-partNumberImage");
		var isDisabled = addItemLink.attr('disabled');

		if (typeof isDisabled !== typeof undefined && isDisabled !== false){ return; } // Avoid multi-clicks

		addItemLink.attr('disabled', 'disabled');

		// objSelf.DOMRefs.confirmAddToListModalListName.val(listName);
		// objSelf.DOMRefs.confirmAddToListModalPartNumber.val(productNumber);
		// objSelf.DOMRefs.confirmAddToListModalPartNumberImage.val(partNumberImage);

		$("#confirmAddToListModalListName").val(listName);
		$("#confirmAddToListModalPartNumber").val(productNumber);
		$("#confirmAddToListModalPartNumberImage").val(partNumberImage);
		objSelf.saveNewListItem(listId, partNumber, 1)
			.then(function(){
				addItemLink.removeAttr('disabled'); // Enable Save button
			});
	});
};

products.MyList.prototype.attachModalEvents = function(){
	var objSelf = this;

	// Add List Modal [Save] button click
	objSelf.DOMRefs.btnAddListName.on('click', function(event){
		event.preventDefault();

		var listName = objSelf.DOMRefs.addListNameInput.val();
		var partNumber = objSelf.DOMRefs.btnAddListName.attr('data-partnumber');
		var isDisabled = objSelf.DOMRefs.btnAddListName.attr('disabled');

		if (typeof isDisabled !== typeof undefined && isDisabled !== false){ return; } // Avoid multi-clicks

		objSelf.DOMRefs.btnAddListName.attr('disabled', 'disabled');
		objSelf.DOMRefs.addListModal.find('.alert-message').remove();

		objSelf.saveNewListByName(listName)
			.then(function(response){
				if(response.Success){
					var listByName = objSelf.getListByName(listName);
					var listId = listByName.id;
					var listOption = $('.user-lists[data-partnumber="'+partNumber+'"] .btnAddItem[data-listId="'+listId+'"]');

					// Trigger add current product to (new created) list
					if(listOption.length){
						objSelf.DOMRefs.addListModal.modal("hide");
						listOption.click();
					}
				}
				else{
					var errorMessage = $( objSelf.getMessageDiv("error", response.Message) ).css('margin', '10px 0px');
					objSelf.DOMRefs.addListModal.find('.modal-body').append( errorMessage );
				}
			});
	});

	// Perform every time Create New List Action Modal is closed
	objSelf.DOMRefs.addListModal.on("hidden.bs.modal", function (e) {
		// Reset values to blank
		objSelf.DOMRefs.addListModal.find('.alert-message').remove(); // Remove existing messages
		objSelf.DOMRefs.btnAddListName.attr("data-partnumber", "");
		objSelf.DOMRefs.btnAddListName.removeAttr('disabled');        // Enable Save button
	});

	// Add Items to List Modal [Save] button click
	/* objSelf.DOMRefs.btnAddItemsToList.on("click", function(event){
		event.preventDefault();
		var listId = objSelf.currentListId;
		var partNumber = objSelf.DOMRefs.addItemsToListInput.val();

		objSelf.DOMRefs.addItemsToListModal.find('.alert-message').remove(); // Remove existing messages
		objSelf.saveNewListItem(listId, partNumber);
	}); */
};

products.MyList.prototype.getMessageDiv = function(messageType, messageText){
	var objSelf = this;

	if (messageType === "error"){
		return '	<div class="row alert-message error-message">\
			    		<div class="alert alert-danger col-md-12">\
							<button type="button" class="close" data-dismiss="alert">&times;</button>\
				            <span class="size14">' + messageText + '</span>\
				        </div>\
				    </div>';
	}

	if (messageType === "success"){
		return '	<div class="row alert-message success-message">\
			    		<div class="alert alert-success col-md-12">\
							<button type="button" class="close" data-dismiss="alert">&times;</button>\
				            <span class="size14">' + messageText + '</span>\
				        </div>\
				    </div>';
	}
};

products.MyList.prototype.getUserAuthentication = function(){
	var objSelf = this;

	return new Promise(function(resolve, reject){
		resolve(
			$.ajax({
				url: "/api/main/isUserAuthenticated",
				contentType: "application/json; charset=utf-8",
				dataType: "json",
				success: function(response){
					objSelf.isUserAuthenticated = response.Success;
				},
				error: function(){
					console.log('error getting user authentication');
				},
				cache: false
			})
		);
		reject( new Error("fail") );
	});
};

/********************************************************
List Related Actions
********************************************************/
products.MyList.prototype.getListById = function(listId){
	var objSelf = this;

	if (listId <= 0 || objSelf.userLists.length <= 0){ return objSelf.userListNew(); }

	for (var i = objSelf.userLists.length - 1; i >= 0; i--) {
		var userList = objSelf.userLists[i];

		if (userList.id == listId){ return userList; }
	}

	return objSelf.userListNew();
};

products.MyList.prototype.getListByName = function(listName){
	var objSelf = this;

	if (listName == "" || objSelf.userLists.length <= 0){ return objSelf.userListNew(); }

	for (var i = objSelf.userLists.length - 1; i >= 0; i--) {
		var userList = objSelf.userLists[i];

		if (userList.name == listName){ return userList; }
	}

	return objSelf.userListNew();
};

products.MyList.prototype.getListItem = function(listId, partNumber){
	var objSelf = this;
	var userList = objSelf.getListById(listId);

	if (partNumber == null || partNumber == "" || userList.listItems.length <= 0){ return objSelf.listItemNew(); }

	for (var i = userList.listItems.length - 1; i >= 0; i--) {
		var listItem = userList.listItems[i];

		if (listItem.partNumber == partNumber){ return listItem; }
	}

	return objSelf.listItemNew();
};

/* Generate UserList object from config string or config object */
products.MyList.prototype.getUserListsFromConfig = function(userListsConfig){
	var objSelf = this;
	var userLists = []; // products.MyList.UserList[]
	var arrUserLists = userListsConfig || [];

	// Generate products.MyList.UserList entries
	for (var i = arrUserLists.length - 1; i >= 0; i--) {
		var userList = objSelf.userListNew( arrUserLists[i] );
		var userListItems = userList.listItems;

		// Overwrite simple object with specific products.MyList.UserListItem entry
		for (var j = userListItems.length - 1; j >= 0; j--) {
			userListItems[j] = objSelf.listItemNew( userListItems[j] );
		}

		// userList.sortListItems(); // Sort UserListItem objects by position value

		userLists.push( userList );
	}

	return userLists;
};

products.MyList.prototype.saveMultipleListItems = function(listId, items){
	var objSelf = this;
	var itemsData = {};
		itemsData[listId] = items;

	return new Promise(function(resolve, reject){
		resolve(
			// backend inserts new entry with DateTime.Now time stamps (for new entries. it increments qty for existing ones)
			$.ajax({
				url: "/api/myAccount/userListAddItems",
				contentType: "application/json; charset=utf-8",
				dataType: "json",
				method: "POST",
				data: JSON.stringify( itemsData ),
				success: function (response) {
					var messageType = response.Success ? "success" : "error";

					// We'll get a fully populated listItem back
					if (response.Success){
						var listById = objSelf.getListById(listId);
						var arrListItems = response.Data;

						for (var i = 0; i < arrListItems.length; i++) {
							// Create new front end list item
							var listItem = objSelf.listItemNew({
								listId:      arrListItems[i].listId,
								qty:         arrListItems[i].qty,
								partNumber:  arrListItems[i].partNumber,
								productName: arrListItems[i].productName,
								productUrl:  arrListItems[i].productUrl,
								pdfUrl:      arrListItems[i].pdfUrl,
								pgName:      arrListItems[i].pgName,
								sgName:      arrListItems[i].sgName,
								resellers:   objSelf.getResellersFromConfig(arrListItems[i].resellers),
								notes:       arrListItems[i].notes,
								required:    arrListItems[i].required,
								position:    arrListItems[i].position
							});

							// Append newly saved list item to local object
							listById.addListItem(listItem);
						}
					}
					else{
						alert(response.Message);
					}
				},
				error: function(exc){
					console.log(exc);
				}
			})
		);
		reject( new Error("fail") );
	});
};

products.MyList.prototype.saveNewListByName = function(listName){
	var objSelf = this;

	return new Promise(function(resolve, reject){
		resolve(
			$.ajax({
				url: "/api/myAccount/userListAddList",
				contentType: "application/json; charset=utf-8",
				dataType: "json",
				method: "POST",
				data: JSON.stringify(listName),
				success: function (response) {
					if (response.Success){
						// Insert new list into local userLists array
						var listEntry = objSelf.userListNew({
							id       : response.Data.Id,
							name     : response.Data.Name,
							isPrivate: response.Data.IsPrivate
						});

						objSelf.userLists.push(listEntry);    // Add to internal users' list array
						objSelf.uiAddNewListEntry(listEntry); // Build html list and insert at end of list
						// objSelf.DOMRefs.addListModal.modal("hide");
					}
					else{
						objSelf.DOMRefs.btnAddListName.removeAttr('disabled'); // Enable Save button
					}
				},
				error: function(exc){
					console.log(exc);
				},
				cache: false
			})
		);
		reject( new Error("fail") );
	});
};

products.MyList.prototype.setUserListsFromDb = function(){
	var objSelf = this;

	objSelf.getUserAuthentication()
		.then(function(){ 
			if(objSelf.isUserAuthenticated){ 
				$.ajax({
					url: "/api/myAccount/userListGetAllWithItems",
					contentType: "application/json; charset=utf-8",
					dataType: "json",
					success: function (response) {
						if (response.Success){
							objSelf.userLists = objSelf.getUserListsFromConfig( response.Data );
							objSelf.currentList = objSelf.getListById(objSelf.currentListId);
							objSelf.addLocalStorageFavorites();
							objSelf.generateListOfLists();
						}
					},
					error: function(exc){
						console.log(exc);
					},
					cache: false
				});
			}
		})
		.catch(function(error){ console.log(error); });
};

products.MyList.prototype.sortLists = function(userList){
	var objSelf = this;

	// Sort local list objects
	objSelf.userLists.sort(function(a, b){
		return a.name > b.name ? 1 : -1; // ascending
	});

	// Find "Favorites" array index
	var favIndex = objSelf.userLists.map(function(userList){ return userList.name; }).indexOf('Favorites');

	// Move favorites to top
	if(favIndex >= 0){
		var userListFav = objSelf.userLists.splice(favIndex, 1); // Returns array of item removed

		objSelf.userLists.splice(0, 0, userListFav[0]);          // Insert at start of array
	}
};

products.MyList.prototype.uiAddNewListEntry = function(userList){
	var objSelf = this;

	if (objSelf.userLists.length == 1){
		objSelf.DOMRefs.userLists.html('');
	}

	var list = '<li><a class="btnAddItem clickMe gtmAddItemToList" data-listId=' + userList.id + '>' + userList.name + '</a></li>';
	objSelf.DOMRefs.userLists.append(list);
};

/********************************************************
List Item Related Actions
********************************************************/
// TODO: Maybe call it saveListItem to make it more generic. We may use it to update changes to specific items
products.MyList.prototype.saveNewListItem = function(listId, partNumber, qty){
	var objSelf = this;

	return new Promise(function(resolve, reject){
		resolve(
			// backend inserts new entry with DateTime.Now time stamps (for new entries. it increments qty for existing ones)
			$.ajax({
				url: "/api/myAccount/userListAddItem",
				contentType: "application/json; charset=utf-8",
				dataType: "json",
				method: "POST",
				data: JSON.stringify({ listId: listId, partNumber: partNumber, qty: qty }),
				success: function (response) {
					var messageType = response.Success ? "success" : "error";

					// We'll get a fully populated listItem back
					if (response.Success){
						var listById = objSelf.getListById(listId);

						// Create new front end list item
						var listItem = objSelf.listItemNew({
							listId:      response.Data.listId,
							qty:         response.Data.qty,
							partNumber:  response.Data.partNumber,
							productName: response.Data.productName,
							productUrl:  response.Data.productUrl,
							pdfUrl:      response.Data.pdfUrl,
							pgName:      response.Data.pgName,
							sgName:      response.Data.sgName,
							notes:       response.Data.notes,
							required:    response.Data.required,
							position:    response.Data.ordinalSequence
						});

						// Append newly saved list item to local object
						listById.addListItem(listItem);

						// Update URL so View List will go to the correct list
						var viewListUrl = "/products/list-manager?listid=" + listId;
						// objSelf.DOMRefs.btnViewList.attr("href", viewListUrl);
						$("#view-list").attr("href", viewListUrl);

						// Build modal content
						var partNumber = $("#confirmAddToListModalPartNumber").val();
						var partNumberImage = $("#confirmAddToListModalPartNumberImage").val();

						var confirmationMessage = "<p>1 item added to <a href='" + viewListUrl + "'>" + $("#confirmAddToListModalListName").val() + "</a></p>";
						confirmationMessage += "<div class='media'><div class='media-object pull-left'><img class='m-Left10 m-Right10' src='" + partNumberImage + "' /></div><div class='media-body'><strong>" + partNumber + "</strong><p class='size14'>" + response.Data.productName + "</p></div></div>";

						$("#confirmAddToListModalMessage").html(confirmationMessage);

						// Trigger modal
						$("#confirmAddToListModal").modal("show");
					}
					else{
						alert(response.Message);
					}
				},
				error: function(exc){
					console.log(exc);
				}
			})
		);
		reject( new Error("fail") );
	});
};

/********************************************************
USER LIST CLASS FUNCTIONS
*********************************************************/
/* UserList constructor */
products.MyList.UserList = function(listParams){
	listParams = listParams || {};

	this.id        = listParams.id        || 0;
	this.name      = listParams.name      || "";
	this.notes     = listParams.notes     || "";
	this.isPrivate = listParams.isPrivate || false;
	this.itemCount = listParams.itemCount || 0;  // TODO: may do away with itemCount property, just get listItems.length
	this.listItems = listParams.listItems || []; // Array of UserListItem objects

	// Public Section
	return this;
};

products.MyList.UserList.prototype.addListItem = function(userListItem){
	var newItem = true;

	if (!(userListItem instanceof products.MyList.UserListItem)){ return; }

	// Replace any existing list item
	for (var i = this.listItems.length - 1; i >= 0; i--) {
		var listItem = this.listItems[i];

		if (listItem.partNumber == userListItem.partNumber){
			this.listItems[i] = userListItem;
			newItem = false;
			break; // loop break out b/c we've replaced existing item
		}
	}

	// Insert new list item
	if (newItem){
		this.listItems.push(userListItem);
		this.itemCount = this.listItems.length;
	}
};

products.MyList.UserList.prototype.memento = function(){
	return {
		id:        this.id,
		name:      this.name,
		notes:     this.notes,
		isPrivate: this.isPrivate,
		itemCount: this.itemCount,
		listItems: this.listItems
	};
};

/********************************************************
USER LIST ITEM CLASS FUNCTIONS
*********************************************************/
products.MyList.UserListItem = function(itemParams){
	itemParams = itemParams || {};

	this.listId      = itemParams.listId      || 0;
	this.partNumber  = itemParams.partNumber  || "";
	this.productName = itemParams.productName || "";
	this.productUrl  = itemParams.productUrl  || "";
	this.pdfUrl      = itemParams.pdfUrl      || "";
	this.pgName      = itemParams.pgName      || "";
	this.sgName      = itemParams.sgName      || "";
	this.notes       = itemParams.notes       || "";
	this.qty         = itemParams.qty         || 0;
	this.required    = itemParams.required    || false;
	this.position    = itemParams.position    || 0;
};

products.MyList.UserListItem.prototype.memento = function(){
	return {
		listId:      this.listId,
		partNumber:  this.partNumber,
		productName: this.productName,
		productUrl:  this.productUrl,
		pdfUrl:      this.pdfUrl,
		pgName:      this.pgName,
		sgName:      this.sgName,
		notes:       this.notes,
		qty:         this.qty,
		required:    this.required,
		position:    this.position
	};
};

/********************************************************
PRODUCT DETAIL RELATED ACTIONS
********************************************************/
products.MyList.prototype.generateListOfLists = function(){
	var objSelf = this;

	objSelf.sortLists(); // Sort before we generate list

	if (objSelf.userLists.length){
		$(document).find(".user-lists").empty();

		for (var j = 0; j < objSelf.userLists.length; j++){
			var list = '<li><a class="btnAddItem clickMe gtmAddItemToList" data-listId=' + objSelf.userLists[j].id + '>' + objSelf.userLists[j].name + '</a></li>';
			$(document).find(".user-lists").append(list);
		}
	} else {
		// TODO? Do we want to keep this code since it shoould theoretically never be executed in a perfect world?
		var noListsMsg = '<li><em>You have no custom lists created.</em></li>';
		$(document).find(".user-lists").append(noListsMsg);
	}
};

/********************************************************
READY SET GO
********************************************************/
$(document).ready(function(){
	myListPage = new products.MyList();
});
/* TODO: enable all datalayer references */

var products = namespace('tl.products');

products.Finder = function(){
	this.attributeOptions = {};
	this.modelAttributes = {};
	this.upsrbAttributes = {};
	this.runtimeModels = {};
	this.keywordSearchModels = {};
	this.mountFinderDeviceModels = {};
	this.replacementBatteryModels = {};
	this.subgroupModels = {};
	this.selectionsTracker = {};
}

products.Finder.prototype.addVirtualQuantityToAttributeOptions = function(){
	var qtyKey = "";

	// Working with outlets or ports?
	if( this.attributeOptions.hasOwnProperty(1525) ){
		qtyKey = "1525qty";
	}
	else if( this.attributeOptions.hasOwnProperty(2062) ){
		qtyKey = "2062qty";
	}
	else if( this.attributeOptions.hasOwnProperty(2046) ){
		qtyKey = "2046qty";
	}
	else if( this.attributeOptions.hasOwnProperty(2221) ){
		qtyKey = "2221qty";
	}

	// Get quantities. Only happens when source attribute (1525, 2062 or 2221) is present
	if( qtyKey !== "" ){
		// Holds all usable outlet qty values
		this.attributeOptions[qtyKey] = {};
		this.attributeOptions[qtyKey]["options"] = {};

		// Exception: Outlet types are allowed to be multi-select
		if( qtyKey === "1525qty" ){ this.attributeOptions[qtyKey]["filterStyleId"] = 7; }

		// Build virtual quantity attribute
		for(var modelID in this.modelAttributes){
			// Not all models will have XXXXqty attribute
			if( this.modelAttributes[modelID]["attributes"].hasOwnProperty(qtyKey) ){
				// Model attribute should have total qty value in property with same key name
				var qty = parseInt(this.modelAttributes[modelID]["attributes"][qtyKey]);
				// Assure modelAttributes has same (non-string) integer value
				this.modelAttributes[modelID]["attributes"][qtyKey] = qty;

				// Add virtual quantity attribute
				this.attributeOptions[qtyKey]["options"][qty] = {};
				this.attributeOptions[qtyKey]["options"][qty]["selectable"] = true;
				this.attributeOptions[qtyKey]["options"][qty]["selected"] = false;
			}
		}
	}
}

products.Finder.prototype.applyLazyLoadingGroupImages = function(){
	// Lazy load product images
	$("#products .item img.list-group-image").lazyload({
		threshold : 600,
		effect : "fadeIn"
	});
}

products.Finder.prototype.calcMaxRuntime = function(minRuntime){
	var maxRT = 0;
	var minRT = typeof(minRuntime) !== "undefined" ? minRuntime : 30;

	// When missing, calculate MAX Runtime based on MIN Runtime
	if (minRT < 10) { maxRt = 20;                    }
	else            { maxRt = Math.round(minRT * 2); }

	return maxRt;
}

products.Finder.prototype.dataLayerAddFilterClick = function(element){
	var objSelf = this;
	var element = element || undefined;
	var domElement = element === undefined ? $() : $(element);

	/*
	window.dataLayer = window.dataLayer || [];
	window.dataLayer.push({
		"event": "gtm.product.finder.filter.click",
		"product.finder.filter.value": domElement.val()
	});
	*/
}

products.Finder.prototype.findMatchInGroups = function(objParameters){
	var objParameters = objParameters || {};
	var groupOne      = objParameters.hasOwnProperty("groupOne")      ? objParameters.groupOne      : [];
	var groupTwo      = objParameters.hasOwnProperty("groupTwo")      ? objParameters.groupTwo      : [];
	var groupOneDelim = objParameters.hasOwnProperty("groupOneDelim") ? objParameters.groupOneDelim : ',';
	var groupTwoDelim = objParameters.hasOwnProperty("groupTwoDelim") ? objParameters.groupTwoDelim : ',';
	var arrGroupOne = [];
	var arrGroupTwo = [];
	var regExSpaces = new RegExp(groupOneDelim + '\\s+','g'); // RegEx for delimiter plus space EX: (list; of; items)

	switch( typeof(groupOne) ){
		case "object":
			if( groupOne.constructor === Array ){
				// Convert values in array to UPPER CASE for comparison
				arrGroupOne = groupOne.map(function(value){ return value.toUpperCase(); });
			}
		break;
		case "string": // Convert list into array with UPPER CASE values for comparison
			arrGroupOne = groupOne.toString().toUpperCase().replace(regExSpaces, groupOneDelim).split(groupOneDelim);
		break;
	}
	switch( typeof(groupTwo) ){
		case "object":
			if( groupTwo.constructor === Array ){
				// Convert values in array to UPPER CASE for comparison
				arrGroupTwo = groupTwo.map(function(value){ return value.toUpperCase(); });
			}
		break;
		case "string": // Convert list into array with UPPER CASE values for comparison
			arrGroupTwo = groupTwo.toString().toUpperCase().replace(regExSpaces, groupTwoDelim).split(groupTwoDelim);
		break;
	}

	// Compare the two array groups
	for(var i=0; i<=arrGroupOne.length; i++){
		// Found group one item somewhere in group two array
		if( arrGroupTwo.indexOf( arrGroupOne[i] ) !== -1 ){
			return true;
			break; // Break out of group one array loop
		}
	}

	// Geting this far means no matches found
	return false;
}

products.Finder.prototype.getModelsByAttribute = function(attrID){
	var arrModelsWithAttr = [];    // Array of models having attribute provided
	var arrModelsWithAttrVal = []; // Array of models having attribute and selected attribute values
	var arrConnectorA = [];
	var arrConnectorB = [];
	var arrSelectedMultiAndValues = [];
	var isAttrMultiAnd = [1525,1975].indexOf( parseInt(attrID) ) >= 0;

	// Start with array of models that contain the provided attribute (attrid)
	for(var modelID in this.modelAttributes){
		// Current Model - Attributes object
		var modelAttributes = this.modelAttributes[modelID]["attributes"];

		switch(attrID){
			case "1080": case "1085":  // SPECIAL: Handle connector attributes
				// Add Current Model if it has attribute 1080 or 1085
				if( modelAttributes.hasOwnProperty(1080) || modelAttributes.hasOwnProperty(1085) ){
					arrModelsWithAttr.push(modelID);
				}
			break;

			default:
				// Current Model - Does model have the selected attribute?
				if( modelAttributes.hasOwnProperty(attrID) ){
					arrModelsWithAttr.push(modelID);
				}
			break;
		}
	}

	// PRE-TASKS FOR SPECIAL CASES (ATTRIBUTES)
	switch(attrID){
		// Determine selected connectors for cables
		case "1080": case "1085":
			// Selected Connector A value
			if( this.attributeOptions.hasOwnProperty(1080) ){
				for( var attrValue in this.attributeOptions[1080]["options"] ){
					// Found our selected connector A option
					if( this.attributeOptions[1080]["options"][attrValue]["selected"] ){
						arrConnectorA.push( attrValue ); // Add to list of selected options for this connector
					}
				}
			}

			// Selected Connector B value
			if( this.attributeOptions.hasOwnProperty(1085) ){
				for( var attrValue in this.attributeOptions[1085]["options"] ){
					// Found our selected connector B option
					if( this.attributeOptions[1085]["options"][attrValue]["selected"] ){
						arrConnectorB.push( attrValue ); // Add to list of selected options for this connector
					}
				}
			}
		break;
		//  Determine selected multi-select (AND)
		case "1975": case "1525":
			var numAttrID = parseInt(attrID)

			for( var attrValue in this.attributeOptions[numAttrID]["options"] ){
				// This value is marked as selected for this attribute
				if( this.attributeOptions[numAttrID]["options"][attrValue]["selected"] ){
					arrSelectedMultiAndValues.push( attrValue ); // Collect all selected values
				}
			}
		break;
	}

	// Check every model against every selected attribute value
	for(var i=0; i<arrModelsWithAttr.length; i++){
		var currModelAttributes = this.modelAttributes[arrModelsWithAttr[i]]["attributes"];

		switch(attrID){
			case "1975": case "1525": // Models must have all selected multi-and values
				var keepModel = true; // Start with marking model as keeper
				var modelAttributeValue =  currModelAttributes[attrID];
				var arrModelAttributeValues = [];

				// Working with object (struct). Usually attribute 1525 (outlets)
				if( typeof(modelAttributeValue) === "object" ){
					//  Separate Object Keys into value array
					for(var key in modelAttributeValue){
						arrModelAttributeValues.push( key.toUpperCase() );
					}
				}
				// Some model attribute values contain ";" delimited list. Seperate them into array and trim value
				else{
					arrModelAttributeValues = modelAttributeValue.toString().toUpperCase().replace(/;\s+/g, ';').split(";");
				}

				// Loop through all selected multi-and option values
				for(var j=0; j<arrSelectedMultiAndValues.length; j++){
					var currMultiAndValue = arrSelectedMultiAndValues[j].toUpperCase();

					if( arrModelAttributeValues.indexOf( currMultiAndValue ) === -1 ){
						keepModel = false;
						continue;
					}
				}

				if( keepModel ){
					// Add to array of models being returned. Only add if not already in array.
					if( arrModelsWithAttrVal.indexOf( arrModelsWithAttr[i] ) < 0 ){
						// Model contains both attribute and selected attribute value
						arrModelsWithAttrVal.push(arrModelsWithAttr[i]);
					}
				}
			break;

			default:
				// Find selected values for specific attribute
				for( var attrVal in this.attributeOptions[attrID]["options"] ){

					// This value is marked as selected for this attribute
					if( this.attributeOptions[attrID]["options"][attrVal]["selected"] ){
						var keepModel = false; // At this point, start with disgarding this model

						switch(attrID){
							case "1080": case "1085":  // SPECIAL: Handle connector attributes
								var modelConnectorA = currModelAttributes.hasOwnProperty(1080) ? currModelAttributes[1080] : "";
								var modelConnectorB = currModelAttributes.hasOwnProperty(1085) ? currModelAttributes[1085] : "";
								// Some model attribute values contain ";" delimited list. Seperate them into array and trim value
								var arrModelConnectorA = modelConnectorA.toString().toUpperCase().replace(/;\s+/g, ';').split(";");
								var arrModelConnectorB = modelConnectorB.toString().toUpperCase().replace(/;\s+/g, ';').split(";");

								// Connector A and Connector B filters options have been selected
								if( arrConnectorA.length && arrConnectorB.length ){
									// Locate matches between end combinations
									var matchAA = this.findMatchInGroups({ groupOne : arrConnectorA, groupTwo : arrModelConnectorA });
									var matchAB = this.findMatchInGroups({ groupOne : arrConnectorA, groupTwo : arrModelConnectorB });
									var matchBA = this.findMatchInGroups({ groupOne : arrConnectorB, groupTwo : arrModelConnectorA });
									var matchBB = this.findMatchInGroups({ groupOne : arrConnectorB, groupTwo : arrModelConnectorB });

									// Only keep models that that have both connectors at either end
									if( matchAA && matchBB  || matchAB && matchBA ){ keepModel = true; }
								}else{
									// If either of the  model's connectors is a selected attribute value, keep it and move on to next model
									if( arrModelConnectorA.indexOf( attrVal.toUpperCase() ) !== -1 ||
										arrModelConnectorB.indexOf( attrVal.toUpperCase() ) !== -1 )
									{
										keepModel = true;
									}
								}
							break;

							case "1693": // SPECIAL: Remove (qty) before comparing for match
								var modelAttributeValue = currModelAttributes[attrID];

								// Some model attribute values contain ";" delimited list. Seperate them into array and trim value
								var arrModelAttributeValues = modelAttributeValue
									.toString()
									.toUpperCase()
									.replace(/(\s+)?\([0-9]\)(\s+)?/g, '')  // Remove (qty). EX: "(2) IEC-320 C14" => "IEC-320 C14"
									.replace(/;\s+/g, ';')
									.split(";");

								// If model has one of the selected attribute values, keep it and move on to next model
								if( arrModelAttributeValues.indexOf( attrVal.toUpperCase() ) !== -1 ){ keepModel = true; }
							break;

							default:
								var modelAttributeValue = currModelAttributes[attrID];

								// Working with object (struct). Usually attribute 1525 (outlets)
								if( typeof(modelAttributeValue) === "object" ){
									// If model has one of the selected attribute values, keep it and move on to next model
									if( modelAttributeValue.hasOwnProperty(attrVal) ){ keepModel = true; }
								}
								// Working with special features attribute (true/false - yes/no). Usually attributes 1247,1249,1251,1599
								else if( typeof(modelAttributeValue) === "boolean" ){
									// Models that have the selected special feature will have a true value
									if( modelAttributeValue ){ keepModel = true; }
								}
								// Working with simple value (usually string)
								else{
									// Some model attribute values contain ";" delimited list. Seperate them into array and trim value
									var arrModelAttributeValues = modelAttributeValue.toString().toUpperCase().replace(/;\s+/g, ';').split(";");

									// If model has one of the selected attribute values, keep it and move on to next model
									if( arrModelAttributeValues.indexOf( attrVal.toUpperCase() ) !== -1 ){ keepModel = true; }
								}
							break;
						}

						if( keepModel ){
							// Add to array of models being returned. Only add if not already in array.
							if( arrModelsWithAttrVal.indexOf( arrModelsWithAttr[i] ) < 0 ){
								// Model contains both attribute and selected attribute value
								arrModelsWithAttrVal.push(arrModelsWithAttr[i]);
							}
						}
					}
				}
			break;
		}
	}

	// Return only models with selected attribute values OR when we're working with multi-and attributes (model array will be empty when criteria not met)
	if( arrModelsWithAttrVal.length > 0 || isAttrMultiAnd ) { return arrModelsWithAttrVal; }
	else                                                    { return arrModelsWithAttr;    } // Return all models having attribute
}

products.Finder.prototype.getSortedModelIDs = function(sortProperty){
	var arrModelIDs = [];  // Array of model ids to return
	var arrObjModels = []; // Array of model objects to sort
	var arrObjModelsNoPrice = [] // Array of model object missing avg price
	var objModels = this.modelAttributes; // Local copy to work with

	// Create one list to sort and another to append to end of sorted list
	if(sortProperty == "avgPriceHigh" || sortProperty == "avgPriceLow"){
		for(var mid in this.modelAttributes ){
			var objModel = this.modelAttributes[mid];

			if(objModel.avgPrice == null){ arrObjModelsNoPrice.push( objModel ); }
			else                         { arrObjModels.push( objModel );        }
		}
	}
	// Normal array of model objects to sort
	else{
		for(var mid in this.modelAttributes ){
			arrObjModels.push( this.modelAttributes[mid] );
		}
	}

	// Sort local models object by selected property
	arrObjModels.sort(function(a, b){
		switch(sortProperty){
			default: 			 return a.modelID                > b.modelID                ? 1 : -1; break; // ascending
			case "modelNumber":  return a.modelNumber.toString() > b.modelNumber.toString() ? 1 : -1; break; // ascending
			case "avgRating":    return a.avgRating              < b.avgRating              ? 1 : -1; break; // descending
			case "popular":      return a.clickCount             < b.clickCount             ? 1 : -1; break; // descending
			case "rank":         return a.rank                   < b.rank                   ? 1 : -1; break; // descending
			case "avgPriceHigh": return a.avgPrice               < b.avgPrice               ? 1 : -1; break; // descending
			case "avgPriceLow":  return a.avgPrice               > b.avgPrice               ? 1 : -1; break; // ascending
			case "newest":       return new Date(a.publishDate)  < new Date(b.publishDate)  ? 1 : -1; break; // descending
			case "featured": 	 return a.featuredRank           < b.featuredRank           ? 1 : -1; break; // descending
			case /keyAttr-[0-9]+/.test(sortProperty) && sortProperty:
				var arrKeyAttr = sortProperty.split("-");
				var attrValueA = parseInt(a.attributes[ arrKeyAttr[1] ]) || a.attributes[ arrKeyAttr[1] ]; // try numeric, default to original value
				var attrValueB = parseInt(b.attributes[ arrKeyAttr[1] ]) || b.attributes[ arrKeyAttr[1] ]; // try numeric, default to original value

				if(arrKeyAttr.length == 3){
					switch(arrKeyAttr[2]){
						case "low" : return attrValueA > attrValueB ? 1 : -1; break; // ascending
						case "high": return attrValueA < attrValueB ? 1 : -1; break; // descending
					}
				}

				return attrValueA > attrValueB ? 1 : -1; break; // ascending
			break;
		}
	});

	// Create model ids array to return. Sequential loop ensures proper array access
	for(var i=0; i < arrObjModels.length; i++){ arrModelIDs.push(arrObjModels[i].modelID); }

	// Append model id for those models without avg price values
	if(sortProperty == "avgPriceHigh" || sortProperty == "avgPriceLow"){
		for(var i=0; i < arrObjModelsNoPrice.length; i++){ arrModelIDs.push(arrObjModelsNoPrice[i].modelID); }
	}

	return arrModelIDs;
}

products.Finder.prototype.getVisibleModelsCount = function(){
	var visibleModelCount = 0;
	for(var modelID in this.modelAttributes){
		if( this.modelAttributes[modelID]["display"] ){
			visibleModelCount ++;
		}
	}
	return visibleModelCount;
}

products.Finder.prototype.isPositiveInteger = function(n){
    return parseFloat(n) === n >>> 0;
}

products.Finder.prototype.hasAttributeOptionSelected = function(){
	for(var aid in this.attributeOptions){
		if( this.attributeOptions[aid].hasOwnProperty("options") ){
			for(var val in this.attributeOptions[aid]["options"]){
				if( this.attributeOptions[aid]["options"][val]["selected"] ){
					return true;
				}
			}
		}
	}

	return false;
}

products.Finder.prototype.resetAllModelDisplayAndAttributeOptions = function(){
	// Reset all models to visible
	for(var mid in this.modelAttributes){
	  this.modelAttributes[mid]["display"] = true;
	}
	// Reset all options to selectable
	for(var aid in this.attributeOptions){
		for(var val in this.attributeOptions[aid]["options"]){
			this.attributeOptions[aid]["options"][val]["selectable"] = true;
		}
	}
}

products.Finder.prototype.updateAttributeOption = function(attrID, attrVal, selected){
	if( typeof(attrID)   !== "undefined" &&
		typeof(attrVal)  !== "undefined" &&
		typeof(selected) !== "undefined" ){

		// Continue if attribute id exists in object
		if( this.attributeOptions.hasOwnProperty(attrID) ){
			// Continue if attribute value exists in object
			if( this.attributeOptions[attrID]["options"].hasOwnProperty(attrVal) ){
				// Update specific attribute value selectable ONLY when value is selected, just in case
				if(selected){ this.attributeOptions[attrID]["options"][attrVal]["selectable"] = true; }

				// Update specific attribute value as selected
				this.attributeOptions[attrID]["options"][attrVal]["selected"] = selected;

				this.updateSelectionsTracker(attrID, attrVal, selected); // Update internal selections tracker
			}
		}
	}
}

products.Finder.prototype.updateAttributeOptionsBySelectionsTracker = function(){
	// Only proceed when we have previously selected filter options
	if( Object.keys( this.selectionsTracker ).length ) {

		// Mark all matching attribute options as selected
		for( var attrID in this.selectionsTracker ){
			if( this.attributeOptions.hasOwnProperty(attrID) ){
				for( var attrVal in this.selectionsTracker[attrID] ){
					if( this.attributeOptions[attrID]["options"].hasOwnProperty(attrVal) ){
						this.attributeOptions[attrID]["options"][attrVal]["selected"] = true;
					}
				}
			}
		}
	}
}

products.Finder.prototype.updateAttributeOptionsByVisibleModelsAttributes = function(){
	var connectorA = "";
	var connectorB = "";

	// Mark selectable an attribute option when at least one model has it as an attribute
	for(var modelID in this.modelAttributes){
		var isModelDisplayed = this.modelAttributes[modelID]["display"] ? true : false;

		// Pull out attribute value for this model.
		for( var aid in this.modelAttributes[modelID]["attributes"] ){
			if( !this.attributeOptions.hasOwnProperty(aid) ){ continue; } // Skip for non matching attribute ids

			var modelAttributeValue = this.modelAttributes[modelID]["attributes"][aid];
			var isAttrMultiSelect = [7,17].indexOf(parseInt(this.attributeOptions[aid]["filterStyleId"])) >= 0 ? true : false;

			// Only proceed for displayed models or multi-select checkbox attributes
			if( isModelDisplayed ){
				// Working with object (struct). Usually attribute 1525 (outlets)
				if( typeof(modelAttributeValue) === "object" ){
					// Search for any model attribute values found in attribute options
					for( var attributeValue in modelAttributeValue ){
						// Some model attribute values are not present in attribute options
						if( this.attributeOptions[aid]["options"].hasOwnProperty(attributeValue) ){
							// Update specific attribute options as selectable
							this.attributeOptions[aid]["options"][attributeValue]["selectable"] = true;
						}
					}
				}
				// Working with special features attribute (true/false - yes/no). Usually attributes 1247,1249,1251,1599
				else if( typeof(modelAttributeValue) === "boolean" ){
					// Only special features attributes marked as true (applicable to the model)
					if( modelAttributeValue === true ){
						// Dynamically set the special feature attribute selectable.
						// We don't know the sttribute value at run time
						for( var attributeValue in this.attributeOptions[aid]["options"] ){
							this.attributeOptions[aid]["options"][attributeValue]["selectable"] = true;
						}
					}
				}
				// Working with simple value (usually string)
				else{
					// Some model attribute values contain ";" delimited list. Seperate them into array and trim value
					var arrModelAttributeValues = modelAttributeValue.toString().replace(/;\s+/g, ';').split(';');

					// Determine selected connectors for cables
					if( [1080,1085].indexOf( parseInt(aid) ) >= 0 ){
						// Selected Connector A value
						if( this.attributeOptions.hasOwnProperty(1080) ){
							for( var attrValue in this.attributeOptions[1080]["options"] ){
								// Found our selected connector A option
								if( this.attributeOptions[1080]["options"][attrValue]["selected"] ){
									connectorA = attrValue;
									break; // No need to continue looking
								}
							}
						}

						// Selected Connector B value
						if( this.attributeOptions.hasOwnProperty(1085) ){
							for( var attrValue in this.attributeOptions[1085]["options"] ){
								// Found our selected connector B option
								if( this.attributeOptions[1085]["options"][attrValue]["selected"] ){
									connectorB = attrValue;
									break; // No need to continue looking
								}
							}
						}
					}

					// Search for any model attribute values found in attribute options
					arrModelAttributeValues.forEach(function(attributeValue, index, array){
						switch(aid){
							// SPECIAL: Handle connector attributes
							case "1080": case "1085":
								// Connector A - Show usable connectors until a single connector end is selected
								if( this.attributeOptions.hasOwnProperty(1080) ){
									if( this.attributeOptions[1080]["options"].hasOwnProperty(attributeValue) ){
										if( connectorA.length ){
											// Only show selected connector option
											this.attributeOptions[1080]["options"][connectorA]["selectable"] = true;
										}else{
											// Show all usable connector options
											this.attributeOptions[1080]["options"][attributeValue]["selectable"] = true;
										}

										// Disable option from connector A if already selected in connector B
										if( connectorB.length && this.attributeOptions[1080]["options"].hasOwnProperty(connectorB) ){
											this.attributeOptions[1080]["options"][connectorB]["selectable"] = false;

											// Override for models with the same connector on both ends
											for(var mid in this.modelAttributes){
												if( this.modelAttributes[mid]["display"] ){
													if( this.modelAttributes[mid]["attributes"].hasOwnProperty(1080) &&
														this.modelAttributes[mid]["attributes"].hasOwnProperty(1085) &&
														this.modelAttributes[mid]["attributes"][1080] == connectorB &&
														this.modelAttributes[mid]["attributes"][1085] == connectorB )
													{
														this.attributeOptions[1080]["options"][connectorB]["selectable"] = true;
													}
												}
											}
										}
									}
								}

								// Connector B - Show usable connectors until a single connector end is selected
								if( this.attributeOptions.hasOwnProperty(1085) ){
									if( this.attributeOptions[1085]["options"].hasOwnProperty(attributeValue) ){
										if( connectorB.length ){
											// Only show selected connector option
											this.attributeOptions[1085]["options"][connectorB]["selectable"] = true;
										}else{
											// Show all usable connector options
											this.attributeOptions[1085]["options"][attributeValue]["selectable"] = true;
										}

										// Disable option from connector B if already selected in connector A
										if( connectorA.length && this.attributeOptions[1085]["options"].hasOwnProperty(connectorA) ){
											this.attributeOptions[1085]["options"][connectorA]["selectable"] = false;

											// Override for models with the same connector on both ends
											for(var mid in this.modelAttributes){
												if( this.modelAttributes[mid]["display"] ){
													if( this.modelAttributes[mid]["attributes"].hasOwnProperty(1080) &&
														this.modelAttributes[mid]["attributes"].hasOwnProperty(1085) &&
														this.modelAttributes[mid]["attributes"][1080] == connectorA &&
														this.modelAttributes[mid]["attributes"][1085] == connectorA )
													{
														this.attributeOptions[1085]["options"][connectorA]["selectable"] = true;
													}
												}
											}
										}
									}
								}
							break;
							// SPECIAL: Remove (qty) before comparing for match
							case "1693":
								attributeValue = attributeValue.replace(/(\s+)?\([0-9]\)(\s+)?/g, '');  // Remove (qty). EX: "(2) IEC-320 C14" => "IEC-320 C14"
								// NOTE: break; statement missing on purpose. Code will continue to default:
							default:
								// Some model attribute values are not present in attribute options
								if( this.attributeOptions[aid]["options"].hasOwnProperty(attributeValue) ){
									// Update specific attribute options as selectable
									this.attributeOptions[aid]["options"][attributeValue]["selectable"] = true;
								}
							break;
						}
					}, this);
				}
			}
		}
	}
}

products.Finder.prototype.updateModelDisplayByAttributesOptions = function(){
	var arrModelIDs = []; // Array of model ids
	var arrAllModels = []; // Array of all model ids
	var arrModelsByAttribute = [] // 2D array of model ids indexed by attribute

	// Add array of models meeting load-runtime requirements
	if( Object.keys( this.runtimeModels).length ){
		for(var rtModelID in this.runtimeModels){
			arrModelIDs.push(rtModelID);
		}
		// Add load-runtime model ids to 2D Array
		if( arrModelIDs.length){
			arrModelsByAttribute.push( arrModelIDs );
		}
	}

	// Add array of models meeting mount finder device requirements
	if( Object.keys( this.mountFinderDeviceModels).length ){
		// Add mount finder device model ids to 2D Array
		if( this.mountFinderDeviceModels.length){
			arrModelsByAttribute.push( this.mountFinderDeviceModels );
		}
	}

	// Add array of replacement batteries
	if( Object.keys( this.replacementBatteryModels).length ){
		// Add replacement battery model ids to 2D Array
		if( this.replacementBatteryModels.length){
			arrModelsByAttribute.push( this.replacementBatteryModels );
		}
	}

	// Add array of models by subgroup
	if( Object.keys( this.subgroupModels).length ){
		// Add subgroup device model ids to 2D Array
		if( this.subgroupModels.length){
			arrModelsByAttribute.push( this.subgroupModels );
		}
	}

	// Add array of models by keyword search results
	if( Object.keys( this.keywordSearchModels).length ){
		// Add keyword search result model ids to 2D Array
		if( this.keywordSearchModels.length){
			arrModelsByAttribute.push( this.keywordSearchModels );
		}
	}

	// Build array of all model ids
	for(var mid in this.modelAttributes){ arrAllModels.push(mid); }

	// Create 2D array of models based on current filter selections
	for(var attrID in this.attributeOptions){
		arrModelIDs = arrAllModels; // Start with using full list of model ids

		// Update array to use if any values are selected for current attribute
		for( var attrVal in this.attributeOptions[attrID]["options"] ){
			if( this.attributeOptions[attrID]["options"][attrVal]["selected"] ){
				// Use the trimmed list of model ids
				arrModelIDs = this.getModelsByAttribute( attrID );
				break; // Only need to find one option selected
			}
		}

		// Add models for this attribute to 2D Array
		arrModelsByAttribute.push( arrModelIDs );
	}

	// No attributes present to filter by
	if(!arrModelsByAttribute.length) return;

	// Create single array of models matching selected filters and their values
	var arrFilteredModels = arrModelsByAttribute.reduce(function(prevModelArray, currModelArray, index, array){
		// Create single model array from previous and current arrays where model ids are equal
		currModelArray = currModelArray.filter(function(modelID){
			// Couldn't find model id in prevModelArray
			if( prevModelArray.indexOf(modelID) === -1 ){
				// Remove this model id from currentModelArray
				return false;
			}
			// Keep this model id in currentModelArray
			return true;
		});

		// currModelArray will be the new "prevModelArray" in next iteration
		return currModelArray;
	});

	// Start with setting all models NOT visible
	for(var modelID in this.modelAttributes){
		this.modelAttributes[modelID]["display"] = false;
	}

	// Update display for those models that made it through the filtering process
	arrFilteredModels.forEach(function(modelID, index, array){
		this.modelAttributes[modelID]["display"] = true;
	}, this);
}

products.Finder.prototype.updateModelDisplayHavingPrices = function(){
	// Reduce visibility of model based on check prices availability - determined by list being populated
	if( this.modelsHavingPrices.length  ){
		// Loop through all models
		for(var mid in this.modelAttributes){
			// Only for those currently marked as visible
			if( this.modelAttributes[mid]["display"] ){
				// Check against list of models marked as having check prices
				if( this.modelsHavingPrices.indexOf(mid) === -1 ){
					// Turn off display for those models not having check prices
					this.modelAttributes[mid]["display"] = false;
				}
			}
		}
	}
}

products.Finder.prototype.updateSelectionsTracker = function(attrID, attrVal, selected){
	if( typeof(attrID)   !== "undefined" &&
		typeof(attrVal)  !== "undefined" &&
		typeof(selected) !== "undefined" ){

		// Add Selected Attribute Option
		if( selected ){
			// Add attribute when missing
			if( !this.selectionsTracker.hasOwnProperty(attrID) ){
				this.selectionsTracker[attrID] = {};
			}

			this.selectionsTracker[attrID][attrVal] = {};
		}
		// Remove Selected Attribute Option
		else{
			if( this.selectionsTracker.hasOwnProperty(attrID) ){
				// Remove attribute selected option
				if( this.selectionsTracker[attrID].hasOwnProperty(attrVal) ){
					delete this.selectionsTracker[attrID][attrVal];
				}

				// Remove attribute when it contains no options
				if( Object.keys( this.selectionsTracker[attrID] ).length === 0 ){
					delete this.selectionsTracker[attrID];
				}
			}
		}
	}
}

products.Finder.prototype.UPSRB_updateModelDisplayAndSelectableAttributes = function(){
	var battModelID, battUPSManufacturer, battUPSModelNumber, currBattID;
	var brand = "";
	var upsModel = "";
	var version = "";
	var arrBattBrand = [];
	var arrBattUPSModel = [];
	var arrBattVersion = [];
	var arrBattKeywords = [];
	var arrBatteriesByAttribute = [];
	var kwModels = (Object.keys(this.keywordSearchModels).length && this.keywordSearchModels.length) ? this.keywordSearchModels : [];

	// Determine selected options
	for(var aid in this.attributeOptions){
		for(var attrVal in this.attributeOptions[aid]["options"] ){
			if( this.attributeOptions[aid]["options"][attrVal]["selected"] ){
				switch( parseInt(aid) ){
					case 9000: brand    = attrVal; break;
					case 9001: upsModel = attrVal; break;
					case 9002: version  = attrVal; break;
				}
				break; // Only care about one option selected
			}
		}
	}
	// Create arrays of batter ids based on current filter selections
	for(var battID in this.upsrbAttributes){
		// Pull out current battery value for each selectable attribute option
		battModelID = this.upsrbAttributes[battID]["MODEL_ID"];
		battUPSManufacturer = this.upsrbAttributes[battID]["UPS_MANUFACTURER"];
		battUPSModelNumber = this.upsrbAttributes[battID]["UPS_MODEL_NUMBER"];
		battVersion = this.upsrbAttributes[battID]["VERSION"];
		// Populate respective arrays of battery ids matching selections
		if( brand.length    > 0 && brand === battUPSManufacturer      ){ arrBattBrand.push(battID);    }
        if( upsModel.length > 0 && upsModel === battUPSModelNumber    ){ arrBattUPSModel.push(battID); }
        if( version.length  > 0 && version === battVersion            ){ arrBattVersion.push(battID);  }
        if( kwModels.length > 0 && kwModels.indexOf(battModelID) > -1 ){ arrBattKeywords.push(battID); }
	}	
	// Add battery ids to 2D Array
	if( arrBattBrand.length    > 0 ){ arrBatteriesByAttribute.push( arrBattBrand );    }
	if( arrBattUPSModel.length > 0 ){ arrBatteriesByAttribute.push( arrBattUPSModel ); }
	if( arrBattVersion.length  > 0 ){ arrBatteriesByAttribute.push( arrBattVersion );  }
	if( arrBattKeywords.length > 0 ){ arrBatteriesByAttribute.push( arrBattKeywords ); }

	// Need at least one set of matching selected options
	if( arrBatteriesByAttribute.length ){
		// Create single array of battery ids matching selected filters and their values
		var arrFilteredBattIDs = arrBatteriesByAttribute.reduce(function(prevBattArray, currBattArray, index, array){
			// Create single battery array from previous and current arrays where battery ids are equal
			currBattArray = currBattArray.filter(function(battID){
				// Couldn't find battery id in prevBattArray
				if( prevBattArray.indexOf(battID) === -1 ){
					// Remove this battery id from currentBattArray
					return false;
				}
				// Keep this battery id in currentBattArray
				return true;
			});
			// currBattArray will be the new "prevBattArray" in next iteration
			return currBattArray;
		});
		// Start with setting all models NOT visible
		for(var mid in this.modelAttributes){
		  this.modelAttributes[mid]["display"] = false;
		}
		// Start with setting all options NOT selectable
		for(var aid in this.attributeOptions){
			for(var val in this.attributeOptions[aid]["options"]){
				this.attributeOptions[aid]["options"][val]["selectable"] = false;
			}
		}
		for(var i=0, arrLength=arrFilteredBattIDs.length; i < arrLength; i++){
			currBattery = this.upsrbAttributes[ arrFilteredBattIDs[i] ];
			battModelID         = currBattery["MODEL_ID"];
			battUPSManufacturer = currBattery["UPS_MANUFACTURER"];
			battUPSModelNumber  = currBattery["UPS_MODEL_NUMBER"];
			battVersion         = currBattery["VERSION"];
			// Turn on display for matching models
			if( this.modelAttributes.hasOwnProperty(battModelID) ){
		  		this.modelAttributes[battModelID]["display"] = true;
			}
			// Turn on selectable for matching models' attibutes
			if( this.attributeOptions[9000]["options"].hasOwnProperty(battUPSManufacturer) ){
				this.attributeOptions[9000]["options"][battUPSManufacturer]["selectable"] = true;
			}
			if( this.attributeOptions[9001]["options"].hasOwnProperty(battUPSModelNumber) ){
				this.attributeOptions[9001]["options"][battUPSModelNumber]["selectable"] = true;
			}
			if( this.attributeOptions[9002]["options"].hasOwnProperty(battVersion) ){
				this.attributeOptions[9002]["options"][battVersion]["selectable"] = true;
			}
		}
	}
	else{
		this.resetAllModelDisplayAndAttributeOptions();
	}
}
/* Create the Product Section name space ----------------------------------------------- */
var pages = namespace('tl.pages');

pages.Solutions = function(){ // JS class with constructor to handle the new products page.
	var objSelf = this;

	this.objProduct = objProductSection; // Parent tl.product class
	this.objFinder = new products.Finder();
	this.objVisitor = new tl.Visitor();
	this.objVisitorPrefs = this.objVisitor.preferences;
	this.urlPrefix = window.location.protocol + '//' + window.location.host;

	this.loading = '<div class="displayInlineBlock">' + tl.ajxLoading + '</div>';

	// Get jQuery references to the key fields in our page.
	this.DOMRefs = {
		cusTrigger: $("#cus-trigger"),
		productGroupName: $("#productGroupName"),
		productGroupID: $("#productGroupID"),
		sesGroupName: $("#sesGroupName"),
		matchCount: $("#matchCount"),
		listViewStyle: $("#listViewStyle"),
		listSort: $("#listSort"),
		sort: $("#sort"),
		view: $("#view"),
		sortByMenu: $("#sortByMenu"),
		styleID: $("#styleID"),
		grid: $("#grid"),
		list: $("#list"),
		listCondensed: $("#listCondensed"),
		modelList: $("#modelList"),
		productsItem: $("#modelList .item"),
		helpIcon: $(".icoHelp"),
		products: $("#products"),
		productList: $("#productList"),
		listLoading: $("#listLoading"),
		tags: $("#listTools .tag"),
		selectModel: $(".selectModel")
	};

	this.applyVisitorPreferences();
	this.attachDisplaySwitchEvents();			// Display style switcher
	this.attachToolsButtonsEvents();
	this.updateVisitorPreferences();
};

pages.Solutions.prototype.applyVisitorPreferences = function(){
	var objSelf = this;
	var visitorPrefs = objSelf.objVisitorPrefs.memento();
	var displayStyle = visitorPrefs.solutionsPage.displayStyle || undefined;
	var sortByValue = visitorPrefs.solutionsPage.sortBy || undefined;
	var isIE11 = /Trident.*rv[ :]*11\./.test(navigator.userAgent);

	if (isIE11)
	{
		objSelf.applyViewList();
	}
	else
	{
		objSelf.applyViewGrid();
	}
};

pages.Solutions.prototype.updateVisitorPreferences = function(){
	var objSelf = this, displayStyle;
	var visitorPrefs = objSelf.objVisitorPrefs.memento();
	var displayStyleID = "";

	var sortBy = objSelf.DOMRefs.sortByMenu.val() || undefined;

	// Apply model list sorting
	if( sortBy !== undefined ){
		if( sortBy !== visitorPrefs.solutionsPage.sortBy ){
			objSelf.objVisitorPrefs.solutionsPage.sortBy( sortBy );

			// Save changes to local web storage
			objSelf.objVisitorPrefs.saveToLocalStorage();
		}
	}
};

pages.Solutions.prototype.applyViewList = function(){
	var objSelf = this;

	objSelf.DOMRefs.modelList.css("display","grid").removeClass("grid").addClass("list");
	objSelf.DOMRefs.list.removeClass("invert").blur().siblings().addClass("invert");
};

pages.Solutions.prototype.applyViewGrid = function(){
	var objSelf = this;

	objSelf.DOMRefs.modelList.css("display","grid").removeClass("list").addClass("grid");
	objSelf.DOMRefs.grid.removeClass("invert").blur().siblings().addClass("invert");
};

pages.Solutions.prototype.attachDisplaySwitchEvents = function(){
	var objSelf = this;

	objSelf.applyViewGrid();
};

pages.Solutions.prototype.attachToolsButtonsEvents = function(){
	var objSelf = this;

	objSelf.DOMRefs.cusTrigger.on("click", function(){
		tl.animateContactUs();
	});
};

$(document).ready(function(){
	var solutionsPage = new pages.Solutions();
});

$(window).on("load", function(){
	var $modelList = $("#modelList");
	var isIE11 = /Trident.*rv[ :]*11\./.test(navigator.userAgent);

	if (isIE11){
		$modelList.removeClass("grid").addClass("list").show();
	} else {
		$modelList.show();
	}
});
/**
 *	File: 				\assets\js\tripplite.products.orderingHelp.js
 *	Created By: 		Francisco Carmona
 *	Created Date:
 *	Requirements:
 *	Description:		JavaScript files associated with _Ordering and _OnsiteServices partial pages
 *
 * 	Change Log:
 * 	Developer			Date		Comments
 *  -------------------	----------	-----------------------------------------------------------------------------------------------
 *
 */

var products = namespace("tl.products");

products.OrderingHelp = function(){
	this.modelNumber = "";

	this.DOMRefs = {
		non3PhaseModal: $("#non3phase-ordering-modal"),
		threePhaseModal: $("#three-phase-ordering-modal"),
		healthcareModal: $("#healthcare-ordering-modal"),
		microDataCenterModal: $("#micro-data-center-modal"),
		wrightLineModal: $("#wright-line-ordering-modal"),
		wrightLineForm: $("#wright-line-ordering-form"),
		submitSuccess: $("#submitSuccess"),
		submitFail: $("#submitFail")
	};

	this.attachModalEvents();

	if(this.DOMRefs.wrightLineModal.length){ this.attachCustomJQueryValidation(); }
};

products.OrderingHelp.prototype.attachCustomJQueryValidation = function(){
	var objSelf = this;

	// EXAMPLE: FluidValidation - jQuery Validation Plugin - Custom Validation for Front End
	$.validator.addMethod(
		"InterestRequired",
		function(value,element){
			var purchaseInterest = objSelf.DOMRefs.wrightLineForm.find("#wlo-interest-in-purchase").is(':checked');
			var quoteInterest = objSelf.DOMRefs.wrightLineForm.find("#wlo-interest-in-quote").is(':checked');

			return purchaseInterest || quoteInterest;
		},
		"Type of Request is required"
	);
	$.validator.addMethod(
		"StateRequired",
		function(value,element){
			var statesList = objSelf.DOMRefs.wrightLineForm.find("#wlo-state option");

			if (statesList.length == 1) return true; // Skip validation when state list is empty (except for placeholder option)

			return value !="";
		},
		"State is required"
	);

	// FluidValidation - Attach custom validation
	objSelf.DOMRefs.wrightLineForm.find("#wlo-interest-in .form-check-input").rules("add",{InterestRequired: "Required Interest In Option"});
	objSelf.DOMRefs.wrightLineForm.find("#wlo-state").rules("add",{StateRequired: "Required State"});
};

products.OrderingHelp.prototype.attachModalEvents = function(){
	var objSelf = this;

	objSelf.DOMRefs.non3PhaseModal.on("show.bs.modal", function (event) {
		objSelf.modelNumber = $(event.relatedTarget).attr('data-number');
	});

	objSelf.DOMRefs.threePhaseModal.on("show.bs.modal", function (event) {
		objSelf.modelNumber = $(event.relatedTarget).attr('data-number');
	});

	objSelf.DOMRefs.healthcareModal.on("show.bs.modal", function (event) {
		objSelf.modelNumber = $(event.relatedTarget).attr('data-number');
	});

	objSelf.DOMRefs.microDataCenterModal.on("show.bs.modal", function (event) {
		objSelf.modelNumber = $(event.relatedTarget).attr('data-number');
	});

	objSelf.DOMRefs.wrightLineModal.on("show.bs.modal", function (event) {
		objSelf.modelNumber = $(event.relatedTarget).attr('data-number');
	});

	objSelf.DOMRefs.wrightLineModal.on("hidden.bs.modal", function (event) {
		objSelf.closeModal("10");
	});

	objSelf.DOMRefs.wrightLineForm.submit(function(event) {
		// Fluid Validation initially intercepts and sets result property true if no validation errors found, false otherwise.
		if (event.result){
			event.preventDefault();
			objSelf.sendEmail("10");
		}
	});
};

products.OrderingHelp.prototype.closeModal = function(f){
	if(event) { event.preventDefault(); }

	var objSelf = this;
	var formType = f;

	switch(formType){
		case "3":
			objSelf.DOMRefs.non3PhaseModal.find(".end_user_name").val("");
			objSelf.DOMRefs.non3PhaseModal.find(".end_user_email").val("");
			objSelf.DOMRefs.non3PhaseModal.find(".comments").val("");
			objSelf.DOMRefs.non3PhaseModal.find(".formOrderingSubmit").removeClass("disabled");
			objSelf.DOMRefs.non3PhaseModal.find(".form-ordering-container").find("div.btn-success").remove();
		break;
		case "4":
			objSelf.DOMRefs.threePhaseModal.find(".end_user_name").val("");
			objSelf.DOMRefs.threePhaseModal.find(".end_user_email").val("");
			objSelf.DOMRefs.threePhaseModal.find(".comments").val("");
			objSelf.DOMRefs.threePhaseModal.find(".formOrderingSubmit").removeClass("disabled");
			objSelf.DOMRefs.threePhaseModal.find(".form-ordering-container").find("div.btn-success").remove();
		break;
		case "5":
			objSelf.DOMRefs.healthcareModal.find(".end_user_name").val("");
			objSelf.DOMRefs.healthcareModal.find(".end_user_email").val("");
			objSelf.DOMRefs.healthcareModal.find(".comments").val("");
			objSelf.DOMRefs.healthcareModal.find(".formOrderingSubmit").removeClass("disabled");
			objSelf.DOMRefs.healthcareModal.find(".form-ordering-container").find("div.btn-success").remove();
		break;
		case "8":
			objSelf.DOMRefs.microDataCenterModal.find(".end_user_name").val("");
			objSelf.DOMRefs.microDataCenterModal.find(".end_user_email").val("");
			objSelf.DOMRefs.microDataCenterModal.find(".comments").val("");
			objSelf.DOMRefs.microDataCenterModal.find(".formOrderingSubmit").removeClass("disabled");
			objSelf.DOMRefs.microDataCenterModal.find(".form-ordering-container").find("div.btn-success").remove();
		break;
		case "10":
			objSelf.DOMRefs.wrightLineModal.find("#wlo-first-name").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-last-name").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-company-name").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-city").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-state").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-email-address").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-phone-number").val("");
			objSelf.DOMRefs.wrightLineModal.find("#wlo-interest-in-purchase").prop('checked', false);
			objSelf.DOMRefs.wrightLineModal.find("#wlo-interest-in-quote").prop('checked', false);
			objSelf.DOMRefs.wrightLineModal.find(".checkedIcon").css("visibility", "hidden");
			objSelf.DOMRefs.wrightLineModal.find(".formOrderingSubmit").removeClass("disabled").prop("disabled", false);
			objSelf.DOMRefs.wrightLineModal.find(".form-ordering-container").find("div.btn-danger").remove();
		break;
		default:
			objSelf.DOMRefs.healthcareModal.find(".end_user_name").val("");
			objSelf.DOMRefs.healthcareModal.find(".end_user_email").val("");
			objSelf.DOMRefs.healthcareModal.find(".comments").val("");
			objSelf.DOMRefs.healthcareModal.find(".formOrderingSubmit").removeClass("disabled");
			objSelf.DOMRefs.healthcareModal.find(".form-ordering-container").find("div.btn-success").remove();
		break;
	}
};

products.OrderingHelp.prototype.sendEmail = function(f){
	event.preventDefault();

	var objSelf = this;
	var formType = f;
	var inpName, inpEmail = null;
	var nameValue, emailValue, comments = "";
	var submitSuccessMsg = objSelf.DOMRefs.submitSuccess.val();
	var submitFailMsg = objSelf.DOMRefs.submitFail.val();
	var errorFree = true;

	switch(formType){
		// HelpWithOrdering
		case "3":
			inpName = objSelf.DOMRefs.non3PhaseModal.find(".end_user_name");
			inpEmail = objSelf.DOMRefs.non3PhaseModal.find(".end_user_email");
			nameValue = inpName.val();
			emailValue = inpEmail.val();
			comments = ((objSelf.DOMRefs.non3PhaseModal.find(".comments").val().length == 0) ? "(customer submitted no questions)" : objSelf.DOMRefs.non3PhaseModal.find(".comments").val());

			if (objSelf.modelNumber.length > 0)
			{
				comments = "[" + objSelf.modelNumber + "] " + comments;
			}

			if (nameValue.length === 0){
				inpName.addClass("error");
				errorFree = false;
			} else {
				inpName.removeClass("error");
			}

			if (emailValue.length === 0){
				inpEmail.addClass("error");
				errorFree = false;
			} else {
				inpEmail.removeClass("error");
			}

			if (errorFree){
				$.ajax({
					url: "/api/products/emailOrderingHelp",
					data: {
						formType: formType,
						endUserName: nameValue,
						endUserEmail: emailValue,
						sourceUrl: window.location.href,
						comments: comments
					},
					success: function(response){
						objSelf.DOMRefs.non3PhaseModal.find(".formOrderingSubmit").addClass("disabled");
						objSelf.DOMRefs.non3PhaseModal.find(".form-ordering-container").append("<div class='btn-success'>" + submitSuccessMsg + "</div>");
					},
					error: function(response){
						objSelf.DOMRefs.non3PhaseModal.find(".form-ordering-container").append("<div class='btn-danger'>" + submitFailMsg + "</div>");
					}
				});
			}
		break;

		// HelpWith3PhaseOrdering
		case "4":
			inpName = objSelf.DOMRefs.threePhaseModal.find(".end_user_name");
			inpEmail = objSelf.DOMRefs.threePhaseModal.find(".end_user_email");
			nameValue = inpName.val();
			emailValue = inpEmail.val();
			comments = ((objSelf.DOMRefs.threePhaseModal.find(".comments").val().length == 0) ? "(customer submitted no questions)" : objSelf.DOMRefs.threePhaseModal.find(".comments").val());

			if (objSelf.modelNumber.length > 0)
			{
				comments = "[" + objSelf.modelNumber + "] " + comments;
			}

			if (nameValue.length === 0){
				inpName.addClass("error");
				errorFree = false;
			} else {
				inpName.removeClass("error");
			}

			if (emailValue.length === 0){
				inpEmail.addClass("error");
				errorFree = false;
			} else {
				inpEmail.removeClass("error");
			}

			if (errorFree){
				$.ajax({
					url: "/api/products/emailOrderingHelp",
					data: {
						formType: formType,
						endUserName: nameValue,
						endUserEmail: emailValue,
						sourceUrl: window.location.href,
						comments: comments
					},
					success: function(response){
						objSelf.DOMRefs.threePhaseModal.find(".formOrderingSubmit").addClass("disabled");
						objSelf.DOMRefs.threePhaseModal.find(".form-ordering-container").append("<div class='btn-success'>" + submitSuccessMsg + "</div>");
					},
					error: function(response){
						objSelf.DOMRefs.threePhaseModal.find(".form-ordering-container").append("<div class='btn-danger'>" + submitFailMsg + "</div>");
					}
				});
			}
		break;

		// HelpWithHealthcareOrdering
		case "5":
			inpName = objSelf.DOMRefs.healthcareModal.find(".end_user_name");
			inpEmail = objSelf.DOMRefs.healthcareModal.find(".end_user_email");
			nameValue = inpName.val();
			emailValue = inpEmail.val();
			comments = ((objSelf.DOMRefs.healthcareModal.find(".comments").val().length == 0) ? "(customer submitted no questions)" : objSelf.DOMRefs.healthcareModal.find(".comments").val());

			if (objSelf.modelNumber.length > 0)
			{
				comments = "[" + objSelf.modelNumber + "] " + comments;
			}

			if (nameValue.length === 0){
				inpName.addClass("error");
				errorFree = false;
			} else {
				inpName.removeClass("error");
			}

			if (emailValue.length === 0){
				inpEmail.addClass("error");
				errorFree = false;
			} else {
				inpEmail.removeClass("error");
			}

			if (errorFree){
				$.ajax({
					url: "/api/products/emailOrderingHelp",
					data: {
						formType: formType,
						endUserName: nameValue,
						endUserEmail: emailValue,
						sourceUrl: window.location.href,
						comments: comments
					},
					success: function(response){
						objSelf.DOMRefs.healthcareModal.find(".formOrderingSubmit").addClass("disabled");
						objSelf.DOMRefs.healthcareModal.find(".form-ordering-container").append("<div class='btn-success'>" + submitSuccessMsg + "</div>");
					},
					error: function(response){
						objSelf.DOMRefs.healthcareModal.find(".form-ordering-container").append("<div class='btn-danger'>" + submitFailMsg + "</div>");
					}
				});
			}
		break;

		// MicroDataCenter
		case "8":
			inpName = objSelf.DOMRefs.microDataCenterModal.find(".end_user_name");
			inpEmail = objSelf.DOMRefs.microDataCenterModal.find(".end_user_email");
			nameValue = inpName.val();
			emailValue = inpEmail.val();
			comments = ((objSelf.DOMRefs.microDataCenterModal.find(".comments").val().length == 0) ? "(customer submitted no questions)" : objSelf.DOMRefs.microDataCenterModal.find(".comments").val());

			if (objSelf.modelNumber.length > 0)
			{
				comments = "[" + objSelf.modelNumber + "] " + comments;
			}

			if (nameValue.length === 0){
				inpName.addClass("error");
				errorFree = false;
			} else {
				inpName.removeClass("error");
			}

			if (emailValue.length === 0){
				inpEmail.addClass("error");
				errorFree = false;
			} else {
				inpEmail.removeClass("error");
			}

			if (errorFree){
				$.ajax({
					url: "/api/products/emailOrderingHelp",
					data: {
						formType: formType,
						endUserName: nameValue,
						endUserEmail: emailValue,
						sourceUrl: window.location.href,
						comments: comments
					},
					success: function(response){
						objSelf.DOMRefs.microDataCenterModal.find(".formOrderingSubmit").addClass("disabled");
						objSelf.DOMRefs.microDataCenterModal.find(".form-ordering-container").append("<div class='btn-success'>" + submitSuccessMsg + "</div>");
					},
					error: function(response){
						objSelf.DOMRefs.microDataCenterModal.find(".form-ordering-container").append("<div class='btn-danger'>" + submitFailMsg + "</div>");
					}
				});
			}
		break;

		// WrightLineOrderingHelp
		case "10":
			// FluidValidation takes care of Front-End JS Validation. So if we get this far fields have passed validation
			var formData = {
				CleanProductNumber: objSelf.DOMRefs.wrightLineForm.find("#wlo-clean-product-number").val(),
				FirstName         : objSelf.DOMRefs.wrightLineForm.find("#wlo-first-name").val(),
				LastName          : objSelf.DOMRefs.wrightLineForm.find("#wlo-last-name").val(),
				CompanyName       : objSelf.DOMRefs.wrightLineForm.find("#wlo-company-name").val(),
				City              : objSelf.DOMRefs.wrightLineForm.find("#wlo-city").val(),
				State             : objSelf.DOMRefs.wrightLineForm.find("#wlo-state").val(),
				CountryCode       : objSelf.DOMRefs.wrightLineForm.find("#wlo-country-code").val(),
				EmailAddress      : objSelf.DOMRefs.wrightLineForm.find("#wlo-email-address").val(),
				PhoneNumber       : objSelf.DOMRefs.wrightLineForm.find("#wlo-phone-number").val(),
				PurchaseInterest  : objSelf.DOMRefs.wrightLineForm.find("#wlo-interest-in-purchase").is(':checked'),
				QuoteInterest     : objSelf.DOMRefs.wrightLineForm.find("#wlo-interest-in-quote").is(':checked')
			};

			// Override of value from ResourceBundle & ResourcBundleReplacements
			submitFailMsg = "Sorry, your inquiry could not be completed at this time. Please try again in a few minutes or contact a product specialist directly at (800)225-7348";

			$.ajax({
				url: "/api/products/wright-line-ordering-help",
				type: "POST",
				data: JSON.stringify( formData ),
				dataType: "json",
				contentType: "application/json",
				cache: false,
				success: function (response) {
					if (response.Success) {
						objSelf.DOMRefs.wrightLineModal.find(".checkedIcon").css("visibility", "visible");
						objSelf.DOMRefs.wrightLineModal.find(".formOrderingSubmit").prop('disabled', true).addClass("disabled");
					}
					else
						objSelf.DOMRefs.wrightLineModal.find(".form-ordering-container").append("<div class='btn-danger'>" + submitFailMsg + "</div>");
				},
				error: function (response) {
					objSelf.DOMRefs.wrightLineModal.find(".form-ordering-container").append("<div class='btn-danger'>" + submitFailMsg + "</div>");
				}
			});
		break;
	}
};

$(document).ready(function(){
	objOrderingHelp = new products.OrderingHelp();
});
