/**
 * @author Vlad Yakovlev (red.scorpix@gmail.com)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 * @link www.scorpix.ru
 * @version 0.1.3
 * @date 2010-02-28
 * @requires jQuery
 * @requires jCommon
 */

/**
 * Контрол изменения цвета на странице.
 */
var colorPicker = (function() {

	var
		pickerValue = 0.8,
		cookieName = 'pickerValue',
		startColor = '#ffffff',
		endColor = '#000000',
		windowStates = [0, 0.5],
		windowStateClassPrefix = 'back_state_';

	var
		bodyEl,
		layoutEl,
		rootEl,
		workEl,
		pickerEl,
		binds = [];

	var
		dndMinLeft,
		lastState;

	if ($c.browser.msie && 6 >= parseInt($c.browser.version)) {
		var ie6ScrollerWidth;
		/**
		 * Возвращает ширину скроллбара.
		 */
		var getScrollerWidth = function() {

			var scrEl = $('<div style="height: 50px; left: -1000px; overflow: hidden; position: absolute; top: -1000px; width: 100px;" />').appendTo('body');
			var
				inn = $('<div style="height: 200px;" />').appendTo(scrEl),
				width = inn.width();

			scrEl.css('overflow', 'auto');
			width -= inn.width();
			scrEl.remove();

			return width;
		}
	}

	$(function() {
		bodyEl = $('body');
		layoutEl = $('#layout');
		rootEl = $('<div id="color_picker"><div class="work_area"><span class="picker icon"><ins class="png"></ins></span></div></div>').appendTo(bodyEl);

		if ($.browser.msie && 6 >= parseInt($.browser.version)) {
			ie6ScrollerWidth = getScrollerWidth() + 1;
		}

		workEl = rootEl.find('.work_area');
		pickerEl = rootEl.find('.picker');
		$c.support.canvas ? createCanvas() : createVml();
		onResize();
		pickerValue = getCookieValue();
		updateState(pickerValue);

		$(window).resize(onResize);
		$c.draggable(workEl).bind(startDnd, dnd, finishDnd);
	});

	function onResize() {
		if ($c.support.canvas) {
			updateCanvas();
		} else if ($c.browser.msie && 6 >= parseInt($c.browser.version)) {
			rootEl.css('bottom', 0 < $('#layout').width() - $('#scroller').width() ? ie6ScrollerWidth : '');
			rootEl.width($(window).width() - ie6ScrollerWidth);
		}
	}

	function updateState(value) {
		if (1 < value) {
			value = 1;
		} else if (0 > value) {
			value = 0;
		}

		pickerValue = value;
		pickerEl.css('left', (pickerValue * 100) + '%');

		var color = getColor(pickerValue);
		runBinds(color);
		layoutEl.css('background-color', color);

		for (var i = windowStates.length - 1; i >= 0; i--) {
			if (windowStates[i] <= value) {
				if (undefined !== lastState) {
					bodyEl.removeClass(windowStateClassPrefix + lastState.toString());
				}

				lastState = i;
				bodyEl.addClass(windowStateClassPrefix + i.toString());

				break;
			}
		}
	}

	function startDnd(evt) {
		if (!$(evt.target).closest(pickerEl[0]).length) {
			updateState((parseInt(evt.pageX) - Math.round(workEl.offset().left)) / workEl.width());
		}

		dndMinLeft = parseInt(evt.pageX) - Math.round(pickerValue * workEl.width());
		return false;
	}

	function dnd(evt) {
		updateState((parseInt(evt.pageX) - dndMinLeft) / workEl.width());
		return false;
	}

	function finishDnd(evt) {
		$c.cookie(cookieName, pickerValue, { path: '/' });
		return false;
	}

	function createCanvas() {
		drawCanvas($('<canvas style="display: block; height: 100%; left: 0; position: absolute; top: 0; width: 100%;"></canvas>').appendTo(rootEl));
	}

	function updateCanvas() {
		drawCanvas(rootEl.find('canvas'));
	}

	function drawCanvas(canvas) {
		var
			width = rootEl.width(),
			height = rootEl.height();

		canvas.attr({
			height: height,
			width: width
		});

		var
			ctx = canvas[0].getContext('2d'),
			grad = ctx.createLinearGradient(0, 0, width, 0);

		grad.addColorStop(0, startColor);
		grad.addColorStop(1, endColor);

		ctx.fillStyle = grad;
		ctx.fillRect(0, 0, width, height);
	}

	function createVml() {
		var rect = $(document.createElement('v:rect')).addClass('shape').attr('stroked', 'False');
		var fill = $(document.createElement('v:fill')).attr({
			type: 'gradient',
			color: startColor,
			color2: endColor,
			angle: 270
		}).appendTo(rect);

		rect.appendTo(rootEl);
	}

	function runBinds(color) {
		$.each(binds, function() {
			this(color);
		});
	}

	function getColor(value) {
		var colors = [];

		for (var i = 0; i < 3; i++) {
			var
				color1 = parseInt('0x' + startColor.substr(i * 2 + 1, 2)),
				color2 = parseInt('0x' + endColor.substr(i * 2 + 1, 2));

			colors.push(Math.round((color2 - color1) * value + color1));
		}

		return 'rgb(' + colors.join(',') + ')';
	}

	function getCookieValue() {
		var value = $c.cookie(cookieName);

		if (null === value) {
			$c.cookie(cookieName, pickerValue, { path: '/' });

			return pickerValue;
		}

		value = parseFloat(value);

		if (0 > value || 1 < value) {
			value = 0 > value ? 0 : 1;
			$c.cookie(cookieName, value, { path: '/' });
		}

		return value;
	}

	return {
		bind: function(func) {
			binds.push(func);
		},
		color: function() {
			return getColor(pickerValue);
		}
	};
})();
