// ==UserScript==
// @name           CurrencyMunger
// @namespace      http://www.techbelly.com/currency_munge
// @description    Munges Currencies on Guardian Site
// @include        http://*.guardian.co.uk/*
// ==/UserScript==


(function () {

	var win = window;
	var currencyRegExp = new RegExp('(\u00A3|\\$)(\\d[\\d,\.]*)\\s?((bn)|(billion)|(m)|(million)|(k)|(thousand)|(trillion)|(tn))?');
	win.CurrencyMunger = function() {;}

	function addGlobalStyles(css) {
	    var head, style;
	    head = document.getElementsByTagName('head')[0];
	    if (!head) { return; }
	    style = document.createElement('style');
	    style.type = 'text/css';
	    style.innerHTML = css;
	    head.appendChild(style);
	}

	addGlobalStyles(
		'.money_equivalent { color: #990000 ! important; font-weight: bold;} '+
		'.money_menu {position:fixed; top: 80px; left:480px; padding: 20px; background: #eee; border: 2px solid; font-size:80%}');

	var conversion_factors = {
		"teachers" : { "text": "the cost of employing [[number]] new teachers", "factor": 20427 },
		"schools" : {"text": "the cost of building [[number]] new schools", "factor": 25000000},
		"per uk person" : {"text": "£[[number]] for every man, woman and child in the UK", "factor": 66000000},
		"afghanistan": {"text": "[[number]]% of the uk operational cost of the Afghanistan war", "factor": 7440000},
		"wispa": {"text": "the cost of [[number]] Wispas", "factor": 0.46},
		"pound years": {"text": "£1 every second for [[number]] years", "factor": 31556926 },
		"tonnes of pennies": {"text": "[[number]] tonnes of pennies", "factor": 2857},
		"ross years": {"text": "[[number]] years of Jonathan Ross's salary", "factor": 6000000},
		"ten pound notes": {"text": "[[number]]% of ten pound notes in circulation", "factor": 560000000}
	};

	win.CurrencyMunger.prototype = {
		
		init: function() {
			this.create_menu();
		},
		
		create_menu: function() {
		  var menu = '<li><b>Swap numbers</b></li>';
		  for (var i in conversion_factors) {
		    menu += '<li><a onclick="window.munger.replace_numbers(\''+i+'\')">' + i + '</a></li>';
		  };
		  menu += '<li><a onclick="window.munger.remove_previous()">[x] remove</a></li>';
		
		  if (menu != '') {
		    menuobj = document.createElement('ul');
		    menuobj.className = "money_menu"
		    menuobj.innerHTML = menu;
		    body = document.getElementsByTagName('body')[0];
		    body.appendChild(menuobj);
		  };
		},
		
		remove_previous: function() {
			var equivalents = document.evaluate("//span[@class='money_equivalent']", document.body,
								   null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
			for (var i = 0; i < equivalents.snapshotLength; i++) {
				var equivalent = equivalents.snapshotItem(i);
				equivalent.parentNode.removeChild(equivalent);
			};
		},
		
		human_readable: function(number) {
			var suffix = '';
			if (number > Math.pow(10,12)) {
				suffix = ' trillion';
				number = number / Math.pow(10,12);
			};
			if (number > Math.pow(10,9)) {
				suffix = ' billion';
				number = number / Math.pow(10,9);
			};
			if (number > Math.pow(10,6)) {
				suffix = ' million';
				number = number / Math.pow(10,6);
			};
			number = Math.round(number*100)/100 // two decimal digits
		    number += ''; // must be a better way to convert to a string?
		    parts = number.split('.');
		    whole_num = parts[0];
		    decimal = parts.length > 1 ? '.' + parts[1] : '';
		    var regexp = /(\d+)(\d{3})/;
		    while (regexp.test(whole_num))
		        whole_num = whole_num.replace(regexp, '$1' + ',' + '$2');
		    return  whole_num + decimal + suffix;
		},
		
		munge: function(matches,requested_scale,article) {
			amount = parseFloat(matches[2].replace(/,/g,''));

			if (matches[1] == '$') {
				amount = amount * 0.68 // dollar pound exchange rate
			}
			
			switch (matches[3]) {
				case 'trillion': 
				case 'tn':
					amount = amount * Math.pow(10,12); break;
				
				case 'billion':
				case 'bn': amount = amount * Math.pow(10,9); break;
				
				case 'million':
				case 'm': amount = amount * Math.pow(10,6); break;
				
				case 'thousand':
				case 'k': amount = amount * Math.pow(10,3); break;
			}
			
			var scale = conversion_factors[requested_scale]
			var factor = scale["factor"];
			var number = Math.round(amount / factor);
			var text = scale["text"].replace('[[number]]',this.human_readable(number));
			if (number > 0) {
				var equivalent = " ("+text+") ";
				var insert = document.createElement('span');
				insert.className = "money_equivalent";
				insert.appendChild(document.createTextNode(equivalent));
				article.parentNode.insertBefore(insert,article);
			}
		},
		
		replace_numbers: function(requested_scale) {
			this.remove_previous();
			var articleDivX = document.evaluate("//text()[ancestor::div[@id='article-wrapper']]", document.body,
								   null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
			for (var i = 0; i < articleDivX.snapshotLength; i++) {
				var article = articleDivX.snapshotItem(i);
				var articleText = article.nodeValue;
				var matches = currencyRegExp.exec(articleText);
				while (matches) {
					var searchIndex = matches.index;
					article.splitText(searchIndex + matches[0].length);
					article = article.nextSibling;
										
					this.munge(matches,requested_scale,article);
					
					articleText = article.nodeValue; 
					matches = currencyRegExp.exec(articleText);
				}
			}
		}

	};
	
	try {
		window.addEventListener("load", function () {
			unsafeWindow.munger = new win.CurrencyMunger();
			unsafeWindow.munger.init();		
		}, false);
	} catch (ex) {}

})();

