$(function(){

	new graph({
		container: 'div.graph',
		date: currentDate,
		data: graphData,
		tooltip: true
	});

});

function graph(o){

	var _this = this;

	this.container = $(o.container);
	this.date = new Date(o.date);
	this.data = o.data;
	this.tooltip = o.tooltip;
	this.graph = {};
	this.type = 'buy';
	this.mode = 'auctions';

	this.container.find('div.foot').delegate('a', 'click' ,function(){
		_this.switchGraphs(this);
		return false;
	});

	this.buildMonths();
	this.buildGraph(this.type, this.mode);

	$(window).resize(function(){
		_this.resize();
	});

}

graph.prototype = {
	container: null,
	date: null,
	data: null,
	tooltip: null,
	graph: null,
	type: null,
	mode: null
};

graph.prototype.switchGraphs = function(handler){

	var li = $(handler).closest('li');

	if (li.hasClass('act')) {
		return false;
	}

	li
		.addClass('act')
		.siblings().removeClass('act');

	var type = li.data('graph-type'),
		mode = li.data('graph-mode');

	if (typeof type === 'undefined') {
		type = this.type;
	}

	if (type === 'buy') {
		this.container
			.removeClass('graph_sell')
			.addClass('graph_buy');
	} else {
		this.container
			.removeClass('graph_buy')
			.addClass('graph_sell');
	}

	if (typeof mode === 'undefined') {

		li = this.container.find('div.switch_r ul:visible').children(':first');
		mode = li.data('graph-mode');

		li
			.addClass('act')
			.siblings().removeClass('act');

	}

	this.buildGraph(type, mode);

};

graph.prototype.buildMonths = function(){

	var
		_this = this,
		months = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
		date;

	this.container.find('div.months td').each(function(i){

		date = new Date(_this.date.getFullYear(), _this.date.getMonth() - 6 + i, 1);
		this.innerHTML = months[date.getMonth()] + ' ' + date.getFullYear();

	});

};

graph.prototype.buildGraph = function(type, mode){

	var
		container = this.container.find('div.svg').empty(),
		canvas = Raphael(container.get(0), '100%', '100%'),
		disp = this.dispersion(type, mode),
		shift = {
			top: 50,
			left: 50
		},
		ratio = (disp.max - disp.min) / (container.height() - shift.top * 2),
		img = 'img/graph_point.png',
		data, x, y,
		graph = {
			path: [],
			points: [],
			tooltips: [],
			animated: {
				line: false,
				points: false
			}
		};

	container.width = container.width();

	for (var i = 0; i < this.data.length; i++) {

		data = this.data[i][type][mode];

		x = i * (container.width - shift.left * 2) / 6 + shift.left;
		y = ratio ? Math.round((disp.max - disp.min) / ratio - (data - disp.min) / ratio + shift.top) : 100;

		graph.path[i] = [i ? 'L' : 'M', x, y];
		graph.points[i] = canvas.image(img, x - 22, y - 21, 43, 43);

		this.pointShake(graph.points[i], type, i);

		if (this.tooltip) {

            if (type === 'buy') {
                graph.tooltips[i] = $('<div class="tooltip"><div class="tooltip_wrap"><div>Экономия</div>' + this.format(data) + '</div></div>').appendTo(container);
            } else {
                graph.tooltips[i] = $('<div class="tooltip"><div class="tooltip_wrap"><div>Повышение</div>' + this.format(data) + '</div></div>').appendTo(container);
            }
			
			graph.tooltips[i].css({
				top: y - 7,
				left: x - graph.tooltips[i].outerWidth(true) / 2
			});

		}

	}

	graph.line = canvas.path(graph.path);
	graph.line.attr('stroke', '#9a4e5f');
	graph.line.toBack();

	this.type = type;
	this.mode = mode;
	this.graph = graph;

};


graph.prototype.dispersion = function(type, mode){

	var
		max = 0,
		min = Infinity,
		item;

	for (var i = 0; i < this.data.length; i++) {

		item = this.data[i][type][mode];

		min = Math.min(min, item);
		max = Math.max(max, item);

	}

	return {
		max: max,
		min: min
	}

};

graph.prototype.format = function(data){

	var result = (data % 1).toFixed(2).toString().substr(1);
	data = Math.floor(data).toString();

	while (data.length >= 3){
		result = ' ' + data.substr(data.length - 3, 3) + result;
		data = data.substr(0, data.length - 3);
	}

	return data + ' ' + result + ' р.';

};

graph.prototype.pointShake = function(point, type, j){

	var
		_this = this,
		effect = '<>';

	point.mouseover(function(){

		var
			graph = _this.graph,
			oldPath = graph.path,
			newPath = [];

		if (!_this.isAnimated(graph)) {

			graph.animated.line = true;
			graph.animated.points = true;

			this.animate({y: this.attr('y') - 1}, 50, effect, function(){
				this.animate({y: Math.round(this.attr('y')) + 2}, 150, effect, function(){
					this.animate({y: Math.round(this.attr('y')) - 2}, 200, effect, function(){
						this.animate({y: Math.round(this.attr('y')) + 2}, 250, effect, function(){
							this.animate({y: Math.round(this.attr('y')) - 1}, 150, effect, function(){
								graph.animated.points = false;
							});
						});
					});
				});
			});

			for (var i = 0; i < oldPath.length; i++) {
				newPath[i] = [];
				newPath[i][0] = oldPath[i][0];
				newPath[i][1] = oldPath[i][1];
				newPath[i][2] = i == j ? oldPath[i][2] - 1 : oldPath[i][2];
			}

			graph.line.animate({path: newPath}, 50, effect, function(){

				newPath[j][2] = newPath[j][2] + 2;

				this.animate({path: newPath}, 150, effect, function(){

					newPath[j][2] = newPath[j][2] - 2;

					this.animate({path: newPath}, 200, effect, function(){

						newPath[j][2] = newPath[j][2] + 2;

						this.animate({path: newPath}, 250, effect, function(){

							this.animate({path: oldPath}, 150, effect, function(){
								graph.animated.line = false;
							});

						});

					});

				});

			});

		}

	});

};

graph.prototype.isAnimated = function(objects){

	if (!$.isArray(objects)) {
		objects = [objects];
	}

	for (var i = 0; i < objects.length; i++) {
		if (objects[i].animated.line || objects[i].animated.points) {
			return true;
		}
	}

	return false;

};

graph.prototype.resize = function(){

	if (!this.isAnimated(this.graph)) {

		var
			width = this.container.find('div.months table').width() / 6,
			graph = this.graph,
			newPath = [];

		for (var i = 0; i < graph.path.length; i++) {
			newPath[i] = [];
			newPath[i][0] = graph.path[i][0];
			newPath[i][1] = width * i + 50;
			newPath[i][2] = graph.path[i][2];
		}

		graph.line.attr('path', newPath);

		for (var i = 0; i < graph.points.length; i++) {
			graph.points[i].attr('x', width * i + 50 - 22);
		}

		if (this.tooltip) {

			for (var i = 0; i < graph.tooltips.length; i++) {

				var left = width * i + 50 - graph.tooltips[i].width() / 2;
				graph.tooltips[i].css('left', left);

			}

		}

	}

};

