var Erqqvg = new Class({
	Implements: [Options],
	options: {
		page: ''
	},
	live: '',
	positionTop: new Array(0, 0),
	anitime: 250,
	placements: new Array(0),
	updatenum: 0,
	loader: '',
	pruneCount: 0,
	lastprune: 0,
	theRequest: '',
	subreddit: '',
	defaultInterval: 1000,
	labels: {
		'comments': {
			'label': ' Comments',
			'color': '#f7f8a7'
		},
		'score': {
			'label': ' Points',
			'color': '#edfcff'
		},
		'upvotes': {
			'label': ' Upvotes',
			'gaincolor': '#e4f8ce',
			'losecolor': '#f8cece'
		},
		'downvotes': {
			'label': ' Downvotes',
			'gaincolor': '#f8cece',
			'losecolor': '#e4f8ce'
		}
	},
	initialize: function (options) {
		this.setOptions(options);
		switch (this.options.page) {
		case 'front':
			$('navbar_frontpage').addClass("selected");
			this.listInit();
			break;
		case 'subreddit':
			if (console) {
				console.log('subreddit option');
			}
			//$('navbar_subreddit').addClass("selected");
			this.listInit();
			break;
		case 'single':
			//$('navbar_single').addClass("selected");
			this.singleInit();
			break;
		case 'popreddit':
			$('navbar_popreddits').addClass("selected");
			this.popredditInit();
			break;
		case 'stats':
			//$('navbar_stats').addClass("selected");
			this.statsInit();
			break;
		case 'comments':
			$('navbar_comments').addClass("selected");
			this.commentsInit();
			break;
		}
	},
	listInit: function () {
		if (console) {
			console.log('listInit');
		}
		this.live = $('live');
		this.createRanks();
		this.createRequest(this.listingInitialBuild.bind(this), this.listingProcessData.bind(this));
		this.loader = setInterval(function () {
			this.listDoOnInterval();
		}.bind(this), 30000);
	},
	singleInit: function () {
		this.graphnum = 0;
		this.arrayUpvotes = new Array();
		this.arrayDownvotes = new Array();
		this.arrayScore = new Array();
		this.arrayComments = new Array();
		this.storylink = "";
		if (window.location.toString().indexOf('?') == -1) {
			this.getNewStory();
		} else {
			this.storylink = window.location.toString().split('?');
			this.storylink = this.storylink[this.storylink.length - 1];
		}
		this.upvotes = $('upvotes').store('gaincolor', '#e4f8ce').store('losecolor', '#f8cece').store('value', $('upvotes').getFirst());
		this.downvotes = $('downvotes').store('gaincolor', '#f8cece').store('losecolor', '#e4f8ce').store('value', $('downvotes').getFirst());;
		this.score = $('score').store('color', '#edfcff').store('value', $('score').getFirst());;
		this.comments = $('comments').store('color', '#f7f8a7').store('value', $('comments').getFirst());
		this.ogcolor = this.upvotes.getStyle('background-color');
		// Animation objects
		this.upvotes.store('ani', new Fx.Morph(this.upvotes, {
			wait: false,
			duration: 250
		}));
		this.downvotes.store('ani', new Fx.Morph(this.downvotes, {
			wait: false,
			duration: 250
		}));
		this.score.store('ani', new Fx.Morph(this.score, {
			wait: false,
			duration: 250
		}));
		this.comments.store('ani', new Fx.Morph(this.comments, {
			wait: false,
			duration: 250
		}));
		var url = 'singleproxy.php?initial=true&story=' + encodeURIComponent(this.storylink) + '&nocache=' + $random(0, 9999999)
		this.theRequest = new Request.JSON({
			'url': url,
			'method': 'get',
			'onSuccess': this.singleInitialBuild.bind(this),
			'onFailure': this.goToFail
		});
		this.theRequest.send();
		this.theRequest = new Request.JSON({
			'method': 'get',
			'onSuccess': this.singleProcessData.bind(this),
			'onFailure': this.goToFail
		});
		this.loader = setInterval(function () {
			url = 'singleproxy.php?initial=false&story=' + encodeURIComponent(this.storylink) + '&nocache=' + $random(0, 9999999);
			this.theRequest.send({
				'url': url
			});
		}.bind(this), 30000);
	},
	popredditInit: function () {
		new Request.JSON({
			'url': 'popredditsproxy.php?popreddits=true',
			'method': 'get',
			'onSuccess': this.buildChart,
			'onFail': this.goToFail
		}).send();
	},
	statsInit: function () {
		this.theRequest = new Request.JSON({
			'method': 'get',
			'onSuccess': this.buildStats.bind(this),
			'onFail': this.goToFail
		});
		this.theRequest.send({
			'url': 'stats.php?nocache=' + $random(0, 9999999)
		});
		this.loader = setInterval(function () {
			this.theRequest.send({
				'url': 'stats.php?nocache=' + $random(0, 9999999)
			});
		}.bind(this), 30000);
	},
	//used on frontpage and subreddit
	listDoOnInterval: function () {
		this.theRequest.send({
			'url': this.url + $random(0, 9999999)
		});
		if (this.pruneCount == 4) {
			this.prune();
			this.pruneCount = 0;
		} else {
			this.pruneCount++;
		}
	},
	createRanks: function () {
		var ranks = new Element('div', {
			id: 'ranks'
		}).inject(this.live);
		for (var x = 1; x <= 25; x++) {
			new Element('div', {
				text: x
			}).inject(ranks);
		}
		var height = $('ranks').getElement('div').getStyle('height').toInt()
		var marginBottom = $('ranks').getElement('div').getStyle('margin-bottom').toInt()
		for (var x = 2; x <= 25; x++) {
			this.positionTop[x] = (height + marginBottom) * (x - 1);
		}
	},
	ballProgress: function () {
		if (Browser.Engine.trident && Browser.Engine.version < 5) {
			return;
		}
		var filler = $('slownotice').getElement('.filler')
		if (filler.getStyle('width').toInt() != 0) {
			var width = "0px";
			filler.setStyles({
				'left': 'auto',
				'right': '0px'
			});
		} else {
			var width = $('slownotice').getWidth('px');
			filler.setStyles({
				'left': '0px',
				'right': 'auto'
			});
		}
		new Fx.Morph(filler, {
			wait: false,
			duration: 30000
		}).start({
			'width': width
		}).chain(function () {
			if ($chk($('slownotice'))) {
				this.ballProgress();
			}
		}.bind(this))
	},
	makeViewLinks: function () {
		new Element('a', {
			'href': '/' + ((this.options.page == 'subreddit') ? 'subreddit/?' + this.subreddit : ''),
			'class': (this.sort == "hot") ? 'viewing' : '',
			'text': 'hot'
		}).inject($('viewlinks')).addClass('vlink');
		['new', 'rising', 'top', 'controversial'].each(function (v) {
			new Element('a', {
				'href': '/' + ((this.options.page == 'subreddit') ? 'subreddit/?' + this.subreddit + '/' : '?') + v,
				'class': (this.sort == v) ? 'viewing' : '',
				'text': v
			}).inject($('viewlinks')).addClass('vlink');
		}.bind(this))
		$('viewlinks').setStyle('display', '');
	},
	createRequest: function (initialCallback, repeatCallback) {
		if (console) {
			console.log('createRequest');
		}
		if (this.options.page == 'subreddit') {
			if (console) {
				console.log('subreddit page');
			}
			this.createSubredditRequest(initialCallback, repeatCallback);
			return;
		}
		var url = window.location.href.split('?')[1];
		if (undefined == url) {
			url = '';
			this.sort = 'hot';
		} else {
			url = url.split('/'); //solve trailing slash issues
			if ('rising' == url[1]) { // someone did new/rising
				this.sort = 'rising';
				url = '&sort=rising';
			} else {
				this.sort = url[0];
				url = '&sort=' + url[0];
			}
		}
		var initialUrl = 'frontpageproxy.php?initial=true&nocache=' + $random(0, 99999999) + url;
		this.theRequest = new Request.JSON({
			url: initialUrl,
			method: 'get',
			onSuccess: initialCallback,
			onFailure: this.goToFail
		});
		this.theRequest.send();
		this.url = 'frontpageproxy.php?initial=false' + url + '&nocache=';
		this.theRequest = new Request.JSON({
			method: 'get',
			onSuccess: repeatCallback,
			onFailure: this.goToFail
		});
	},
	listingInitialBuild: function (r) {
		if (r == null) {
			this.goToFail();
			return;
		}
		if (this.options.page == 'subreddit' && r.fail == true) { //bad subreddit
			this.getNewSubreddit();
			return;
		} else if (this.options.page == 'subreddit') {
			if (r.data.children[0] != null) {
				var subreddit = r.data.children[0].data.subreddit;
			} else {
				var subreddit = this.subreddit;
			}
			document.title = 'Erqqvg - ' + subreddit;
			new Element('a', {
				'text': subreddit,
				'href': 'http://www.reddit.com/r/' + subreddit
			}).inject('subreddittitle');
			$('subreddittitle').setStyle('display', '');
		} else if (r.fail) { //general failure
			this.goToFail();
			return;
		}
		this.ballProgress();
		this.makeViewLinks();
		if (this.sort == 'hot' && this.options.page == 'front' && $defined(r[0])) { //prepare to facilitate immediate action for the default view
			var secondInitial = r[1];
			r = r[0];
		}
		r.data.children.each(function (a, b) {
			var li = this.createListing(a.data);
			var rank = b + 1;
			li.store('rank', rank);
			setTimeout(function () {
				li.setStyle('top', this.positionTop[rank] - 50).retrieve('ani').start({
					'top': this.positionTop[rank],
					'opacity': 1
				});
			}.bind(this), this.anitime * b);
		}.bind(this))
		$('live').setStyle('height', $('ranks').getHeight() + 'px')
		if (this.sort == 'hot' && this.options.page == 'front' && $defined(secondInitial)) { //facilitate immediate action for the default view
			setTimeout(function () {
				this.listingProcessData(secondInitial);
			}.bind(this), this.anitime * (r.data.children.length + 3))
		}
	},
	listingProcessData: function (r) {
		if (r == null || r.fail == true) {
			this.goToFail();
			return;
		}
		this.updatenum++;
		r.data.children.each(function (a, b) {
			if ($(a.data.id) == null) {
				this.createListing(a.data);
			}
			this.listingPrepareCrements(a.data.id, 'upvotes', a.data.ups);
			this.listingPrepareCrements(a.data.id, 'downvotes', a.data.downs);
			this.listingPrepareCrements(a.data.id, 'comments', a.data.num_comments);
			this.move(a.data.id, b + 1);
		}.bind(this))
		this.hideHidden(); //Now that's a classy function name
	},
	createListing: function (data) {
		if (data.url.indexOf('http://') == -1) {
			data.url = 'http://reddit.com' + data.url;
		}
		var listing = new Element('div', {
			'id': data.id,
			'class': 'listing',
			'styles': {
				'opacity': 0
			}
		});
		data.title = data.title.replace(/&lt;/g, '<');
		data.title = data.title.replace(/&gt;/g, '>');
		data.title = data.title.replace(/&amp;/g, '&');
		data.title = data.title.replace(/&quot;/g, '"');
		new Element('a', {
			'href': data.url.replace(/&amp;/g, '&'),
			'title': data.title,
			'class': 'title',
			'text': this.truncate(data.title, 147),
			'target': '_blank'
		}).inject(listing)
		var listingInfo = new Element('div', {
			'class': 'listingInfo'
		}).inject(listing)
		var score = new Element('div', {
			'class': 'score',
			'text': data.score + this.labels['score']['label']
		}).inject(listingInfo)
		var upvotes = new Element('div', {
			'class': 'upvotes',
			'text': data.ups + this.labels['upvotes']['label']
		}).inject(listingInfo)
		var downvotes = new Element('div', {
			'class': 'downvotes',
			'text': data.downs + this.labels['downvotes']['label']
		}).inject(listingInfo)
		var comments = new Element('div', {
			'class': 'comments',
			'text': ''
		}).inject(listingInfo)
		new Element('a', {
			'href': 'http://reddit.com/r/' + data.subreddit + '/comments/' + data.id + '/',
			'text': data.num_comments + this.labels['comments']['label']
		}).inject(comments)
		var author = new Element('div', {
			'class': 'author',
			'text': 'By '
		}).inject(listingInfo)
		new Element('a', {
			'href': 'http://reddit.com/user/' + data.author,
			'text': data.author
		}).inject(author);
		if (this.options.page == "front") {
			var subreddit = new Element('div', {
				'class': 'subreddit',
				'text': ''
			}).inject(listingInfo);
			new Element('a', {
				'href': '/subreddit/?' + data.subreddit,
				'text': data.subreddit
			}).inject(subreddit);
		}
		var storylink = new Element('div', {
			'class': 'storylink',
			'text': ''
		}).inject(listingInfo);
		new Element('a', {
			'href': '/single/?http://www.reddit.com/r/' + data.subreddit + '/comments/' + data.id + '/',
			'text': 'Info'
		}).inject(storylink);
		var domain = new Element('div', {
			'class': 'site',
			'text': '('
		}).inject(listingInfo)
		new Element('a', {
			'href': 'http://reddit.com/domain/' + data.domain,
			'text': data.domain
		}).inject(domain);
		domain.appendText(')');
		listing.inject(this.live);
		listing.store('ani', new Fx.Morph(listing, {
			wait: false,
			duration: this.defaultInterval,
			transition: Fx.Transitions.Linear
		}))
		score.store('ani', new Fx.Morph(score, {
			wait: false,
			duration: 250
		}))
		upvotes.store('ani', new Fx.Morph(upvotes, {
			wait: false,
			duration: 250
		}))
		downvotes.store('ani', new Fx.Morph(downvotes, {
			wait: false,
			duration: 250
		}))
		comments.store('ani', new Fx.Morph(comments, {
			wait: false,
			duration: 250
		}))
		return listing;
	},
	truncate: function (string, length) {
		if (string.length > length - 3) {
			var string = string.substring(0, length - 3) + '...';
		}
		return string;
	},
	listingPrepareCrements: function (id, type, newVal) {
		if (type == 'comment') {
			var oldVal = $(id).getElement('.' + type).getElement('a').toInt()
		} else {
			var oldVal = $(id).getElement('.' + type).get('text').toInt();
		}
		if (oldVal < newVal) {
			for (var i = oldVal; i <= newVal; i++) {
				setTimeout(function () {
					this.listingCrement(id, type, 1);
				}.bind(this), $random(250, 29000))
			}
		} else if (oldVal > newVal) {
			for (var i = oldVal; i >= newVal; i--) {
				setTimeout(function () {
					this.listingCrement(id, type, -1);
				}.bind(this), $random(250, 29000))
			}
		}
	},
	listingCrement: function (id, cls, amount) {
		if ($chk($('slownotice'))) {
			$('slownotice').destroy();
		}
		if (cls == 'upvotes' || cls == 'downvotes') {
			if (amount == 1) {
				var colortype = 'gaincolor'
			} else {
				var colortype = 'losecolor';
			}
		} else {
			var colortype = 'color';
		}
		var el = $(id).getElement('.' + cls);
		if (cls == 'comments') {
			var dataEl = el.getElement('a');
		} else {
			var dataEl = el;
		}
		current = dataEl.get('text').toInt();
		dataEl.set('text', (current + amount) + this.labels[cls]['label'])
		el.retrieve('ani').start({
			'background-color': this.labels[cls][colortype]
		}).chain(function () {
			el.retrieve('ani').start({
				'background-color': '#FFF'
			})
		})
		if (cls == 'upvotes') {
			this.listingCrement(id, 'score', amount);
		} else if (cls == 'downvotes') {
			this.listingCrement(id, 'score', amount * -1);
		}
	},
	move: function (id, newPosition) {
		var el = $(id);
		el.store('updatenum', this.updatenum);
		if (el.getStyle('top') != this.positionTop[newPosition] + 'px' && $chk($('slownotice'))) {
			$('slownotice').destroy();
		}
		if (el.getStyle('opacity') == 0) {
			var hidden = true;
		}
		if (hidden == true) {
			el.setStyle('top', this.positionTop[newPosition] + 'px').retrieve('ani').start({
				'opacity': 1
			});
		} else {
			el.retrieve('ani').start({
				'top': this.positionTop[newPosition] + 'px'
			});
		}
	},
	hideHidden: function () {
		$$('.listing').each(function (el, index) {
			if (el.getStyle('opacity') != 0 && el.retrieve('updatenum') != this.updatenum) {
				el.retrieve('ani').start({
					'top': el.getStyle('top').toInt() + 50 + 'px',
					'opacity': 0
				});
			}
		}.bind(this))
	},
	getByRank: function (r) {
		var result = $$('#live div').filter(function (el, i) {
			if (el.retrieve('rank') == r) {
				return true;
			}
			return false;
		});
		return result[0];
	},
	prune: function () {
		$$('.listing').each(function (el, index) {
			if (el.getStyle('opacity') == 0 && el.retrieve('updatenum') < this.lastprune) {
				el.destroy();
			}
		}.bind(this))
		this.lastprune = this.updatenum;
	},
	//Used only by Subreddit
	createSubredditRequest: function (initialCallback, repeatCallback) {
		if (console) {
			console.log('create subreddit');
		}
		if (window.location.toString().indexOf('?') != -1) {
			this.subreddit = window.location.toString().split('?');
			this.subreddit = this.subreddit[this.subreddit.length - 1];
			var sort = this.subreddit.split('/');
			if (sort[1] != undefined) {
				if (sort[2] == 'rising') {
					sort[1] = 'rising';
				}
				this.sort = sort[1];
				this.subreddit = sort[0];
				sort = '&sort=' + this.sort;
			} else {
				this.sort = 'hot';
				sort = '';
			}
		} else {
			this.getNewSubreddit();
			return;
		}
		var url = 'subredditsproxy.php?initial=true&subreddit=' + this.subreddit + sort + '&nocache=' + $random(0, 99999999);
		this.theRequest = new Request.JSON({
			url: url,
			method: 'get',
			onSuccess: initialCallback,
			onFailure: this.goToFail
		});
		this.theRequest.send();
		this.url = 'subredditsproxy.php?initial=false&subreddit=' + this.subreddit + sort + '&nocache=';
		this.theRequest = new Request.JSON({
			method: 'get',
			onSuccess: repeatCallback,
			onFailure: this.goToFail
		});
	},
	getNewSubreddit: function () {
		if (this.subreddit != "") {
			$('badmsg').set({
				'styles': {
					'color': '#c00'
				},
				'text': 'The subreddit you provided does not appear to be a valid subreddit.  Please enter a valid subreddit:'
			})
		} else {
			$('badmsg').set('text', 'Please enter the name of the subreddit you wish to view live:');
		}
		clearInterval(this.loader);
		$('badsubredditnotice').setStyle('display', '');
		$('ranks').setStyle('display', 'none');
		$('slownotice').setStyle('display', 'none');
		$('submitsubreddit').addEvent('click', function () {
			this.changeSubreddit($('inputsubreddit').value)
		}.bind(this))
		$('inputsubreddit').addEvent('keyup', function (e) {
			if (e.code == 13) {
				this.changeSubreddit($('inputsubreddit').value)
			}
		}.bind(this))
	},
	changeSubreddit: function (newsr) {
		window.location = "/subreddit/?" + newsr;
	},
	//Used only by Single
	singleInitialBuild: function (r) {
		if (r == null) {
			this.goToFail();
			return;
		}
		if (r.fail == true) {
			this.getNewStory();
			return;
		}
		r = r[0].data.children[0].data;
		r.title = r.title.replace(/&lt;/g, '<');
		r.title = r.title.replace(/&gt;/g, '>');
		r.title = r.title.replace(/&amp;/g, '&');
		r.title = r.title.replace(/&quot;/g, '"');
		document.title = 'Erqqvg - ' + this.truncate(r.title, 100);
		$('storytitle').set('text', '');
		new Element('a', {
			'text': r.title,
			'href': "http://www.reddit.com/r/" + r.subreddit + '/comments/' + r.id + '/'
		}).inject('storytitle');
		this.ballProgress();
		this.singleCrement(this.comments, r.num_comments);
		this.singleCrement(this.upvotes, r.ups);
		this.singleCrement(this.downvotes, r.downs);
	},
	singleProcessData: function (r) {
		if (r == null || r.fail == true) {
			this.goToFail();
			return;
		}
		r = r[0].data.children[0].data
		this.singlePrepareCrements(this.comments, r.num_comments);
		this.singlePrepareCrements(this.upvotes, r.ups);
		this.singlePrepareCrements(this.downvotes, r.downs);
		if ($('slownotice').getStyle('display') == "none") {
			this.addGraphData(r);
		}
	},
	addGraphData: function (r) {
		// Comments
		var oldC = this.comments.retrieve('value').get('text').toInt();
		var addC = r.num_comments - oldC;
		var commentsAdd = this.makeGraphData(oldC, addC);
		// Upvotes
		var oldU = this.upvotes.retrieve('value').get('text').toInt();
		var addU = r.ups - oldU;
		var upvotesAdd = this.makeGraphData(oldU, addU);
		// Downvotes
		var oldD = this.downvotes.retrieve('value').get('text').toInt();
		var addD = r.downs - oldD;
		var downvotesAdd = this.makeGraphData(oldD, addD);
		// Score
		var oldS = this.score.retrieve('value').get('text').toInt();
		var scoreAdd = new Array();
		scoreAdd.push(oldS + ((upvotesAdd[0] - oldU) - (downvotesAdd[0] - oldD)));
		scoreAdd.push(oldS + ((upvotesAdd[1] - oldU) - (downvotesAdd[1] - oldD)));
		scoreAdd.push(oldS + ((upvotesAdd[2] - oldU) - (downvotesAdd[2] - oldD)));
		this.graphnum++;
		this.arrayUpvotes.push(new Array(this.graphnum, upvotesAdd[0]));
		this.arrayDownvotes.push(new Array(this.graphnum, downvotesAdd[0]));
		this.arrayScore.push(new Array(this.graphnum, scoreAdd[0]));
		this.arrayComments.push(new Array(this.graphnum, commentsAdd[0]));
		this.drawGraphs();
		$('csv').set('value', $('csv').value + "\n" + (new Array(this.graphnum * 10, scoreAdd[0], upvotesAdd[0], downvotesAdd[0], commentsAdd[0]).join(',')));
		setTimeout(function () {
			this.graphnum++;
			this.arrayUpvotes.push(new Array(this.graphnum, upvotesAdd[1]));
			this.arrayDownvotes.push(new Array(this.graphnum, downvotesAdd[1]));
			this.arrayScore.push(new Array(this.graphnum, scoreAdd[1]));
			this.arrayComments.push(new Array(this.graphnum, commentsAdd[1]));
			this.drawGraphs();
			$('csv').set('value', $('csv').value + "\n" + (new Array(this.graphnum * 10, scoreAdd[1], upvotesAdd[1], downvotesAdd[1], commentsAdd[1]).join(',')));
		}.bind(this), 10000);
		setTimeout(function () {
			this.graphnum++;
			this.arrayUpvotes.push(new Array(this.graphnum, upvotesAdd[2]));
			this.arrayDownvotes.push(new Array(this.graphnum, downvotesAdd[2]));
			this.arrayScore.push(new Array(this.graphnum, scoreAdd[2]));
			this.arrayComments.push(new Array(this.graphnum, commentsAdd[2]));
			this.drawGraphs();
			$('csv').set('value', $('csv').value + "\n" + (new Array(this.graphnum * 10, scoreAdd[2], upvotesAdd[2], downvotesAdd[2], commentsAdd[2]).join(',')));
		}.bind(this), 20000);
	},
	makeGraphData: function (cur, add) {
		var temp = new Array();
		var mod = add % 3;
		if (mod == 0) {
			var toPush = add / 3;
			temp.push(cur + toPush);
			temp.push(cur + toPush + toPush);
			temp.push(cur + add);
		} else if (mod == 1) {
			var toPush = (add / 3).toInt();
			temp.push(cur + toPush);
			temp.push(cur + toPush + toPush + 1);
			temp.push(cur + add);
		} else { //mod == 2
			var toPush = (add / 3).round().toInt();
			temp.push(cur + toPush);
			temp.push(cur + toPush + toPush - 1);
			temp.push(cur + add);
		}
		return temp;
	},
	drawGraphs: function () {
		if (this.arrayUpvotes.length < 2) {
			return;
		}
		this.drawGraph($('upvotesChart'), this.arrayUpvotes, 'Up Votes', '#8aca56');
		this.drawGraph($('downvotesChart'), this.arrayDownvotes, 'Down Votes', '#ca5656');
		this.drawGraph($('scoreChart'), this.arrayScore, 'Score', '#57b8e6');
		this.drawGraph($('commentsChart'), this.arrayComments, 'Comments', '#e8e118');
	},
	drawGraph: function (container, thedata, label, thecolor) {
		var limits = this.minmax(thedata);
		var f = Flotr.draw(
		container, [{
			'data': thedata,
			'label': label,
			'color': thecolor,
			'lines': {
				'fill': true
			}
		}, ], {
			xaxis: {
				noTicks: 0
			},
			yaxis: {
				noTicks: 5,
				min: limits.min - 5,
				max: limits.max + 5
			},
			grid: {
				outlineWidth: 1,
				color: '#ccc'
			}
		});
	},
	singlePrepareCrements: function (el, newVal) {
		var oldVal = el.retrieve('value').get('text').toInt();
		if (oldVal != newVal) {
			$('slownotice').setStyle('display', 'none');
		}
		if (oldVal < newVal) {
			for (var i = oldVal; i <= newVal; i++) {
				setTimeout(function () {
					this.singleCrement(el, 1)
				}.bind(this), $random(250, 29000))
			}
		} else if (oldVal > newVal) {
			for (var i = oldVal; i >= newVal; i--) {
				setTimeout(function () {
					this.singleCrement(el, -1)
				}.bind(this), $random(250, 29000))
			}
		}
	},
	singleCrement: function (el, amount) {
		if (el == this.upvotes || el == this.downvotes) {
			if (amount >= 1) {
				var color = el.retrieve('gaincolor');
			} else {
				var color = el.retrieve('losecolor');
			}
			if (el == this.upvotes) {
				this.singleCrement(this.score, amount);
			} else {
				this.singleCrement(this.score, amount * -1);
			}
		} else {
			var color = el.retrieve('color');
		}
		var valuespan = el.retrieve('value');
		var oldValue = valuespan.get('text').toInt();
		oldValue = (isNaN(oldValue)) ? 0 : oldValue;
		valuespan.set('text', oldValue + amount);
		el.retrieve('ani').start({
			'background-color': color
		}).chain(function () {
			this.start({
				'background-color': this.ogcolor
			});
		})
	},
	minmax: function (data) {
		var min = 99999999,
			max = 0;
		data.each(function (a) {
			if (a[1] > max) {
				max = a[1];
			}
			if (a[1] < min) {
				min = a[1];
			}
		})
		return {
			'min': min,
			'max': max
		}
	},
	getNewStory: function () {
		if (this.storylink == "") {
			$('badmsg').set('text', 'Please enter the url of the story you wish to view live:');
		} else {
			$('badmsg').set({
				'styles': {
					'color': '#c00'
				},
				'text': 'The story link you provided does not appear to be valid.  Please enter a new reddit link:'
			})
		}
		clearInterval(this.loader);
		$('badstorynotice').setStyle('display', '');
		$('slownotice').setStyle('display', 'none');
		$('live').setStyle('display', 'none');
		$$('h2')[0].setStyle('display', 'none')
		$('submitstory').addEvent('click', function () {
			this.changeStory($('inputstory').value)
		}.bind(this))
		$('inputstory').addEvent('keyup', function (e) {
			if (e.code == 13) {
				this.changeStory($('inputstory').value)
			}
		}.bind(this))
	},
	changeStory: function (newst) {
		window.location = "/single/?" + newst;
	},
	//Used only by Popreddits
	buildChart: function (r) {
		var lwidth = $('live').getWidth() - 220;
		r.each(function (d, i) {
			var name = new Element('a', {
				'class': 'srname',
				'text': d.name,
				'href': 'http://www.reddit.com/r/' + d.name + '/',
				'styles': {
					'opacity': 0,
					'top': '-50px'
				}
			}).inject($('live'));
			var barContainer = new Element('div', {
				'class': 'barContainer',
				'styles': {
					'width': lwidth + 'px'
				}
			}).inject($('live'));
			var bar = new Element('div', {
				'class': 'bar',
				'styles': {
					'width': '0px',
					'overflow': 'hidden',
					'top': '-50px'
				}
			}).inject(barContainer);
			var value = new Element('span', {
				'class': 'value',
				'text': d.stories,
				'styles': {
					'right': '900px'
				}
			}).inject(bar);
			var width = (d.width / 100 * lwidth).round();
			var animate = function () {
					new Fx.Morph(name, {
						duration: 500,
						transition: Fx.Transitions.Quad.easeOut
					}).start({
						'top': '0px',
						'opacity': 1
					});
					new Fx.Morph(bar, {
						duration: 500,
						transition: Fx.Transitions.Bounce.easeOut
					}).start({
						'top': '0px',
						'opacity': 1
					});
					var expandBar = function () {
							new Fx.Morph(bar, {
								duration: 1200,
								transition: Fx.Transitions.Back.easeOut
							}).start({
								'width': width + 'px'
							});
						}
					expandBar.delay(800);
					var showValue = function () {
							new Fx.Morph(value, {
								duration: 500,
								transition: Fx.Transitions.Quad.easeOut
							}).start({
								'right': '5px'
							});
						}
					showValue.delay(1300);
				}
			animate.delay(250 * i);
		})
		new Element('div', {
			'class': 'clear'
		}).inject($('live'));
	},
	//Used only by stats
	buildStats: function (r) {
		for (var i = 0; i < 10; i++) {
			$('subreddit_row' + i).setStyle('display', 'none');
			$('story_row' + i).setStyle('display', 'none');
		}
		if (r == null || r.fail == true) {
			this.goToFail();
			return;
		}
		$('frontpageloads_hour').set('text', r.hourfrontpageloads);
		$('frontpageloads_day').set('text', r.dayfrontpageloads);
		$('frontpageupdates_hour').set('text', r.hourfrontpageupdates);
		$('frontpageupdates_day').set('text', r.dayfrontpageupdates);
		$('subredditloads_hour').set('text', r.hoursubredditloads);
		$('subredditloads_day').set('text', r.daysubredditloads);
		$('subredditupdates_hour').set('text', r.hoursubredditupdates);
		$('subredditupdates_day').set('text', r.daysubredditupdates);
		$('storyloads_hour').set('text', r.hourstoryloads);
		$('storyloads_day').set('text', r.daystoryloads);
		$('storyupdates_hour').set('text', r.hourstoryupdates);
		$('storyupdates_day').set('text', r.daystoryupdates);
		$('popreddit_hour').set('text', r.hourpopreddits);
		$('popreddit_day').set('text', r.daypopreddits);
		$('vizedditloads_hour').set('text', r.hourvizedditloads);
		$('vizedditloads_day').set('text', r.dayvizedditloads);
		$('vizedditupdates_hour').set('text', r.hourvizedditupdates);
		$('vizedditupdates_day').set('text', r.dayvizedditupdates);
		$('commentsloads_hour').set('text', r.hourcommentloads);
		$('commentsloads_day').set('text', r.daycommentloads);
		$('commentsupdates_hour').set('text', r.hourcommentupdates);
		$('commentsupdates_day').set('text', r.daycommentupdates);
		$('vocabularyloads_hour').set('text', r.hourvocabularyloads);
		$('vocabularyloads_day').set('text', r.dayvocabularyloads);
		$('vocabularyupdates_hour').set('text', r.hourvocabularyupdates);
		$('vocabularyupdates_day').set('text', r.dayvocabularyupdates);
		$('total_hour').set('text', r.hourtotal);
		$('total_day').set('text', r.daytotal);
		for (var n = 0; n < 10; n++) {
			// subreddits
			var showsubrow = false;
			if ($type(r.topten.hoursubreddit[n])) {
				showsubrow = true;
				$('subreddit_title_' + n + '_hour').set('text', r.topten.hoursubreddit[n].subreddit);
				$('subreddit_title_' + n + '_hour').set('href', '/subreddit/?' + r.topten.hoursubreddit[n].subreddit);
				$('subreddit_views_' + n + '_hour').set('text', r.topten.hoursubreddit[n].count);
			} else {
				$('subreddit_title_' + n + '_hour').empty();
				$('subreddit_views_' + n + '_hour').empty();
			}
			if ($type(r.topten.daysubreddit[n])) {
				showsubrow = true;
				$('subreddit_title_' + n + '_day').set('text', r.topten.daysubreddit[n].subreddit);
				$('subreddit_title_' + n + '_day').set('href', '/subreddit/?' + r.topten.daysubreddit[n].subreddit);
				$('subreddit_views_' + n + '_day').set('text', r.topten.daysubreddit[n].count);
			} else {
				$('subreddit_title_' + n + '_day').empty();
				$('subreddit_views_' + n + '_day').empty();
			}
			if (showsubrow) {
				$('subreddit_row' + n).setStyle('display', '');
				$('subreddit_row' + n).getElements('td').each(function (chi) {
					if (chi.get('text') == "") {
						chi.setStyle('border-bottom', '0');
					} else {
						chi.setStyle('border-bottom', '1px solid #dfdfdf');
					}
				})
			} else {
				$('subreddit_row' + n).setStyle('display', 'none');
			}
			// stories
			var showstoryrow = false;
			if ($type(r.topten.hourstory[n])) {
				showstoryrow = true;
				$('story_title_' + n + '_hour').set('text', r.topten.hourstory[n].title);
				$('story_title_' + n + '_hour').set('href', '/single/?http://www.reddit.com/r/' + r.topten.hourstory[n].subreddit + '/comments/' + r.topten.hourstory[n].story + '/');
				$('story_views_' + n + '_hour').set('text', r.topten.hourstory[n].count);
			} else {
				$('story_title_' + n + '_hour').empty();
				$('story_views_' + n + '_hour').empty();
			}
			if ($type(r.topten.daystory[n])) {
				showstoryrow = true;
				$('story_title_' + n + '_day').set('text', r.topten.daystory[n].title);
				$('story_title_' + n + '_day').set('href', '/single/?http://www.reddit.com/r/' + r.topten.daystory[n].subreddit + '/comments/' + r.topten.daystory[n].story + '/');
				$('story_views_' + n + '_day').set('text', r.topten.daystory[n].count);
			} else {
				$('story_title_' + n + '_day').empty();
				$('story_views_' + n + '_day').empty();
			}
			if (showstoryrow) {
				$('story_row' + n).setStyle('display', '');
				$('story_row' + n).getElements('td').each(function (chi) {
					if (chi.get('text') == "") {
						chi.setStyle('border-bottom', '0');
					} else {
						chi.setStyle('border-bottom', '1px solid #dfdfdf');
					}
				})
			} else {
				$('story_row' + n).setStyle('display', 'none');
			}
		}
	},
	commentsInit: function () {
		this.commentriver = $('commentriver');
		this.showdown = new Showdown.converter();
		this.userscroll = false;
		window.addEvent('mousewheel', function () {
			this.userscroll = true;
		}.bind(this));
		this.scrollTopTimer = this.scrollToTop.bind(this).periodical(100);
		this.theRequest = new Request.JSON({
			method: 'get',
			onSuccess: this.displayComments.bind(this),
			onFailure: this.goToFail.bind(this)
		})
		this.theRequest.send({
			"url": "commentsproxy.php?initial=true&nocache=" + $random(0, 999999)
		});
		this.loader = setInterval(function () {
			this.theRequest.send({
				url: 'commentsproxy.php?nocache=' + $random(0, 999999)
			});
		}.bind(this), 30000);
	},
	scrollToTop: function () {
		if (this.userscroll) {
			$clear(this.scrollTopTimer);
			return;
		}
		if (window.getScrollTop() > 0) {
			window.scrollTo(0, 0);
			$clear(this.scrollTopTimer);
			return;
		}
	},
	displayComments: function (data) {
		if (data == null || data.fail) {
			this.goToFail();
		}
		data.each(function (e, i) {
			var f = function () {
					this.buildComment(e);
				}
			f.bind(this).delay($random(0, 30000));
		}.bind(this))
	},
	buildComment: function (comdata) {
		comdata.body = comdata.body.replace("&gt;", ">");
		comdata.body = this.showdown.makeHtml(comdata.body);
		var container = new Element('div', {
			'class': 'comContainer',
			'id': 'com_' + comdata.id,
			'styles': {
				'height': '0px'
			}
		}).inject(this.commentriver, 'top');
		var inner = new Element('div', {
			'class': 'comInner'
		}).inject(container);
		var body = new Element('div', {
			'class': 'comBody',
			'html': comdata.body
		}).inject(inner);
		new Element('a', {
			'class': 'comLink',
			'href': 'http://www.reddit.com/comments/' + comdata.link_id.split('_')[1],
			'text': 'View Story'
		}).inject(body, 'top');
		var author = new Element('div', {
			'class': 'comAuthor'
		}).inject(inner);
		new Element('div', {
			'class': 'comTip'
		}).inject(author);
		new Element('a', {
			'href': 'http://www.reddit.com/user/' + comdata.author,
			'text': comdata.author
		}).inject(author);
		var ani = new Fx.Morph(container, {
			duration: inner.getHeight() / 100 * 200
		});
		container.store('ani', ani);
		ani.start({
			'height': inner.getHeight() + 15 + 'px'
		});
	},
	//common functions
	goToFail: function () {
		if ($chk($('slownotice'))) {
			$('slownotice').setStyle('display', 'none');
		}
		$('failnotice').setStyle('display', '');
		if (this.loader != '') {
			clearInterval(this.loader);
		}
	}
})
