var $j = jQuery.noConflict();

$j.slider = function (selector, options) {
	var settings = $j.extend({
		"descriptors": null,
		"rows": 3,
		"panelWidth": 230,
		"panelHeight": 110,
		"padding": 10
	}, options);
	
	this._descriptors = settings.descriptors;
	this._selector = selector;
	this._rows = settings.rows;
	this._cols = settings.descriptors.length / settings.rows;
	this._padding = settings.padding;
	this._scrolling = false;
	this._gutter = null;
	this._panelWidth = settings.panelWidth;
	this._panelHeight = settings.panelHeight;
	this._scrollingWidth = 0;
	this._currentlySelected = null;
	
	this._register();
}

$j.slider.descriptor = function (id, label) {
	this.id = id;
	this.label = label;
}
$d = function (id, label) { return new $j.slider.descriptor(id, label) };

$j.slider.prototype._register = function () {
	var obj = this;
	
	$j(this._selector).disableTextSelect();
	var arrow = $j("<div class=\"arrowLeft\"></div>").appendTo(this._selector);
	arrow.bind('click', function () { obj.scroll('left'); })

	var container = $j("<div class=\"container\"></div>").appendTo(this._selector);
	this._gutter = $j("<div class=\"gutter\"></div>").appendTo(container);
	
	arrow = $j("<div class=\"arrowRight\"></div>").appendTo(this._selector);
	arrow.bind('click', function () { obj.scroll('right'); })
	
	for (var i in this._descriptors) {
		var descriptor = this._descriptors[i];
		this._createPanel(descriptor, false);
	}
		
	this._scrollingWidth = this._panelWidth + this._padding;
	this._resetGutter();
	
	this._updatePanels();
}

$j.slider.prototype._resetGutter = function () {
	this._gutter.css('left', '-' + this._panelWidth + "px");
}

$j.slider.prototype._createPanel = function (descriptor, update) {
	var panel = $j("<div class='panel panelOut'></div>").data("descriptor", descriptor).data("slider", this);
	
	$j(this._selector).trigger("contentCreated", {"panel":panel});
		
	this._addEvents(panel);
	panel.css("display", "none");
	panel.appendTo(this._gutter);
	
	if (update != false) this._updatePanels();
}

$j.slider.prototype._removeEvents = function (panel) {
	panel.unbind();
}

$j.slider.prototype.select = function (panel) {
	if (this._currentlySelected != null && this._currentlySelected != panel) {
		this._currentlySelected.removeClass('panelSelected');
		this._currentlySelected = null;
	}
	
	panel.addClass('panelSelected');
	this._currentlySelected = panel;
	
	$j(this._selector).trigger("panelSelect", {"panel":panel});
}

$j.slider.prototype._addEvents = function (panel) {
	panel.bind("mouseover", function () {
		$j(this).addClass('panelOver');
		$j(this).removeClass('panelOut');
	})
	panel.bind("mouseout", function () {
		$j(this).removeClass('panelOver');
		$j(this).addClass('panelOut');
	})
	panel.bind("click", function () {$j(this).data("slider").select($j(this))})
}

$j.slider.prototype._updatePanels = function () {
	var col = -1;
	var row = 0;
	var obj = this;
	
	this._gutter.find("div.panel").each(
		function (i) {
			if (i % obj._cols == 0) {
				col++;
				row = 0;
			}

			var panel = $j(this);
			var left = row * (obj._panelWidth + obj._padding);
			var top = col * (obj._panelHeight + obj._padding);
			
			panel.css('top', top);
			panel.css('left', left);
			
			panel.css("display", "block");
			
			row++;
		}
	);
}

$j.slider.prototype.enableById = function (ids) {
	var selector = $j(this._selector);
	this._gutter.find("div.panel").each(
		function (i) {
			var obj = $j(this);
			
			if (ids == null || ids == undefined || ids.length < 1) {
				obj.removeClass("panelDisabled");
				selector.trigger("panelEnabled", {"panel":obj});
			} else {
				var found = false;
				
				for (var i in ids) {
					if (obj.data("descriptor").id == ids[i]) {
						found = true;
						break;
					}
				}
				
				if (found) {
					obj.removeClass("panelDisabled");
					selector.trigger("panelEnabled", {"panel":obj});
				} else {
					obj.addClass("panelDisabled");
					selector.trigger("panelDisabled", {"panel":obj});
				}
			}
		}
	);
}

$j.slider.prototype.enable = function (descriptors) {
	var selector = $j(this._selector);
	this._gutter.find("div.panel").each(
		function (i) {
			var obj = $j(this);
			
			if (descriptors == null || descriptors == undefined || descriptors.length < 1) {
				obj.removeClass("panelDisabled");
				selector.trigger("panelEnabled", {"panel":obj});
			} else {
				var found = false;
				
				for (var i in descriptors) {
					if (obj.data("descriptor") == descriptors[i]) {
						found = true;
						break;
					}
				}
				
				if (found) {
					obj.removeClass("panelDisabled");
					selector.trigger("panelEnabled", {"panel":obj});
				} else {
					obj.addClass("panelDisabled");
					selector.trigger("panelDisabled", {"panel":obj});
				}
			}
		}
	);
}

$j.slider.prototype._restructure = function () {
	var pos = this._gutter.position().left;

	for (var i = 0; i < this._rows; i++) {
		var firstIndex = (i * this._cols);
		var secondIndex = firstIndex + (this._cols - 1);
		
		var first = this._gutter.children('div.panel:eq(' + firstIndex + ')');
		var second = this._gutter.children('div.panel:eq(' + secondIndex + ')');

		if (pos > 0) second.insertBefore(first);
		else if (pos < 0 ) first.insertAfter(second);
	}
	
	this._resetGutter();
	this._updatePanels();
}

$j.slider.prototype.scroll = function (direction) {	
	var pos = null;
	
	switch(direction) {
		case 'left':
			pos = "+=" + this._scrollingWidth + "px";
			break;
		case 'right':
			pos = "-=" + this._scrollingWidth + "px";
			break;
	}
	
	if (pos != null && !this._scrolling) {
		this._scrolling = true;

		var obj = this;
		var onComplete = function () {
			obj._restructure();
			obj._scrolling = false;
		}
		
		this._gutter.animate({"left": pos}, "slow", "swing", onComplete);
	}
}