/*
* jQuery UI Slider 1.7.2
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Slider
*
* Depends:
*	ui.core.js
*/

(function($) {

	$.widget("ui.slider", $.extend({}, $.ui.mouse, {

		_init: function() {

			var self = this, o = this.options;
			this._keySliding = false;
			this._handleIndex = null;
			this._detectOrientation();
			this._mouseInit();

			this.element
			.addClass("ui-slider"
				+ " ui-slider-" + this.orientation
				+ " ui-widget"
				+ " ui-widget-content"
				+ " ui-corner-all");


			this.range = $([]);

			if (o.range) {

				if (o.range === true) {
					this.range = $('<div></div>');
					if (!o.values) o.values = [this._valueMin(), this._valueMin()];
					if (o.values.length && o.values.length != 2) {
						o.values = [o.values[0], o.values[0]];
					}
				} else {
					this.range = $('<div></div>');
				}

				this.range
				.appendTo(this.element)
				.addClass("ui-slider-range");

				if (o.range == "min" || o.range == "max") {
					this.range.addClass("ui-slider-range-" + o.range);
				}

				// note: this isn't the most fittingly semantic framework class for this element,
				// but worked best visually with a variety of themes
				this.range.addClass("ui-widget-header");

			}

			if ($(".ui-slider-handle", this.element).length == 0)
				$('<a href="#"></a>')
				.appendTo(this.element)
				.addClass("ui-slider-handle");

			if (o.values && o.values.length) {
				while ($(".ui-slider-handle", this.element).length < o.values.length)
					$('<a href="#"></a>')
					.appendTo(this.element)
					.addClass("ui-slider-handle");
			}

			this.handles = $(".ui-slider-handle", this.element)
			.addClass("ui-state-default"
				+ " ui-corner-all");

			this.handle = this.handles.eq(0);

			this.handles.add(this.range).filter("a")
			.click(function(event) {
				event.preventDefault();
			})
			.hover(function() {
				if (!o.disabled) {
					$(this).addClass('ui-state-hover');
				}
			}, function() {
				$(this).removeClass('ui-state-hover');
			})
			.focus(function() {
				if (!o.disabled) {
					$(".ui-slider .ui-state-focus").removeClass('ui-state-focus'); $(this).addClass('ui-state-focus');
				} else {
					$(this).blur();
				}
			})
			.blur(function() {
				$(this).removeClass('ui-state-focus');
			});

			this.handles.each(function(i) {
				$(this).data("index.ui-slider-handle", i);
			});

			this.handles.keydown(function(event) {

				var ret = true;

				var index = $(this).data("index.ui-slider-handle");

				if (self.options.disabled)
					return;

				switch (event.keyCode) {
					case $.ui.keyCode.HOME:
					case $.ui.keyCode.END:
					case $.ui.keyCode.UP:
					case $.ui.keyCode.RIGHT:
					case $.ui.keyCode.DOWN:
					case $.ui.keyCode.LEFT:
						ret = false;
						if (!self._keySliding) {
							self._keySliding = true;
							$(this).addClass("ui-state-active");
							self._start(event, index);
						}
						break;
				}

				var curVal, newVal, step = self._step();
				if (self.options.values && self.options.values.length) {
					curVal = newVal = self.values(index);
				} else {
					curVal = newVal = self.value();
				}

				switch (event.keyCode) {
					case $.ui.keyCode.HOME:
						newVal = self._valueMin();
						break;
					case $.ui.keyCode.END:
						newVal = self._valueMax();
						break;
					case $.ui.keyCode.UP:
					case $.ui.keyCode.RIGHT:
						if (curVal == self._valueMax()) return;
						newVal = curVal + step;
						break;
					case $.ui.keyCode.DOWN:
					case $.ui.keyCode.LEFT:
						if (curVal == self._valueMin()) return;
						newVal = curVal - step;
						break;
				}

				self._slide(event, index, newVal);

				return ret;

			}).keyup(function(event) {

				var index = $(this).data("index.ui-slider-handle");

				if (self._keySliding) {
					self._stop(event, index);
					self._change(event, index);
					self._keySliding = false;
					$(this).removeClass("ui-state-active");
				}

			});

			this._refreshValue();

		},

		destroy: function() {

			this.handles.remove();
			this.range.remove();

			this.element
			.removeClass("ui-slider"
				+ " ui-slider-horizontal"
				+ " ui-slider-vertical"
				+ " ui-slider-disabled"
				+ " ui-widget"
				+ " ui-widget-content"
				+ " ui-corner-all")
			.removeData("slider")
			.unbind(".slider");

			this._mouseDestroy();

		},

		_mouseCapture: function(event) {

			var o = this.options;

			if (o.disabled)
				return false;

			this.elementSize = {
				width: this.element.outerWidth(),
				height: this.element.outerHeight()
			};
			this.elementOffset = this.element.offset();

			var position = { x: event.pageX, y: event.pageY };
			var normValue = this._normValueFromMouse(position);

			var distance = this._valueMax() - this._valueMin() + 1, closestHandle;
			var self = this, index;
			this.handles.each(function(i) {
				var thisDistance = Math.abs(normValue - self.values(i));
				if (distance > thisDistance) {
					distance = thisDistance;
					closestHandle = $(this);
					index = i;
				}
			});

			// workaround for bug #3736 (if both handles of a range are at 0,
			// the first is always used as the one with least distance,
			// and moving it is obviously prevented by preventing negative ranges)
			if (o.range == true && this.values(1) == o.min) {
				closestHandle = $(this.handles[++index]);
			}

			this._start(event, index);

			self._handleIndex = index;

			closestHandle
			.addClass("ui-state-active")
			.focus();

			var offset = closestHandle.offset();
			var mouseOverHandle = !$(event.target).parents().andSelf().is('.ui-slider-handle');
			this._clickOffset = mouseOverHandle ? { left: 0, top: 0} : {
				left: event.pageX - offset.left - (closestHandle.width() / 2),
				top: event.pageY - offset.top
				- (closestHandle.height() / 2)
				- (parseInt(closestHandle.css('borderTopWidth'), 10) || 0)
				- (parseInt(closestHandle.css('borderBottomWidth'), 10) || 0)
				+ (parseInt(closestHandle.css('marginTop'), 10) || 0)
			};

			normValue = this._normValueFromMouse(position);
			this._slide(event, index, normValue);
			return true;

		},

		_mouseStart: function(event) {
			return true;
		},

		_mouseDrag: function(event) {

			var position = { x: event.pageX, y: event.pageY };
			var normValue = this._normValueFromMouse(position);

			this._slide(event, this._handleIndex, normValue);

			return false;

		},

		_mouseStop: function(event) {

			this.handles.removeClass("ui-state-active");
			this._stop(event, this._handleIndex);
			this._change(event, this._handleIndex);
			this._handleIndex = null;
			this._clickOffset = null;

			return false;

		},

		_detectOrientation: function() {
			this.orientation = this.options.orientation == 'vertical' ? 'vertical' : 'horizontal';
		},

		_normValueFromMouse: function(position) {

			var pixelTotal, pixelMouse;
			if ('horizontal' == this.orientation) {
				pixelTotal = this.elementSize.width;
				pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0);
			} else {
				pixelTotal = this.elementSize.height;
				pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0);
			}

			var percentMouse = (pixelMouse / pixelTotal);
			if (percentMouse > 1) percentMouse = 1;
			if (percentMouse < 0) percentMouse = 0;
			if ('vertical' == this.orientation)
				percentMouse = 1 - percentMouse;

			var valueTotal = this._valueMax() - this._valueMin(),
			valueMouse = percentMouse * valueTotal,
			valueMouseModStep = valueMouse % this.options.step,
			normValue = this._valueMin() + valueMouse - valueMouseModStep;

			if (valueMouseModStep > (this.options.step / 2))
				normValue += this.options.step;

			// Since JavaScript has problems with large floats, round
			// the final value to 5 digits after the decimal point (see #4124)
			return parseFloat(normValue.toFixed(5));

		},

		_start: function(event, index) {
			var uiHash = {
				handle: this.handles[index],
				value: this.value()
			};
			if (this.options.values && this.options.values.length) {
				uiHash.value = this.values(index);
				uiHash.values = this.values();
			}
			this._trigger("start", event, uiHash);
		},

		_slide: function(event, index, newVal) {

			var handle = this.handles[index];

			if (this.options.values && this.options.values.length) {

				var otherVal = this.values(index ? 0 : 1);

				if ((this.options.values.length == 2 && this.options.range === true) &&
				((index == 0 && newVal > otherVal) || (index == 1 && newVal < otherVal))) {
					newVal = otherVal;
				}

				if (newVal != this.values(index)) {
					var newValues = this.values();
					newValues[index] = newVal;
					// A slide can be canceled by returning false from the slide callback
					var allowed = this._trigger("slide", event, {
						handle: this.handles[index],
						value: newVal,
						values: newValues
					});
					var otherVal = this.values(index ? 0 : 1);
					if (allowed !== false) {
						this.values(index, newVal, (event.type == 'mousedown' && this.options.animate), true);
					}
				}

			} else {

				if (newVal != this.value()) {
					// A slide can be canceled by returning false from the slide callback
					var allowed = this._trigger("slide", event, {
						handle: this.handles[index],
						value: newVal
					});
					if (allowed !== false) {
						this._setData('value', newVal, (event.type == 'mousedown' && this.options.animate));
					}

				}

			}

		},

		_stop: function(event, index) {
			var uiHash = {
				handle: this.handles[index],
				value: this.value()
			};
			if (this.options.values && this.options.values.length) {
				uiHash.value = this.values(index);
				uiHash.values = this.values();
			}
			this._trigger("stop", event, uiHash);
		},

		_change: function(event, index) {
			var uiHash = {
				handle: this.handles[index],
				value: this.value()
			};
			if (this.options.values && this.options.values.length) {
				uiHash.value = this.values(index);
				uiHash.values = this.values();
			}
			this._trigger("change", event, uiHash);
		},

		value: function(newValue) {

			if (arguments.length) {
				//this._setData("value", newValue);
				this._setData('value', newVal, this.options.animate_if_programmed);
				this._change(null, 0);
			}

			return this._value();

		},

		values: function(index, newValue, animated, noPropagation) {

			if (arguments.length > 1) {
				this.options.values[index] = newValue;
				this._refreshValue(animated);
				if (!noPropagation) this._change(null, index);
			}

			if (arguments.length) {
				if (this.options.values && this.options.values.length) {
					return this._values(index);
				} else {
					return this.value();
				}
			} else {
				return this._values();
			}

		},

		_setData: function(key, value, animated) {

			$.widget.prototype._setData.apply(this, arguments);

			switch (key) {
				case 'disabled':
					if (value) {
						this.handles.filter(".ui-state-focus").blur();
						this.handles.removeClass("ui-state-hover");
						this.handles.attr("disabled", "disabled");
					} else {
						this.handles.removeAttr("disabled");
					}
				case 'orientation':

					this._detectOrientation();

					this.element
					.removeClass("ui-slider-horizontal ui-slider-vertical")
					.addClass("ui-slider-" + this.orientation);
					this._refreshValue(animated);
					break;
				case 'value':
					animated = this.options.animate_if_programmed == true ? true : false;
					this._refreshValue(animated);
					break;
			}

		},

		_step: function() {
			var step = this.options.step;
			return step;
		},

		_value: function() {

			var val = this.options.value;
			if (val < this._valueMin()) val = this._valueMin();
			if (val > this._valueMax()) val = this._valueMax();

			return val;

		},

		_values: function(index) {

			if (arguments.length) {
				var val = this.options.values[index];
				if (val < this._valueMin()) val = this._valueMin();
				if (val > this._valueMax()) val = this._valueMax();

				return val;
			} else {
				return this.options.values;
			}

		},

		_valueMin: function() {
			var valueMin = this.options.min;
			return valueMin;
		},

		_valueMax: function() {
			var valueMax = this.options.max;
			return valueMax;
		},

		_refreshValue: function(animate) {

			var oRange = this.options.range, o = this.options, self = this;

			if (this.options.values && this.options.values.length) {
				var vp0, vp1;
				this.handles.each(function(i, j) {
					var valPercent = (self.values(i) - self._valueMin()) / (self._valueMax() - self._valueMin()) * 100;
					var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
					$(this).stop(1, 1)[animate ? 'animate' : 'css'](_set, o.animate);
					if (self.options.range === true) {
						if (self.orientation == 'horizontal') {
							(i == 0) && self.range.stop(1, 1)[animate ? 'animate' : 'css']({ left: valPercent + '%' }, o.animate);
							(i == 1) && self.range[animate ? 'animate' : 'css']({ width: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
						} else {
							(i == 0) && self.range.stop(1, 1)[animate ? 'animate' : 'css']({ bottom: (valPercent) + '%' }, o.animate);
							(i == 1) && self.range[animate ? 'animate' : 'css']({ height: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate });
						}
					}
					lastValPercent = valPercent;
				});
			} else {
				var value = this.value(),
				valueMin = this._valueMin(),
				valueMax = this._valueMax(),
				valPercent = valueMax != valueMin
					? (value - valueMin) / (valueMax - valueMin) * 100
					: 0;
				//to move the ul left/right according to the slider handle.
				//first get the width of both containers
				var stripwidth = $("#imagestrip").css("width");
				var containerwidth = $("#gallerygroup").css("width");
				//remove the px at the end of each leaving only the numbers and convert to int
				stripwidth = parseInt(stripwidth.substring(0, stripwidth.length - 2));
				containerwidth = parseInt(containerwidth.substring(0, containerwidth.length - 2));
				//get the actual strip width less the display window width then get the percentage value of the stripwidth in relation to the current slider % position
				// % of slider divided by 100 multiply by the actual strip width
				var newwidth = parseInt(stripwidth - containerwidth);
				var newleft = (valPercent / 100) * newwidth;
				var element = document.getElementById("imagestrip");
				if (newleft != NaN && newleft && undefined && newleft != null) {
					element.style.left = '-' + newleft + 'px';
				}

				var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%';
				this.handle.stop(1, 1)[animate ? 'animate' : 'css'](_set, o.animate);

				(oRange == "min") && (this.orientation == "horizontal") && this.range.stop(1, 1)[animate ? 'animate' : 'css']({ width: valPercent + '%' }, o.animate);
				(oRange == "max") && (this.orientation == "horizontal") && this.range[animate ? 'animate' : 'css']({ width: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
				(oRange == "min") && (this.orientation == "vertical") && this.range.stop(1, 1)[animate ? 'animate' : 'css']({ height: valPercent + '%' }, o.animate);
				(oRange == "max") && (this.orientation == "vertical") && this.range[animate ? 'animate' : 'css']({ height: (100 - valPercent) + '%' }, { queue: false, duration: o.animate });
			}

		}

	}));

	$.extend($.ui.slider, {
		getter: "value values",
		version: "1.7.2",
		eventPrefix: "slide",
		defaults: {
			animate: false,
			animate_if_programmed: false,
			delay: 0,
			distance: 0,
			max: 100,
			min: 0,
			orientation: 'horizontal',
			range: false,
			step: 1,
			value: 0,
			values: null
		}
	});
})(jQuery);

