/*******************************************************************************
Article.js contains objects used only on Usmf Article pages
Article.prepare() is called in Article.Master
*******************************************************************************/
var Article = {
	prepare : function () {
		
		Fool.onContent(function () {
			//Article.Tickle.hide();
			Article.Curdle.prepare();
			if($('particle')){
				Article.Poll.prepare('particle');
			}
			WWW.MOM.prepare();
			// put in the article corners
			if(!Prototype.Browser.IE6){
				Article.Corners.prepare();
			}
		});

		Fool.onLoad(function() {
				Article.Registration.prepare();
		
				// Set up class name changes to alter appearance when user clicks on switcher links e.g. mostest
				Fool.Util.Switcher.prepareSwitcherLinks();

				//Set numbers on list items in "The Most Foolish"
				Fool.Util.applyNumbers();

				//Show first ticker as selected
				if ($('f_tickerData')) {
					$$('#f_tickerData ul.f_switcher li a').first().className = 'active';
				}

				// Set up onclick functions for links in "The Most Foolish" and "Related Tickers"
				Fool.Util.MostFoolish.prepareMostFoolish();
				Fool.Util.TickerData.prepareTickerData();

				// For each poll button, apply onclick function and block form submission
				$$("#pollData input.button").each( function(btn, n) {
					Event.observe(btn, 'click', function(e) {
						Fool.Util.updatePoll(n == 0 ? true : false);
						Event.stop(e);
					});
				});
			}
		);
	}
};

// this draws the corners on the alp
Article.Corners = {
	prepare : function () {
		var corners = [
			{
				selector : ".round, #secondary .component, .commentHead h6",
				cornerType : "all"
			}
		];
		Fool.Util.Corners.prepare(corners);
	}
};

// This object drives the Article Registration Interrupt
Article.Registration = (function () {

	// Cookie parameters
	var cookies = Fool.Util.Cookies, name = 'Oookie', expiry = (new Date()).inDays(1), path = '/', domain = '.fool.com';

	// Cell ID provided by the MultiVariant test control [Gurtzy says this is a lie.]
	var cellId = cookies.get(name);

	// Fx.Overlay instance which acts as a lightbox, pollInterval is an intervalId
	var overlay, pollInterval, isVisible = false;

	// Ecap doesn't expose any events or callbacks we can hook into to determine
	//	when Ecap has finished processing. Instead we'll just poll the className
	//	of div.ecap, when it has a class of ecapSuccess we'll dismiss the interrupt
	//	after a delay
	var ecap;
	function pollEcapState (doPoll) {
		if (doPoll) {
			pollInterval = setInterval(function () {
				// Redefining ecap here because Firefox isn't updating the reference dynamically
				// when the ecap is in an iframe. (Dunno if it's supposed to...)
				var ecap = $('interrupt').contentWindow.$('regwall').down('div.ecap');
				if (ecap.hasClassName('ecapSuccess')) {
					Article.Registration.dismiss.delay(8);
					pollEcapState(false);
				}
			}, 500);
		} else {
			if (pollInterval) {
				clearInterval(pollInterval);
				pollInterval = null;
			}
		}
	}

	return {
		// Executed onContent, checks if cellId is set
		prepare : function () {
			// If cellId value was retrieved from a cookie, call the interrupt
			// isRegistered is set in GlobalJavascript.cs
			if (!isRegistered && (cellId !== undefined && cellId > 0) && $('interrupt')) {
				ecap = $('interrupt').contentWindow.$('regwall').down('div.ecap');
				this.interrupt();
			}
		},
		interrupt : function () {
			// Domains from which users visit where we may serve an interrupt, seperate additional domains with |
			// Currently matches: "//[optional_3rd/4th_level_domain]fool.com"
			var whitelist = /\/\/[^\s]*fool\.com/;

			// Bail out if either condition is true
			if (isRegistered  || !(whitelist.test(document.referrer))) {
				return false;
			}

			// Show interrupt overlay
			isVisible = true;
			overlay = new Fx.Overlay('interrupt', {
				opacity : .8
			});
			overlay.show();

			// Start listening for changes to Ecap's state
			pollEcapState(true);

			// Invalidate the cookie containing the cellId
			this.invalidateCellId();

			// NOTE: IE6, IE7 and Opera don't support negative text-indent on input[type=button] elements
			// Opera seems finicky in supporting font-coloring or sizing on input[type=button] elements
			// Instead of various CSS hackery or setting a nonsense value in markup,
			// just set the value to something negligible
			if (document.all) {
				ecap.down('input.ecapButton').value = '.';
			}
		},
		dismiss : function () {
			if (isVisible) {
				isVisible = false;
				pollEcapState(false);
				overlay.hide();
			}
		},
		// NOTE: Normally a DFP served ad calls setCellId but we can call it directly for testing
		setCellId : function (id) {
			// Remember the Cell Id in a cookie for 24 hours
			cookies.set(name, id, expiry, path, domain);
		},
		invalidateCellId : function () {
			cookies.set(name, "-1", expiry, path, domain);
		}
	};
})();

Article.Curdle = (function () {
	var container, overlay, isVisible = false;
	
	// Cookie parameters
	var cookies = Fool.Util.Cookies,
								name = 'Oookie',
								expiry = (new Date()).inDays(1), path = '/', domain = '.fool.com';
	
	// checks for an oookie
	var cellId = cookies.get(name);
	
	function hurdle () {
		overlay = new Fx.Overlay(container, { opacity : .8 });
		overlay.show();
		
		isVisible = true;
		invalidateCellId();
	}
	
	function invalidateCellId() {
		cookies.set(name, "-1", expiry, path, domain);
	}
	
	function wireListeners() {
		container.select('a.f_dismiss').each(function (element) {element.observe('click', Article.Curdle.dismiss); });
	}
	
	return {
		prepare : function () {
			container = $('curdle');
			// same rules as regwall
			if (!isRegistered && (cellId !== undefined && cellId > 0) && container) {
				wireListeners();
				hurdle();
			}
		},
		dismiss : function () {
			if (isVisible) {
				isVisible = false;
				overlay.hide();
			}
		}
	}
})();


Article.Tickle = {
	contentElement : null,
	articleTools : null,
	tickle : null,
	controls : null,
	hide : function () {
		var viewportHeight = document.viewport.getHeight();
		var articleHeight = viewportHeight - 400;
		var ticklePosition;
		this.contentElement = $('content');
		this.articleTools = $('articleTools');
		var semiLoggedIn = false;
		var tickleData, numComments, numRecs, tickle, loginLink, registerLink;
		
		var tickleTemplate = new Template('<div id="tickle"><div class="controls clearfix"><a href="#" id="tickleLogin">Login</a> or <a href="#" id="tickleRegister">Register</a> to Keep Reading</div><div class="curl"></div></div>');
		
		if(Fool.Cookie.getCookieValue('Fool','Username','&') != "" && Fool.Cookie.getCookieValue('Fool','Username','&') != "Fool"){
			return false;
		}
		
		tickleData = {controls: tickleData};
		
		var tickleMarkup = tickleTemplate.evaluate(tickleData);
		
		this.contentElement.setStyle({height: articleHeight+"px", overflow: 'hidden'});
		
		ticklePosition = this.contentElement.positionedOffset()[1] + this.contentElement.getHeight();
		
		this.articleTools.insert({before:tickleMarkup});
		
		this.articleTools.setStyle({visibility: 'hidden'});
		
		this.tickle = $('tickle');
		
		loginLink = $('tickleLogin');
		registerLink = $('tickleRegister');
		
		loginLink.observe('click', this.controller);
		registerLink.observe('click', this.controller);
		
		this.tickle.setStyle(
			{
			top: ticklePosition+"px"
			}
		);
		
		
		this.controls = this.tickle.down('div.controls');
		
		var promoAd = $('primary').down('div.promoboxAd');
		if(promoAd != undefined && promoAd != null) promoAd.hide();
	},
	show : function () {
		this.tickle.hide();
		this.contentElement.setStyle({height:'auto'});
		this.articleTools.setStyle({visibility:'visible'});
	},
	showRegPage : function () {
		this.controls.addClassName('ecap');
		new Ajax.Updater(this.controls, '/Ajax/Articles/InlineRegECap.aspx', {
			onComplete : function () {
				$('aspnetForm').observe('submit', function(event){
					Article.Tickle.show();
					Event.stop(event);
				})
			}
			});
	},
	showLoginPage : function () {
		this.controls.addClassName('login');
		new Ajax.Updater(this.controls, '/Common/Ajax/usmf/LoginPage.aspx', {
			onComplete : function () {
				$('aspnetForm').observe('submit', function(event){
					Article.Tickle.show();
					Event.stop(event);
				})
			}
			});
	},
	controller : function (event) {
		if(event.target.id == 'tickleRegister'){
			Article.Tickle.showRegPage();
		}else if (event.target.id == 'tickleLogin'){
			Article.Tickle.showLoginPage();
		}
		Event.stop(event);
	}
}

Article.Poll = (function (){
	var url = '/Ajax/ParticleRequestHandler.ashx',
			container = null,
			question = null,
			results = null,
			footer = null,
			submit = null,
			viewResults = null,
			pollId = null
			selectedOption = null,
			totalWidth = 200;

	function controller(event){
		event.stop();
		var target = event.target;
		var resultData = null;
		switch (target.nodeName) {
			case 'A':
				// view results
				requestResults();
				hideControls('<div class="right"><a href="javascript:window.location.reload();">Return to poll</a></div>');
				break;
			case 'INPUT':
				// vote
				this.selectedOption = getRadioValueOrNull(this.results, null);
				if(this.selectedOption){
					submitVote();
					hideControls(null);
				}else{ // if they didn't select an option just show them the results, mimics previous poll behavior
					requestResults();
					hideControls('<div class="right"><a href="javascript:window.location.reload();">Return to poll</a></div>');
				}
				break;
		}
		
	}

	function requestResults(){
		new Ajax.Request(url, {
			method: 'post',
			parameters: {
				'action':'viewResults',
				'pollId': Article.Poll.pollId
			},
			onSuccess: function (transport){
				displayResults(transport.responseJSON);
			},
			onFailure: function (transport){
				//console.dir(transport);
			}
		})
	}

	function submitVote(){
		new Ajax.Request(url, {
			method: 'post',
			parameters: {
				'action': 'vote',
				'radPoll': Article.Poll.selectedOption,
				'pollId': Article.Poll.pollId
			},
			onSuccess: function (transport){
				displayResults(transport.responseJSON);
			},
			onFailure: function (transport){
				//console.dir(transport);
			}
		})
	}

	function getRadioValueOrNull(parent, name){
		name = name ? name : null;
		var selector = 'input[type=radio]';
		selector += name ? '[name='+name+']' : '';
		var selected = parent.select(selector).find(function(el){ return el.checked ? el.value : null });
		
		return selected ? selected.value : null;
	}

	function hideControls(replacementMarkup){
		if(!replacementMarkup){
			Article.Poll.footer.down('div.right').remove();
		}else{
			Article.Poll.footer.down('div.right').replace(replacementMarkup);
		}
	}

	function displayResults(jsonObj){
		var wrapperTemplate = new Template('<div class="results"><dl>#{contents}</dl>#{ResultsParagraph}</div>');
		
		var rowTemplate = new Template('<dt>#{Answer}</dt><dd><div class="meter"><img src="http://g.fool.com/img/Article/particle/meter_red.gif" height="8" width="#{ImgWidth}" /></div>#{Votes} votes - #{Percentage}%</dd>');
				
		var paragraphTemplate = new Template('<p>#{ResultText}</p><span class="corner ne"></span><span class="corner nw"></span><span class="corner se"></span><span class="corner sw"></span>');
		
		var contents = "";
		
		jsonObj.Choices.each(function(choice){
			choice.ImgWidth = Math.round((choice.Votes/jsonObj.TotalVotes) * totalWidth);
			choice.Percentage = Math.round((choice.Votes/jsonObj.TotalVotes) * 100);
			
			contents += rowTemplate.evaluate(choice);
		});
		
		var ResultsParagraph = paragraphTemplate.evaluate(jsonObj);
		
		var resultsMarkup = wrapperTemplate.evaluate({'contents':contents, 'ResultsParagraph':ResultsParagraph});

		Article.Poll.results.replace(resultsMarkup);
	}


	return {
		prepare : function (containerId){
			this.container = $(containerId);
			this.question = this.container.down('div.question');
			this.results = this.container.down('div.answers');
			this.footer = this.container.down('div.particleFooter');
			this.submit = this.container.down('input.submit');
			this.viewResults = this.container.down('a.viewResults');
			this.pollId = $F('pollId');
			
			// attach event listeners
			this.submit.observe('click', controller.bindAsEventListener(Article.Poll));
			this.viewResults.observe('click', controller.bindAsEventListener(Article.Poll));
		}
	} // end return
})();


/*
 TODO: Refactor into and away from this Fool.Util(Fool.js) or Article (Article.js)...
*/
Object.extend(Fool.Util, {
	//Apply numbered graphics as background images to list items (for The Most Foolish)
	applyNumbers: function() {
		var i=0;
		if(document.getElementById("mostList")) {
			$A($('mostList').getElementsByTagName('li')).each( function(li) {
				i++;
				li.style.backgroundImage = 'url(http://g.fool.com/art/article/mosts/num_' + i + '.gif)';
			});
		}
	},
	/*
	Use with tab-like sets of links where one needs to be shown as active. List must have class "f_switcher".
	Include the following on the page: Event.observe(window, 'load', Fool.Util.Switcher.prepareSwitcherLinks);
	*/
	Switcher: {
		//Set each link to respond to mouse click. Note that there may be more than one set of links.
		prepareSwitcherLinks: function () {
			var switcherLinks = $$('ul.f_switcher li', 'ol.f_switcher li');
			switcherLinks.each(
				function(a) {
					Event.observe(a, 'click', function(event) {Fool.Util.Switcher.resetSwitcherLinks(event)} );
				}
			)
		},

		//Reset the active link
		resetSwitcherLinks: function (event) {
			//Get the link that fired the event
			var trigger = Event.element(event);

			//Set every link in that set of links to class of 'false'. Was going to use removeClassName but IE generates script error
			$A(trigger.parentNode.parentNode.getElementsByTagName('a')).each(
				function(a) {
					a.className = a.className.replace(/active/,"").replace(/^ | $/, "");
				}
			);
			//Set current link to class of 'active' and remove focus
			trigger.className = (trigger.className + " active").replace(/ /, "");
			trigger.blur();
		}
	},


	/*
	Use with Ticker data box. Must call Fool.Util.MostFoolish.prepareTickerData() within page initialization function.
	*/
	TickerData: {

		//Set each link to respond to mouse click. Note that there may be more than one set of links.
		prepareTickerData: function () {
			var tickerLinks = $$('div#f_tickerData ul.f_switcher li');
			tickerLinks.each(
				function(a) {
					Event.observe(a, 'click', function(event) {Fool.Util.TickerData.resetTickerData(event)} );
				}
			)
		},

		//Reset the active link
		resetTickerData: function (event) {
			//Get the link that fired the event, then the ticker and document id.
			var trigger = Event.element(event);
			var ticker = trigger.id.split("_")[0];
			var docId  = trigger.id.split("_")[1];

			//Show "Loading ..." graphic
			Fool.Util.showLoading("relatedTickerData");

			//Make ajax request
			var url = '/ajax/articles/GetArticleTickerData.aspx';
			var params = 'days=7&count=10&tkr=' + ticker + '&did=' + docId;

			var myAjax = new Ajax.Updater(
				'relatedTickerData',
				url,
				{
					method: 'get',
					parameters: params,
					onSuccess : function () {
						// Defer the execution of AddQueryParamsToLinks until the rest of the Ajax.Updater code finishes
						(function () {
							// NOTE: Even if there are no related articles an empty div exists
							var relatedTickerData = $("relatedTickerData");
							if (relatedTickerData) {
								var relatedArticles = relatedTickerData.down("div.articles");
								Fool.Util.AddQueryParamsToLinks(relatedArticles);
							}
						}).defer();
					}
				}
			);

			//Block default link behavior
			Event.stop(event);
		}
	},


	/*
	Use with Most Foolish box. Must call Fool.Util.MostFoolish.prepareMostFoolish() within page initialization function.
	*/
	MostFoolish: {

		//Set each link to respond to mouse click. Note that there may be more than one set of links.
		prepareMostFoolish: function () {
			var mostLinks = $$('div#f_mostest ul li');
			mostLinks.each(
				function(a) {
					Event.observe(a, 'click', function(event) {Fool.Util.MostFoolish.resetMostFoolish(event)} );
				}
			)
		},

		//Reset the active link
		resetMostFoolish: function (event) {
			//Get the link that fired the event, then the thing we are getting most of.
			var trigger = Event.element(event);
			var mostWhat = trigger.innerHTML.toLowerCase();
			if(mostWhat == "read") {
				mostWhat = "popular";
			}

			//Show "Loading ..." graphic
			Fool.Util.showLoading("mostPanel");

			//Make ajax request
			var url = '/ajax/articles/getMost' + mostWhat + 'UrlsData.aspx';
			var params = 'days=7&count=10';

			var myAjax = new Ajax.Updater(
				'mostPanel',
				url,
				{
					method: 'get',
					parameters: params,
					onComplete: Fool.Util.applyNumbers
				}
			);
		}
	},


	//Update poll box after user clicks either Vote or Show Results
	updatePoll: function(update) {
		var url = '/ajax/articles/PollDataProxy.aspx';
		var params = 'poll=results';

		if(update) {
			//Get user selection and add to parameter string.
			//Have to include full radio button name so .cs file will still work with JS off.
			var aRadioBtns = $$('div#pollDataContainer ul li input.radPoll');
			var sValue;
			for(var i=0; i < aRadioBtns.length; i++) {
				if(aRadioBtns[i].checked) {
					sValue = aRadioBtns[i].value;
				}
			}
			if(sValue) {
				params += '&_ctl0%3A_ctl0%3A_ctl0%3ABaseContentPlaceHolder%3AArticleContentPlaceHolder%3ActrlPollData%3AradPoll=' + sValue;
			}
		}

		//Show loading graphic
		Fool.Util.showLoading('pollDataContainer');

		//Make the ajax request
		var myAjax = new Ajax.Updater(
			'pollDataContainer',
			url,
			{
				method: 'post',
				parameters: params,
				evalScripts: true
			}
		);
	}
});


// NOTE: Patch in place for RegistrationInterrupt DFP ad calls which still reference Usmf.Article
Usmf.Article = Article;
