/* Silently create the mcd namespace if it does not exist */
if (typeof mcd === 'undefined') {
	var mcd = [];
}

/**
* privileges.js
* 
* controls the promotions.php page
* 
* @author Brendan Barr (bbarr@mcdpartners.com)
*/

mcd.privileges = {
	
	offerArray : [],
	filteredOfferArray : [],
	filteredTopOfferArray : [],
	
	// Created to hold any offers that are used in filteredTopOfferArray
	generalOfferArray : [],
	
	imagesPath : '/merchant-offers/images/offer-images/',
	
	filters : ['categories=0', 'cities=0'],
	sort : 'date',
	defaultCity : '',
	defaultCountry : '',
	
	categories : [],
	activeCategory: 0,
	pageNum : 1,
	
	staleCheck : false,
	
	page : {

		// Offers wrapper
		offersWrapper : document.getElementById('browse-merchant-offers-wrapper'),

		/**
		 * Initializes page. if isSimple is true, only the content area is reset
		 * 
		 * @param {Boolean} isSimple
		 */
		
		setup : function(isSimple){			
			mcd.dom.removeClass(mcd.privileges.page.offersWrapper, 'hide');
			
			if(mcd.privileges.offerArray.length === 0) {
				mcd.privileges.page.error();
			}
			
			// Remove stale offers only once
			if(!mcd.privileges.staleCheck) {
				mcd.privileges.offerArray = mcd.offerHandler.filter.removeStaleOffers(mcd.privileges.offerArray);
				mcd.privileges.staleCheck = true;				
			}			
			
			// if reset is triggered by a sort or the city filter, isSimple is set to true which limits reset
			if (isSimple) {
				mcd.privileges.page.reset(isSimple);
			}
			else {
				mcd.privileges.page.reset();				
				// copy top offers from offerArray to filteredTopOfferArray						
				mcd.offerHandler.extractTopOffers();							
			}
									
			// apply filter
			mcd.offerHandler.filter.apply();
			
			// apply sort
			mcd.offerHandler.sort.apply();
			
			// apply pagination
			mcd.offerHandler.pagination.apply();
			
			// display actual offers 
			mcd.privileges.page.buildOffers();
			
			// set up details, with overlay for top offers and hidden tr for standard
			mcd.offerHandler.setupOverlay();
			mcd.offerHandler.setupStandardDetails();
			
			// if FULL setup, load dynamic lists and apply event handlers
			if(!isSimple){
				mcd.privileges.page.loadCategoryList();
				mcd.privileges.page.loadCityList();
				mcd.privileges.page.loadCountryList();
				mcd.privileges.page.attachCategoryEvents();
				mcd.privileges.page.attachSortEvents();
				mcd.privileges.page.attachCityEvents();
			}
			
			// reinitialize sorters
			mcd.privileges.page.activeSort();
			
			// label last offer class="last"
			mcd.privileges.page.labelLastOffer();
			
			// check for presence of top ads, if missing, show category image
			mcd.privileges.page.confirmTopAds();
			
			// finally, wait .5sec and display hidden elements
			setTimeout(mcd.privileges.page.loaded, 500);
		},
		
		/**
		 *  If error on XML load
		 */
		
		error : function() {
			mcd.dom.addClass(document.getElementById('throbber'), 'hide');
			mcd.dom.addClass('merchant-nav', 'hide');
			mcd.dom.addClass('merchant-content', 'hide');
			mcd.dom.removeClass('error-content', 'hide');
		},
		
		
		/**
		 *  Display initial throbber while XML/page loads
		 */
		
		loadingPage : function() {
			mcd.dom.removeClass(document.getElementById('throbber'), 'hide');
		},
		
		/**
		 * Display throbber while the category changes 
		 */
		
		loadingCategory : function() {
			document.getElementById('throbber').className = 'partial';
			mcd.dom.removeClass('throbber', 'hide');
			mcd.dom.addClass('merchant-content', 'hide');
		},
		
		/**
		 * Display throbber in offer list area when offers are sorted, 
		 * filtered by city, or pagination page change
		 */
		
		loadingOffers : function() { 
			mcd.dom.removeClass(document.getElementById('offers-throbber'), 'hide');
			mcd.dom.addClass('browse-merchant-offers-wrapper', 'loading');
		},
		
		/**
		 * Hides any loading elements and shows all content
		 */
		
		loaded : function() {
			mcd.dom.addClass('throbber', 'hide');
			mcd.dom.addClass('offers-throbber', 'hide');
			mcd.dom.removeClass('merchant-nav', 'hide');
			mcd.dom.removeClass('merchant-content', 'hide');
			mcd.dom.removeClass('browse-merchant-offers-wrapper', 'loading');
		},
		
		/**
		 * Assigns 'selected' state to selected category nav
		 */
		
		activateCategory : function() {
			var active = mcd.privileges.activeCategory;
			var links = document.getElementById('nav-content').getElementsByTagName('a');
			var category = mcd.privileges.categories[mcd.privileges.activeCategory];
			
			for(var i = 0; i < links.length; i++) {
				if(links[i].href.split('#')[1] == active){
					mcd.dom.addClass(links[i], 'selected')
				}
				else if(mcd.dom.hasClass(links[i], 'selected')) {
					mcd.dom.removeClass(links[i], 'selected')
				}
			}
			
			// update header
			document.getElementById('merchant-content').getElementsByTagName('h3')[0].innerHTML = '&mdash; ' + category
		},
		
		/**
		 * Assigns arrows and directions to sort links 
		 */
		
		activeSort : function(){
			var sort = mcd.privileges.sort;
			
			var date = document.getElementById('date');
			var alpha = document.getElementById('alpha');
			
			date.parentNode.className = 'exp sort-key';
			alpha.parentNode.className = 'offers sort-key';
			
			if(sort.indexOf('-reversed') != -1){
				var id = sort.split('-')[0];
				mcd.dom.addClass(document.getElementById(id).parentNode, 'sort-desc');
			}
			else {
				mcd.dom.addClass(document.getElementById(sort).parentNode, 'sort-asc');
			}
		},	
		
		/**
		 * Sets mcd.privileges.sort
		 * 
		 * @param {HTMLElement} el
		 */
		
		activateSort : function(el) {
			var id = el.getAttribute('id');
			
			// set reversed state of mcd.privileges.sort
			mcd.privileges.sort = (mcd.privileges.sort == id)
			? id + '-reversed'
			: id;
		},
		
		/**
		 * Attach event handler for Category links
		 */
		
		attachCategoryEvents : function() {
		
			var navLinks = mcd.dom.getElement('nav-content').getElementsByTagName('a');
			
			mcd.privileges.page.activateCategory();
			
			for(var i = 0; i < navLinks.length; i++){
		
				// activate nav links
				mcd.event.add(navLinks[i], 'click', function(event){
					mcd.event.preventDefault(event);
					
					// turns on loading state
					mcd.privileges.page.loadingCategory();
					
					var key = this.getAttribute('href').split('#')[1];
					mcd.privileges.activeCategory = key;
						

					// switch category filter with selected category
					mcd.offerHandler.filter.remove('categories=');
					mcd.privileges.filters.push('categories=' + key);
					
					// re-init city filter to defaultCity ie: all cities
					mcd.offerHandler.filter.remove('cities=');
					mcd.privileges.filters.push('cities=' + mcd.privileges.defaultCity);
					
					// re-init sort to "date"
					mcd.privileges.sort = 'date';
					
					// re-init pageNum
					mcd.privileges.pageNum = 1;
					
					// assigns 'selected' state to active category link
					mcd.privileges.page.activateCategory();
					
					// rebuild page
					mcd.privileges.page.setup();
				});
			}
		},
		
		/**
		 * Attach event handler for Sort links
		 */
		
		attachSortEvents : function(){
			
			var sorters = mcd.dom.getElementsByAttribute('class', 'sorter', document.getElementById('browse-merchant-offers'), 'a', true);
			
			for(var x = 0; x < sorters.length; x++) {
				mcd.event.add(sorters[x], 'click', function(event){
					mcd.event.preventDefault(event);
					
					// assign arrows and directions to sort links
					mcd.privileges.page.activateSort(this);
					
					// rebuild page (isSimple)
					mcd.privileges.page.setup(true)
				});
			}
		},
		
		/**
		 * Attach event handler for City links
		 */
		
		attachCityEvents : function(){
			
			var cities = document.getElementById('city-select');
			var options = cities.getElementsByTagName('option');
			
			mcd.event.add(cities, 'change', function(event){
				
				// sets loading state
				mcd.privileges.page.loadingOffers();
				
				// swap cities filter
				mcd.offerHandler.filter.remove('cities=')
				mcd.privileges.filters.push('cities=' + options[cities.selectedIndex].value)
				
				// re-init pageNum
				mcd.privileges.pageNum = 1;
				
				// rebuild page
				mcd.privileges.page.setup(true);
			});	
		},
		
		/**
		 * Find and label last offer class="last"
		 */
		
		labelLastOffer : function() {
			var tbodys = document.getElementById('browse-merchant-offers').getElementsByTagName('tbody');
			if(tbodys.length > 0) {
				
				mcd.dom.addClass(tbodys[tbodys.length-1], 'last');
			}
		},
		
		/**
		 * Confirm presence of top ads, else, show default category image
		 */
		
		confirmTopAds : function(){
			var parent = document.getElementById('browse-top-offers');
			var active = mcd.privileges.activeCategory;
			var category;

			if(document.getElementById('top-offers').getElementsByTagName('li').length < 1){	
				parent.className = 'empty';
				var categories = mcd.privileges.categories;
				category = categories[active];
				parent.getElementsByTagName('div')[0].getElementsByTagName('p')[0].innerHTML = category;
				parent.getElementsByTagName('div')[0].className = 'cat_' + active;
			}
			else{
				parent.className = '';
			}
		},
		
		/**
		 * Reset page by flushing various containers
		 * If isSimple is true, only flush offers
		 * 
		 * @param {Object} isSimple
		 */
		
		reset : function(isSimple) {
			if(!isSimple){
				mcd.privileges.util.flushContainer(document.getElementById('nav-content').getElementsByTagName('ul')[0], 'li');	
				mcd.privileges.util.flushContainer(document.getElementById('city-select'), 'option');
			}		
			
			mcd.privileges.util.flushContainer(document.getElementById('pagination'), 'li');
			mcd.privileges.util.flushContainer(document.getElementById('top-offers'), 'li');
			mcd.privileges.util.flushContainer(document.getElementById('browse-merchant-offers'), 'tbody')
		},
		
		/**
		 * Build category list from offerArray categories
		 */
		
		loadCategoryList : function() {
			var categories = mcd.privileges.categories;
			var activeCategories = [0];
			var offers = mcd.privileges.offerArray;
			var list = document.getElementById('nav-content').getElementsByTagName('ul')[0];
		
			for(offer in offers) {
				var offerCategories = offers[offer]['categories'];
				for(category in offerCategories) {
					if(!mcd.privileges.util.contains(activeCategories, offerCategories[category])) {
						activeCategories.push(offerCategories[category]);
					}
				}
			}
			
			var categorySort = [];
			for(var i = 0; i < activeCategories.length; i++) {
				var category = mcd.privileges.categories[activeCategories[i]];
				categorySort.push(category + '_' + activeCategories[i]);
			}
			categorySort.sort();
			for(x in categorySort) {
				var cat = categorySort[x].split('_')[0];
				var index = categorySort[x].split('_')[1];
				var li = mcd.privileges.util.createEl('li', list);
				mcd.privileges.util.createEl('a', li, cat, true, {'href' : '#' + index});
			}
		},
		
		/**
		 * Build country list from XML 
		 */
		
		loadCountryList : function() {
			var select = document.getElementById('select-country');
			var options = select.getElementsByTagName('option');
			var country = mcd.privileges.util.getParam('country');
			
			for(var i in options) {
				if(!options[i]) continue;
				if(options[i].value == '') {
					select.removeChild(options[i]);
				}
				if(options[i].value == country) {
					options[i].setAttribute('selected', 'selected');
				}
			}
		},
		
		/**
		 * Build city list from filteredOfferArray cities
		 */
		
		loadCityList : function() {
			var defaultCity = mcd.privileges.defaultCity;
			var cities = [defaultCity];
			var offers = mcd.privileges.offerArray;
			var list = document.getElementById('city-select');
			var city = mcd.offerHandler.filter.get('cities');
			
			for(offer in offers) {
				var offerCities = offers[offer]['cities'];
				
				for(var i in offerCities) {
					if(!mcd.privileges.util.contains(cities, offerCities[i])) {
						cities.push(offerCities[i]);
					}
				}
			}
			cities.sort();
			var start = false;
			for(var i = 0; i < cities.length; i++) {				
				if(start == false){
					if(cities[i] == city) {
						var option = mcd.privileges.util.createEl('option', list, cities[i], true, {'value' : cities[i]})	
						i = -1;
						start = true;
					}
				}
				else if (cities[i] != city) {
					var option = mcd.privileges.util.createEl('option', list, cities[i], true, {'value' : cities[i]})	
				}
			}
		},
		
		/**
		 * Build offers, standard and top		 		 
		 */
		
		buildOffers : function(){
		
			// treat filtered array as offerArray
			var offerArray = mcd.privileges.filteredOfferArray;
			var topOfferArray = mcd.privileges.filteredTopOfferArray;
			
			if(offerArray.length > 0) {
				for(var offer in offerArray) {
					var type = mcd.offerHandler.getType(offerArray[offer]);									
					mcd.offerHandler.buildStandardOffer(offerArray[offer]);				
				}						
		 	} else {
		 		mcd.dom.addClass(mcd.privileges.page.offersWrapper, 'hide');
		 	}
			
						
			for(var topOffer in topOfferArray) {
				var type = mcd.offerHandler.getType(topOfferArray[topOffer]);
				mcd.offerHandler.buildTopOffer(topOfferArray[topOffer], type);
			}
			
			// resubmit stored secondary offers (stored in offerhandler during processing)
			mcd.offerHandler.secondary.resubmit();				
								
		}
	},
	
	util : {
		
		/**
		 * Builds DOM node the hard way
		 * 
		 * @param {String} tag
		 * @param {HTMLElement} parent
		 * @param {String} text
		 * @param {Boolean} useInnerHTML
		 * @param {Object} attributes
		 */
		
		createEl : function (tag, parent, text, useInnerHTML, attributes) {
			attributes = attributes || [];
			var el = document.createElement(tag);
		 	for(prop in attributes){
				if(prop === 'class') {
					el.className = attributes[prop];
				}
				else {
					el.setAttribute(prop, attributes[prop]);
				}
			}
			if (text) {
				if(useInnerHTML) {
					el.innerHTML = text;			
				}
				else {
					var text = document.createTextNode(text);
					el.appendChild(text);	
				}
			}
			
			parent.appendChild(el);
			return el;
		},
		
		/**
		 * Clears a container of all its specified children
		 * 
		 * @param {Object} parent
		 * @param {Object} childNodes
		 */
		
		flushContainer : function(parent, childNodes) {	

			var children = parent.getElementsByTagName(childNodes);
			var childrenLength = children.length;
			if(childrenLength > 0) {
				for(var i = childrenLength-1; i >= 0; i--) {
					children[i].parentNode.removeChild(children[i]);
				}
			}
		},
		
		/*
		 * Abstract link activator
		 * 
		 * @param {Object} array
		 * @param {Object} target
		 * @param {Object} check
		 */
		/*activateLink : function(array, target, check) {
			for(var i = 0; i < array.length; i++){
				if(check(array[i]) && !mcd.dom.hasClass(array[i], 'active')) {
					mcd.addClass(array[i], 'active');
				}
				else if(mcd.dom.hasClass(array[i], 'active')){
					mcd.removeClass(array[i], 'active')
				}
			}
		},*/
		
		/**
		 * Checks to see if an Array contains a certain String
		 * (IE6 doesn't support .indexOf() on Arrays)
		 * 
		 * @param {Object} array
		 * @param {Object} string
		 */
		
		contains : function(array, string) {
			for(var i = 0; i < array.length; i++) {
				if(array[i] == string){
					return true;
				}
			}
			return false;
		},
		
		/**
		 * Finds language-specific category names from XML and adds to Array
		 * 
		 * @param {XMLNodeset} node
		 */
		
		setCategories : function(node) {
			var categories = node.getElementsByTagName('categories')[0].getElementsByTagName('category');
			
			for(var i = 0; i < categories.length; i++) {
				mcd.privileges.categories.push(categories[i].childNodes[0].nodeValue);
			}
		},
		
		/**
		 * Assigns default language-specific City option
		 * 
		 * @param {XMLNodeset} node
		 */
		
		setDefaultCity : function(node) {
			mcd.privileges.defaultCity = node.getElementsByTagName('cityDefault')[0].childNodes[0].nodeValue;
			mcd.offerHandler.filter.remove('cities=');
			mcd.privileges.filters.push('cities=' + mcd.privileges.defaultCity);
		},
		
		/**
		 * Assign default language-specific Country option
		 * 
		 * @param {XMLNodeset} node
		 * @param {String} country
		 */
		
		setDefaultCountry : function(node, country) {
			var countries = node.getElementsByTagName('country');
	
			for(var i = 0; i < countries.length; i++) {
				
				var urlName = countries[i].getElementsByTagName('urlName')[0].childNodes[0].nodeValue;
				var realName = countries[i].getElementsByTagName('realName')[0].childNodes[0].nodeValue;			
				var countryDefault = node.getElementsByTagName('countryDefault')[0].childNodes[0].nodeValue;
	
				if(urlName == country){
					document.getElementById('merchant-content').getElementsByTagName('h2')[0].innerHTML = realName + ' ';
					mcd.privileges.defaultCountry = countryDefault;
					return true;
				}
				if(i == countries.length-1) {
					return false;
				}
			}
		},
		
		/**
		 * Finds nearest parent node of a specified tagName
		 * 
		 * @param {String} tag
		 * @param {HTMLElement} reference
		 */
		
		findParent : function(tag, reference) {
		
			while(reference.parentNode){
				reference = reference.parentNode;
				if(reference.tagName == tag.toUpperCase()) {
					return reference;
				}
			}
			return false;
		},
		
		/**
		 * Returns GET variable of specified name
		 * 
		 * @param {String} name
		 */
		
		getParam : function(name) {
			var param = window.location.href.split(name + '=')[1];
			if(!param) return false;
			if(param.indexOf('&') != -1) {
				param = param.split('&')[0]
			}
			if(param.indexOf('#') != -1) {
				param = param.split('#')[0]
			}
			
			return param;
		},
		
		/**
		 * Sets URI Param and redirects page to new location
		 * 
		 * @param {String} name
		 * @param {String} value
		 */
		
		setParam : function(name, value) {
			var href = window.location.href;
			var re = new RegExp(name + '\=[A-Za-z\-]*');
			
			href = href.replace(re, name + '=' + value);
			
			window.location.href = href;
		}
	},
	
	
	/**
	 *  Get initial language XML file
	 */
	
	getSetUpXml : function(){	
		
		mcd.privileges.page.loadingPage();
		
		// get country and language from url
		var country = mcd.privileges.util.getParam('country');
		var language = mcd.privileges.util.getParam('language');
		
		// call basic params
		var response = mcd.xmlHandler.get({
			'uri' : 'assets/xml/languages-countries.xml'
		},
		function(xml){
			var nodes = xml.getElementsByTagName('dinersPrivileges')[0].getElementsByTagName('language');
			var pass = false;
			
			for(var i = 0; i < nodes.length; i++) {
				if(nodes[i].getElementsByTagName('urlName')[0].childNodes[0].nodeValue == language) {
					mcd.privileges.util.setCategories(nodes[i]);
					mcd.privileges.util.setDefaultCity(nodes[i]);
					if(mcd.privileges.util.setDefaultCountry(nodes[i], country)){
						pass = true;
					}
				}
			}
			
			if(pass){
				mcd.privileges.getOffersXml();
			}
			else{
				mcd.privileges.page.error();
			}
			
		});
	},

	/**
	 *  Get language-specific offers XML 
	 */
	
	getOffersXml : function() {
		
		// get country and language from url
		var country = mcd.privileges.util.getParam('country');
		
		// call offers
		var response = mcd.xmlHandler.get({
			'uri' : 'assets/xml/countries/promotions-' + country + '-en.xml'
		}, 
		function(xml){
			
			var nodes = xml.getElementsByTagName('dinersPrivileges')[0].getElementsByTagName('offer');
			var array = mcd.privileges.offerArray;
			
			mcd.xmlHandler.buildArray(nodes, array, mcd.privileges.page.setup);		
		});
	}
}

/**
 * Starts AJAX call on page load 
 */

mcd.dom.ready(mcd.privileges.getSetUpXml);

