var barGraph = angular.module('custom-bar-graph', []);

barGraph.directive('barGraph', function(){
	return {
		restrict: 'A',
		scope: {
			values: '=',
			type: '='
		},
		link: function(scope, element, attrs){
			var scale = {
		  		y: d3.scale.linear(),
		  		x: d3.scale.ordinal()
			};

			var totalWidth = 360;
			var totalHeight = 310;

			//the higher the height of the bar is supposed to be, the lower the scaled height is.
			//the starting point (top) of the bar is at the scaled height, and the bar's height is the max possible height - the scaled height
			scale.y.range([totalHeight, 0]);
			scale.y.domain([0, 10]);

			var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
			
			function draw(){

				//setting height, width, and margins of chart area
				var chart = d3.select('.'+ scope.type)
				    .attr({
				        'width': totalWidth + 110,
				        'height': totalHeight + 30
				    })
				    .append("g")
		    		.attr("transform", "translate(" + 200 + "," + 5 + ")");

		    	//calculating barwidth
				var barWidth = scope.values && scope.values.length ?  (totalWidth - 100) / scope.values.length : (totalWidth - 100);

		    	var yAxis = d3.svg.axis()
					    .scale(scale.y)
					    .orient("right")
					    .ticks(10)
					    .tickSize(totalWidth)
					    .tickPadding(-totalWidth - 20);	


			    chart.append("g")
				    .attr("class", "y axis")
				    .call(yAxis);

				var colors = chart.selectAll('.colors')
					.data(['blue', 'light-blue'])
					.enter()
					.append('g');
				colors.append('rect')
					.attr({
						'x': -200,
						'y': 15,
						'height': 14,
						'width': 14
					})
					.style('fill', '#445882')
				colors.append('text')
						.attr({
							'x': -180,
							'y': 27
						})
						.text('Completed');

				colors.append('rect')
						.attr({
							'x': -200,
							'y': 30,
							'height': 14,
							'width': 14
						})
						.style('fill', '#4475DA')
				colors.append('text')
					.attr({
						'x': -180,
						'y': 42
					})
					.text('Active');

				var legend = chart.selectAll('.legend')
					.data(scope.values)
					.enter()
					.append('g')

				legend.append('text')
					.attr({
						'x': -200,
						'y': function(d,i){
							return i * 15 + totalHeight / 2;
						}
					})
					.style('font-weight', 'bold')
					.text(function(d, i) { 
			    		return alphabet.substring(i, i + 1);
			    	});

			    legend.append('text')
			    	.attr({
			    		'x': -180,
						'y': function(d,i){
							return i * 15 + totalHeight / 2;
						},
						'class': 'legend-label'
			    	})
			    	.style('fill-opacity', 1e-6)
			    	.text(function(d){
			    		return d.label;
			    	})
			    	.transition()
			    		.duration(450)
			    		.style('fill-opacity', 1);
				
				var bars = chart
				    .selectAll('.container')
				    .data(scope.values)
				    .enter()
				    .append('g');

				bars.append('rect')
				    .attr({
				    	'x': function (d, i) {
				            return i * barWidth;
				        },
				        'y': function (d) {
				            return totalHeight;
				        },
				        'height': function (d) {
				            return 0;
				        },
				        'width': barWidth - 1
				    })
				    .attr("class", "bars")
				    .on("mousemove", function(d, i){
				    	bars.selectAll('.text-box').remove();
				    	var posX = d3.mouse(this)[0];
				    	var x = Number(posX) - Math.sin(posX * 3.14 / 540) * (150);
				    	console.log(posX);
				    	var textBox = bars.append('g').attr('class', 'text-box');
			    		textBox.append('rect')
				    		.attr('x', 0)
				    		.attr('y', scale.y(d.active)  + scale.y(d.completed) - totalHeight - 50)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.attr('width', 150)
				    		.attr('height', 40)
				    		.style('fill', '#fdfdfd')
				    		.style('opacity', 0.4)
				    	textBox.append('rect')
				    		.attr('x', 0)
				    		.attr('y', scale.y(d.active)  + scale.y(d.completed) - totalHeight - 10)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.attr('width', 150)
				    		.attr('height', 3)
				    		.style('fill', '#445882')
				    		.style('opacity', 0.4)
			    		textBox.append('text')
				    		.attr('x', 10)
				    		.attr('y', scale.y(d.active)  + scale.y(d.completed) - totalHeight - 33)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.style('fill', '#445882')
				    		.text(d.label);
				    	textBox.append('text')
				    		.attr('x', 10)
				    		.attr('y', scale.y(d.active)  + scale.y(d.completed) - totalHeight - 18)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.text("Completed : " + d.completed);
				    })
					.on('mouseout', function(){
						bars.selectAll('.text-box').remove();
					})
				    .transition()
				    	.duration(450)
				    	.style("fill-opacity", 1)
				    	.attr({
				    		'y': function(d, i){
					        	return scale.y(d.active)  + scale.y(d.completed) - totalHeight;
					        },
				    		'height': function (d, i) {
				            	return totalHeight - scale.y(d.completed);
				       		}
				    	});
				bars.append('rect')
				    .attr({
				        'x': function (d, i) {
				           	return i * barWidth;
				        },
				        'y': totalHeight,
				        'height': function (d, i) {
				            return 0;
				        },
				        'width': barWidth - 1
				    })
				    .style("fill-opacity", 1e-6)
				    .attr("class", "bar")
				    .on("mousemove", function(d, i){
				    	bars.selectAll('.text-box').remove();
				    	var posX = d3.mouse(this)[0];
				    	var x = Number(posX) - Math.sin(posX * 3.14 / 540) * (150);
				    	console.log(posX);
				    	var textBox = bars.append('g').attr('class', 'text-box');
			    		textBox.append('rect')
				    		.attr('x', 0)
				    		.attr('y', scale.y(d.active) - 50)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.attr('width', 150)
				    		.attr('height', 40)
				    		.style('fill', '#fdfdfd')
				    		.style('opacity', 0.4)
				    	textBox.append('rect')
				    		.attr('x', 0)
				    		.attr('y', scale.y(d.active) - 10)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.attr('width', 150)
				    		.attr('height', 3)
				    		.style('fill', '#4475DA')
				    		.style('opacity', 0.4)
			    		textBox.append('text')
				    		.attr('x', 10)
				    		.attr('y', scale.y(d.active) - 33)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.style('fill', '#445882')
				    		.text(d.label);
				    	textBox.append('text')
				    		.attr('x', 10)
				    		.attr('y', scale.y(d.active) - 18)
				    		.attr('transform', 'translate('+ x.toString() + ',0)')
				    		.text("Active: " + d.active);
				    })
					.on('mouseout', function(){
						bars.selectAll('.text-box').remove();
					})
				    .transition()
				    	.duration(450)
				    	.style("fill-opacity", 1)
				    	.attr({
				    		'y': function(d, i){
					        	return scale.y(d.active);
					        },
				    		'height': function (d, i) {
				            	return totalHeight - scale.y(d.active);
				       		}
				    	});
			    bars.append("text")
			    	.attr({
			    		'x': function (d, i) {
				           	return (i + 0.5) * barWidth;
				        },
				        'y': totalHeight + 40
			    	})
			    	.attr('class', 'y-axis')
			    	.text(function(d, i) { 
			    		return alphabet.substring(i, i + 1);
			    	})
			    	.transition()
			    		.attr('y', totalHeight + 15);				
			}

			draw();

			scope.$watch(function(){
				return scope.values; 
			}, function(){
				
				d3.select('.chart').selectAll('.bar')
					.transition()
						.duration(450)
						.attr({
								'y': function(d, i){
						        	return totalHeight;
						        },
					    		'height': function (d, i) {
					            	return 0;
					       		}
					    	})
					.remove();
				d3.select('.chart').selectAll('.bars')
					.transition()
						.duration(450)
						.attr({
								'y': function(d, i){
						        	return totalHeight;
						        },
					    		'height': function (d, i) {
					            	return 0;
					       		}
					    	})
					.remove();
				d3.select('.chart').selectAll('.y-axis')
					.transition()
						.duration(450)
						.attr('y', totalHeight + 40)
				d3.select('.chart').selectAll('g')
					.transition()
						.duration(450)
						.remove();

				d3.select('.chart').selectAll('.legend-label')
					.transition()
						.duration(200)
						.style('fill-opacity', 1e-6)
						.remove();
				
				draw();	
			})

		}
	}
})