if (typeof discover === 'undefined') {
	var discover = {};
}


discover.shopBrowse = (function () {
	
	var service;
	
	var dateChecker = {
		
		/**
		* Checks an offer date and checks if its within the time
		
		* @param {Object} Date object
		* @param {String} Type of check we're doing, before or after date
		*/
		compareDate : function (date, check) {
			var currentDate = Date();
			switch(check) {
				case 'start':
					return (mcd.date.isToday(date) || mcd.date.isAfterDate(date, new Date()));
					break;					
				case 'end':
					return  mcd.date.isBeforeDate(new Date(), date);
					break;
			}
		},
		
		checkOfferStartDate : function (offer) {
			return offer.startDate;
		},
		
		/*
		* Reuseable function to take an XML date string and convert it to an array
		* @param {String} String date sperated by - from the XML feed
		* @return {Array} Array representation of the date
		*/
		dateToArray : function (date) {
			var returnDate = date.split('-');
			returnDate[1] = parseInt(returnDate[1], 10) - 1;
			return returnDate;
		},
				
		/**
		* Checks an offer if it falls in the correct date range
		*
		* @param {Object} offer object
		* @return {Bool} if date lies correctly
		*/
		validateOffer : function (offer) {			
			//Check if the offer doesn't have a start
			if(offer.startDate) {		
				var offerDate = dateChecker.dateToArray(offer.startDate);								
				var date = mcd.date.dateFromArray(offerDate);
				
				//Check if the date passes the start date check
				if(dateChecker.compareDate(date, 'start')) {
					return false;
				} 	
			}
			
			//Check offer end date
			if(offer.endDate){
				var endDate = dateChecker.dateToArray(offer.endDate);
				var date = mcd.date.dateFromArray(endDate);
				
				if(!dateChecker.compareDate(date, 'end')) {
					return false;
				}
			}
						
			return true;			
		},
				
		/*
		* Checks an offers 'Hot Deal' date
		*
		* @param {Object} Offer
		* @return {Bool}
		*/
		validateDeal : function (offer) {
			if(offer.offerStartDate) {				
				var startDate = dateChecker.dateToArray(offer.offerStartDate);
				var date = mcd.date.dateFromArray(startDate);				
				if(dateChecker.compareDate(date, 'start')){					
					return false;
				}
			}		
			
			if(offer.offerEndDate) {
				var endDate = dateChecker.dateToArray(offer.offerEndDate);
				var date = mcd.date.dateFromArray(endDate);
				if(!dateChecker.compareDate(date, 'end')) {
					return false;
				}
			}			
			return true;
		}
		
	};
	
	/**
	 * List of functions we will be using within the private object
	 */
	var app = {
		throbberContainer : document.getElementById('partners-throbber'),
		partnersContainer : document.getElementById('partners-table'),
		worksTrigger : document.getElementById('how-it-works-trigger'),
		productCategories : null,
		selectedTab : null,
		selectedRetailers : null,		
		config : null,
		
		xmlFiles : {
			'cbb' : 'ShopD_Public_CBB_Partners.xml',
			'miles' : 'ShopD_Public_Miles_Partners.xml'
		},
			
		init : function (config) {
			
			if(app.throbberContainer) 	app.showThrobber();
				
			var tConfig = {
				'type' : 'cbb',
				'browse' : true
			}
			
			app.pageInit();
			
			app.config = config || tConfig;
			
			//Parse a query string
			var queryString = window.location.search;
			queryString = queryString.substring(queryString.indexOf('?')+1, queryString.length);
			queryString = queryString.split('=');
			
			//Check for a parse type passed by query string
			for(var i=0; i<queryString.length; i++) {
				if(queryString[i] === 'parseType') {
					var x = i+1;
					app.config.type = queryString[x];					
				}
			}
			
			//initialize the categories object
			app.resetCategories();
			
			//Check if we are setting up tab navigation, IE: browse all partners page
			if(app.config.browse) {
				app.toggleContainerClass(app.config.type);
				app.togglePromo(app.config.type);
				app.tabSetup(app.config.type);
			}
			
			//Force a wait before parsing, let the rest of the page setup first
			window.setTimeout(app.processCheck(), 100);
			
		},
		
		/**
		* Do not allow an ajax call until the page is finished setting up completely
		*/
		processCheck : function () {
			return function () {
				var nonJs = mcd.dom.getElementsByAttribute('class', 'no-js', document.body, '', true);
				if(nonJs.length != 0) {
					window.setTimeout(app.processCheck(), 500);
				}else{
					app.initialAjax();
				}
			}		
		},
			
		/**
		* Our first ajax call for the page
		*/
		initialAjax : function () {
			var request = app.createRequest('/customer-service/rewards/xml/' + app.xmlFiles[app.config.type]);
			request.send('');			
		},
		
		/**
		* Generic page init, displaying JS only features
		*/
		pageInit : function () {
			var elements = mcd.dom.getElementsByAttribute('class', 'js-only', document.body, '', true);
			if(elements){
				for(var i=0; i<elements.length; i++) {
					var element = elements[i];
					mcd.dom.removeClass(element, 'js-only');
				}				
			}				
		},
		
		/**
		* Set up tabs on browse page
		*/
		tabSetup : function (type) {
			var tabs = {
				'cbb' : document.getElementById('cbb-tab'),
				'miles' : document.getElementById('miles-tab')
			}
			
			app.worksTrigger.setAttribute('href', '/customer-service/rewards/how-it-works-' + type + '.html');
			
			var retailer = document.getElementById(type + '-retailers');
			var currentTab = tabs[type].parentNode;
						
			//Set up initial tab state
			mcd.dom.addClass(currentTab, 'tabs-selected');
			mcd.dom.addClass(retailer, 'selected-retailer');
			mcd.dom.removeClass(retailer, 'hide');
			
			app.selectedTab = currentTab;
			app.selectedRetailers = retailer;
			
			//Set up click handlers for tabs			
			mcd.event.add(tabs.cbb, 'click', app.tabClick);
			mcd.event.add(tabs.miles, 'click', app.tabClick);
		},	
		
		/*
		* Our tab navigation click handler
		*/
		tabClick : function (e) {
			var target = mcd.event.getTarget(e);
			mcd.event.preventDefault(e);						
			
			//Remove current tab selection
			mcd.dom.removeClass(app.selectedTab, 'tabs-selected');
			mcd.dom.removeClass(app.selectedRetailers, 'selected-retailer');
			mcd.dom.addClass(app.selectedRetailers, 'hide');
				
			//Make sure our target is the link
			while(target.tagName !== 'A') {
				target = target.parentNode;
			}
			
			var rel = target.rel;			
			var retailerContainer = document.getElementById(rel + '-retailers');
			
			//Find the list item for the tab
			while(target.tagName !== 'LI') {
				target = target.parentNode;
			}
						
			mcd.dom.addClass(target, 'tabs-selected');
			mcd.dom.addClass(retailerContainer, 'selected-retailer');
			mcd.dom.removeClass(retailerContainer, 'hide');
			
			//Update current selected tab and retailers
			app.selectedTab = target;
			app.selectedRetailers = retailerContainer;
			app.worksTrigger.setAttribute('href', '/customer-service/rewards/how-it-works-' + rel + '.html');
			app.toggleContainerClass(rel);
			app.togglePromo(rel);
			
			//Empty table container and Fetch XML now for tab
			app.clearPageContents();
			
			var request = app.createRequest('/customer-service/rewards/xml/' + app.xmlFiles[rel]);
			request.send('');								
		},
		
		/**
		* Reset a page before parsing the XML and pushing its contents to the page
		*/
		clearPageContents : function () {
			app.partnersContainer.innerHTML = '';
			app.resetCategories();

			var dropDown = document.getElementById('retailers-dropdown');
			dropDown.innerHTML = '';
			
			var initialOption = document.createElement('option');
			initialOption.innerHTML = 'Select Retailer';
			initialOption.setAttribute('value', 'misc/redirect/redirect_shopcenter.htm');			
			
			dropDown.appendChild(initialOption);
		},
		
		/*
		* Show Throbber
		*/
		showThrobber : function () {
			mcd.dom.removeClass(app.throbberContainer, 'hide');
		},
		
		/*
		* Hide the Throbber
		*/
		hideThrobber : function () {
			mcd.dom.addClass(app.throbberContainer, 'hide');
		},
		
		
		/*
		* Toggle an Ajax error message
		*/
		toggleAjaxError : function () {
			var ajaxError = document.getElementById('ajax-error');
			mcd.dom.toggleClass(ajaxError, 'hide');
		},
		
		/**
		 * Template for rewards object
		 */
		createNewPartnerObject : function (partner) {
			var dataObject = {
				'partner' : '',
				'partnerFlag' : '',
				'cbb' : '',
				'url' : '',
				'startDate' : '',
				'endDate' : '',
				'offerFlag' : '',
				'offerCode' : '',
				'offerStartDate' : '',
				'offerEndDate' : '',
				'offer' : ''
			};
			
			//Loop through a partner's properties
			for(var i=0; i<partner.attributes.length; i++) {
				var attr = partner.attributes[i];
				
				if(attr.name === 'P') dataObject['partner'] = app.getNodeContents(attr);
				if(attr.name === 'PF') dataObject['partnerFlag'] = app.getNodeContents(attr);
				if(attr.name === 'CBB') dataObject['cbb'] = app.getNodeContents(attr);
				if(attr.name === 'URL') dataObject['url'] = app.getNodeContents(attr);
				if(attr.name === 'SD') dataObject['startDate'] = app.getNodeContents(attr);
				if(attr.name === 'ED') dataObject['endDate'] = app.getNodeContents(attr);
				if(attr.name === 'OF') dataObject['offerFlag'] = app.getNodeContents(attr);
				if(attr.name === 'OC') dataObject['offerCode'] = app.getNodeContents(attr);
				if(attr.name === 'OSD') dataObject['offerStartDate'] = app.getNodeContents(attr);
				if(attr.name === 'OED') dataObject['offerEndDate'] = app.getNodeContents(attr);
				if(attr.name === 'Off') dataObject['offer'] = app.getNodeContents(attr);
								
			}
					
			return dataObject
		},
		
		/*
		* Return an XML attribute's value based on the availability
		* of the nodeValue attribute, (IE does not support .nodeValue)
		* @param {XMLElement}
		* @return Attribute's contents
		*/
		getNodeContents : function (node) {
			if(node.nodeValue === null) return node.text;
			else return node.nodeValue;
		},
		
		/**
		* Loop through all of the partners and offers from the XML file 
		* and store them accordingly (Alphabetically)
		* @param {Object} HTTPRequest Response (XML)
		*/
		parsePartners : function (xml) {			
			var partners = xml.getElementsByTagName('pD');
			var partnersArr = app.productCategories;
			
			if( app.config.browse) var jump = document.getElementById('jump-menu');		
						
			for (var i = 0; i < partners.length; i++) {
				var newPartner = app.createNewPartnerObject(partners[i]);
				var character = newPartner.partner.charAt(0).toUpperCase();					
				
				//Group any numbers with the # character
				if(parseInt(character)) {
					character = '#';
				}
				
				if(dateChecker.validateOffer(newPartner)) {
					partnersArr[character].push(newPartner);														
				}																			
			}
			
			//Create a UL for the jump menu if we're browsing
			if(app.config.browse) {
				jump.innerHTML = '';
				var ul = document.createElement('ul');
			}
			
			
			/*
			* Loop through each product category
			*/
			for(product in partnersArr) {
				
				if(app.config.browse) var tBody = app.createPartnerHeading(product);
				
				var products = partnersArr[product];
				//Check if the category had any 
				if(products.length > 0) {
					
					//Create a jump menu item if we're in browse mode
					if(app.config.browse) {
						var li = document.createElement('li');
						var anchor = document.createElement('a');
						
						anchor.href = '#partners-' + product.toLowerCase();
						anchor.innerHTML = product;
						
						if(product === 'Z') mcd.dom.addClass(li, 'last');
						
						li.appendChild(anchor);						
						ul.appendChild(li);
							
					}
					
					//Loop through products in array for this category
					for(var i=0; i<products.length; i++) {
						var partner = products[i];
						app.populateDropDown(partner);		
						
						if(app.config.browse) app.createPartner(partner, tBody);
						
					}
				} else {
										
					if(app.config.browse) {
						
						var li = document.createElement('li');
						li.innerHTML = product;
						
						if(product === 'Z') mcd.dom.addClass(li, 'last');
						
						ul.appendChild(li);
						
						var row = document.createElement('tr');
						tBody.appendChild(row);
						
						var cell = document.createElement('td');
						cell.innerHTML = 'Currently no partners.';
						
						row.appendChild(cell);
					}
				}
			}
			
			if(app.config.browse) {
				jump.appendChild(ul);				
				app.hideThrobber();
			}
	
		},
		
		/**
		* Creates a new table for the product group
		*
		* @param {Object} Partner Object
		*/
		createPartnerHeading : function (caption) {
			var partnerGroup = document.createElement('table');
			var partnerList = document.getElementById("partners-table");	
			partnerList.appendChild(partnerGroup);
			
			var partnerTitle = document.createElement('thead');
			partnerGroup.appendChild(partnerTitle);
			
			//create row for table heading
			var newRow = document.createElement('tr');
			partnerTitle.appendChild(newRow);
			
			var partnerTitleTag = document.createElement('th');
			newRow.appendChild(partnerTitleTag);
			partnerTitleTag.setAttribute("colSpan", "2");
			
			var partnerTitleLink = document.createElement('a');
			partnerTitleTag.appendChild(partnerTitleLink);			
			partnerTitleLink.setAttribute('id', 'partners-' + caption.toLowerCase());
			
			var captionTitle = document.createTextNode(caption);
			partnerTitleTag.appendChild(captionTitle);
			
			var partnerTbody = document.createElement('tbody');
			partnerGroup.appendChild(partnerTbody);
			
			return partnerTbody;			
		},
		
		/*
		* Create a partner table to add to the table
		*/
		createPartner : function (newPartner, partnerGroup) {	
			
			var tableRow = document.createElement('tr');
			partnerGroup.appendChild(tableRow);
			
			var tableCellName = document.createElement('td');
			tableRow.appendChild(tableCellName);		
			mcd.dom.addClass(tableCellName, 'retailer');
			
			if (newPartner['partnerFlag']) {
				var partnerFlag = document.createElement('span');
				tableCellName.appendChild(partnerFlag);
				mcd.dom.addClass(partnerFlag, 'new');
				partnerFlag.innerHTML = newPartner['partnerFlag'] + ' ' ;;
			}
			
			var retailerLink = document.createElement('a');
			tableCellName.appendChild(retailerLink);
			retailerLink.innerHTML = newPartner['partner'];
			retailerLink.href = "https://www.discover.com/shopdiscover/" + newPartner['url'];
			retailerLink.setAttribute('title',newPartner['partner'])
			
			var secondTableRowCell = document.createElement('td');
			tableRow.appendChild(secondTableRowCell);
			
			if(newPartner['cbb']) {								
				mcd.dom.addClass(secondTableRowCell, 'offer');
				secondTableRowCell.innerHTML = newPartner['cbb']*100 + "% <em>Cashback Bonus</em> ";
			}else{
				secondTableRowCell.innerHTML = 'Double Miles';
			}
			
			if (newPartner['offer']) {				
				//Check for offer start date and validate it if it exists
				if(dateChecker.validateDeal(newPartner)) {
					var offerFlag = document.createElement('span');
					secondTableRowCell.appendChild(offerFlag);
					mcd.dom.addClass(offerFlag, 'hot-deal');
					offerFlag.innerHTML = newPartner['offerFlag'] + ' ';
					var offerLink = document.createElement('a');
					secondTableRowCell.appendChild(offerLink);
					offerLink.setAttribute('title', newPartner['offer']);
					offerLink.href = "https://www.discovercard.com/hotdeals/";
					offerLink.innerHTML = newPartner['offer'];						
				}												
			};
				
		},
		
		/*
		* Populate a drop down menu option
		*/
		populateDropDown : function (newPartner) {
			var dropDown = document.getElementById('retailers-dropdown');
			var dropDownOption = document.createElement('option');
			dropDown.appendChild(dropDownOption);
			dropDownOption.innerHTML = newPartner['partner'];
			
			// Set the redirect URL value based off the newPartner[url] with a regex string replace
			var expressionCheck = /^cbb\/|^miles\//;
			var url = newPartner['url'].replace(expressionCheck, '$&redirect-') + '.html';
			
			dropDownOption.setAttribute('value', "misc/redirect/shopdiscover/" + url);
		},
		
		/*
		* Reset our product container for a new parse
		*/
		resetCategories : function () {
			app.productCategories = { 
				'#' : [],
				'A' : [],
				'B' : [],
				'C' : [],
				'D' : [],
				'E' : [],
				'F' : [],
				'G' : [],
				'H' : [],
				'I' : [],
				'J' : [],
				'K' : [],
				'L' : [],
				'M' : [],
				'N' : [],
				'O' : [],
				'P' : [],
				'Q' : [],
				'R' : [],
				'S' : [],
				'T' : [],
				'U' : [],
				'V' : [],
				'W' : [],
				'X' : [],
				'Y' : [],
				'Z' : []			
			};				
		},
		
		/**
		* Handles switching between container class tags for miles and CBB
		*/
		toggleContainerClass : function (type) {
			var container = document.getElementById('container');
			switch(type) {
				case 'cbb':
					mcd.dom.addClass(container, 'cbb');
					mcd.dom.removeClass(container, 'miles');
					break;
				case 'miles':
					mcd.dom.addClass(container, 'miles');
					mcd.dom.removeClass(container, 'cbb');
					break;
			}
		},
		
		/**
		* Handles toggling a promo based on the miles or cbb
		*/
		togglePromo : function (type) {
			var cbbPromo = document.getElementById('cbb-promo');
			var milesPromo = document.getElementById('miles-promo');
			
			switch(type) {
				case 'cbb':
					mcd.dom.addClass(milesPromo, 'hide');
					mcd.dom.removeClass(cbbPromo, 'hide');
					break;
				case 'miles':
					mcd.dom.addClass(cbbPromo, 'hide');
					mcd.dom.removeClass(milesPromo, 'hide');
					break;
			}
		},
								
		/**
		* Creates an XHR Object
		*/
		createRequest : function (uri) {
			var request = mcd.http.request({				
				'method'  : 'GET',
				'uri' : uri,
				'onreadystatechange' : function(){
					if(app.config.browse) app.showThrobber();
					
					if(request.readyState==4){
						if(request.status !== 200){
							app.hideThrobber();
							app.toggleAjaxError();
						} else {
							app.parsePartners(request.responseXML);
						}
					}
				}
			});						
			return request;			
		}				
	};
					
	return service = {
		'init' : app.init
	};
	
})();
