// ==UserScript==
// @name           JSLint highlighter
// @namespace      fcc
// @description    Highlight JSLint errors to expose the biggest problems
// @include        http://jslint.com/
// @include        http://www.jslint.com/
// ==/UserScript==

(function(s){
	var addGlobalStyle = function(css) {
		var head, style;
		head = document.getElementsByTagName('head')[0];
		if (!head) {return;}
		style = document.createElement('style');
		style.className = 'fcc-grease';
		style.type = 'text/css';
		style.toggle = function() {
			if (style.innerHTML==='') {style.innerHTML = css.join("\n");}
			else {style.innerHTML = '';}
		};
		head.appendChild(style);
		style.toggle();
		return style;
	};
	var _ = function(s,d,i) {
		i = i || {};
		for (var p in s) {
			if (!i[p]) {d[p] = s[p];}
		}
	};
	var createToggler = function(o) {
		var body, elm;
		body = document.getElementsByTagName('body')[0];
		if (!body) {return;}
		elm = document.createElement('a');
		elm.href = '#on';
		elm.innerHTML = 'Greased';
		_({
			position:'fixed',
			right:'0px',
			top:'0px',
			backgroundColor:'#090',
			color:'#fff',
			cursor:'pointer',
			textDecoration:'none',
			padding:'.5em',
			zIndex:'999',
			fontSize:'10px',
			fontFamily:'Helvetica,Arial,sans-serif'
		}, elm.style);
		body.appendChild(elm);
		var fn = function(ev) {
			var ison = elm.href.indexOf('#on')>0;
			elm.style.backgroundColor = ison? '#900' : '#090';
			elm.href = ison? '#off' : '#on';
			o.toggle(ison);
			if (ev) {ev.preventDefault();}
		};
		elm.addEventListener('click',fn, false);
		window.addEventListener('keypress',function(ev) {
			if (ev.altKey && ev.charCode==103) {fn();}
		}, false);
	};
	// set
	var getColor = function(t) {
		var problems = {
			"Bad escapement" : "green",
			"Be careful when making functions within a loop." : "green",
			"Unnecessary escapement." : "green",
			"Parens are not needed here" : "yellow",
			"Expected an assignment or function call and" : "green",
			"The body of a for in should be wrapped in an if statement" : "yellow",
			"Unexpected escaped character" : "green",
			"to have an indentation of" : "green"
		};
		for (var p in problems) {
			if (t.indexOf(p)>=0) {return problems[p];}
		}
		return "red";
	};
	var highlightErrors = function() {
		var t = document.getElementById('errors');
		if (!t) {return;}
		var ps = t.getElementsByTagName('p');
		for (var i=0,j=ps.length;i<j;i++) {
			if (ps[i].className=='evidence') {
				var prob = ps[i-1];
				var evid = ps[i];
				var c = getColor(prob.innerHTML);
				prob.className = (prob.className==='')? c : prob.className+' '+c;
				evid.className = (evid.className==='')? c : evid.className+' '+c;
			}
		}
	};
	var checkOutput = function() {
		return setTimeout(function() {
			var d = document.getElementById('output');
			if (d.innerHTML!=arguments.callee.h) {
				arguments.callee.h = d.innerHTML;
				if (d.innerHTML) {highlightErrors();}
			}
			setTimeout(arguments.callee,500);
		},500);
	};
	var timer = checkOutput();
	var style = addGlobalStyle(s);
	createToggler({
		toggle:function(ison){
			if (ison) {clearTimeout(timer);}
			else {timer = checkOutput();}
			style.toggle();
		}
	});
})([
	'#errors p {padding:.5em 0 .5em 1em;margin:0;border-left:10px solid #ccc;}',
	'#errors p.evidence {padding:0 0 1em 2em;border-bottom:1px solid #ccc;margin-bottom:1px;}',
	'#errors p.yellow {border-left-color:yellow;background:#ffd;}',
	'#errors p.green {border-left-color:green;background:#dfd;}',
	'#errors p.red {border-left-color:red;background:#fdd;}',
	'#errors p.grey {border-left-color:grey;background:#ddd;}'
]);
