var Grapher = new Class({
	
	//implements
	Implements: [Options],

	//options
	options: {
		json: 'json.php',
		total: 100
	},
	
	//initialization
	initialize: function(element, options) {
		//set options
		this.setOptions(options);
		this.element = $(element);
		this.element.setStyle('position','relative');
		
		var jsonLoader = new Request.JSON({
			url : this.options.json,
			onSuccess : function(response){
				this.graph = response.graph;
				this.setData(this.graph);
			}.bind(this)
		});
		
		jsonLoader.send();
	},
	
	//sets numbers and names; converts numbers to a percentage of %100
	setData: function(graphData) {
		
		graphData.each(function(graphInfo, index){
			var productivity = graphInfo.productivity;
			var name = graphInfo.name;
			var key = graphInfo.key;
			
			var productivityPercent = Math.round((graphInfo.productivity / this.options.total) * 100);
			var productivityPixels = (this.element.getStyle('width').replace('px','')  * (productivityPercent / 100)).toInt();
			
			var graphContainer = new Element('div',{
				'class' : 'graph',
				'id' :'graphkey_' + key
			});
			
			var graphLabel = new Element('div',{
				'class' : 'label',
				'id' : 'graph_' + key + '_label'
			});
			
			var graphVal = new Element('span',{
				'id' : 'graph_' + key + '_val'
			});
			
			var graphBar = new Element('div',{
				'id' : 'graph_' + key,
				'class' : 'graph_bar'
			});
			
			// Time to put all these elements together with a series of injections and adoptions.
			
			graphLabel.inject(graphContainer);
			graphVal.inject(graphLabel);
			graphBar.inject(graphContainer);
			
			graphLabel.set('html', name);
			graphVal.set('html', productivity);
			
			this.element.adopt(graphContainer);
			
			// Set Positions
			
			graphContainer.setStyle('position','absolute');
			this.graphSize = graphContainer.getSize();
			
			var origTop = this.graphSize.y * index;
			
			graphContainer.setStyle('top', origTop);
			
			this.animate(graphBar, productivityPixels);
			
		}.bind(this));
		
		/* End Initial Each */
		
		
		var jsonUpdates = new Request.JSON({
			url : this.options.json,
			onSuccess : function(response){
				this.graphUpdates = response.graph;
				this.updateBars(this.graphUpdates);
			}.bind(this)
		});
		
		function makeUpdate(){
			jsonUpdates.send();
		}
		
		setInterval(makeUpdate, 5000);
		
		this.element.setStyle('height', this.graphSize.y * graphData.length);
	},
	
	updateBars : function(graphUpdates){
		this.positions = [];
		
		graphUpdates.each(function(graphInfo, index){
				var productivity = graphInfo.productivity;
				var key = graphInfo.key;

				var productivityPercent = Math.round((productivity / this.options.total) * 100);
				var productivityPixels = (this.element.getStyle('width').replace('px','')  * (productivityPercent / 100)).toInt();
				
				var barRef = $('graph_' + key);
				var barPosRef = $('graphkey_' + key);
				
				this.animate(barRef, productivityPixels);
				
				var graphSizeHeight = barPosRef.getSize().y;
				this.positions.push(index * graphSizeHeight);
				
				this.animatePosition(barPosRef, index);
				
		}.bind(this));
	},
	
	animate : function(bar, widthTo){
		var graphFx = new Fx.Tween(bar,{
			duration : 1000
		});
		graphFx.start('width', widthTo);
	},
	
	animatePosition: function(bar, pos){
		var graphPos = new Fx.Tween(bar,{
			duration:1000
		});
		graphPos.start('top', this.positions[pos]);
	}
});
