/**
 * jQuery redrawSelect plugin
 * This jQuery plugin was created to redraw default form select element to stylable drop down menu.
 * @name jquery-redrawSelect-1.0b.js
 * @author Robertas Leikus - http://www.skill.lt
 * @version 1.3b
 * @date April 08, 2009
 * @category jQuery plugin
 * @copyright (c) 2009 Robertas Leikus (skill.lt)
 */
jQuery._index = 0;
jQuery._redrawSelectIdents = new Array();
jQuery.fn.redrawSelect = function(options) {
	return this.each(function(options) {
		var aSelect = this;
		var settings = jQuery.extend({
			'ident': (($(aSelect).attr('id')) ? $(aSelect).attr('id') : 'redrawnSelect_' + Math.round(Math.random() * 100)),
			'cssClass': 'redrawSelect'
		}, options);
		if(!$(aSelect).attr('id')) {
			$(aSelect).attr('id') = settings.ident;
		}
		if($(aSelect).attr('class')) 
        settings.cssClass = $(aSelect).attr('class');
		var active = $(aSelect).find('option:selected');
		var optValues = new Object();
		var html = '<div class="' + settings.cssClass + '_h" id="div_' + settings.ident + '_h">';
		html += '<div class="' + settings.cssClass + '_txt" id="div_' + settings.ident + '_txt">' + active.html() + '</div>';
		html += '<div class="' + settings.cssClass + '_opts" id="div_' + settings.ident + '_opts">';
		$(aSelect).find('option').each(function() {
			optValues['div_' + settings.ident + '_opt_' + $(this).attr('value')] = $(this).attr('value');
			html += '<div class="' + settings.cssClass + '_itm' + (($(this).attr('value') == $(aSelect).attr('value')) ? '_act' : '') + '" id="div_' + settings.ident + '_opt_' + $(this).attr('value') + '">' + $(this).html() + '</div>';
		});
		html += '</div></div>';
		$(aSelect).after(html);
		$(aSelect).hide();
		var $container = $('#div_' + settings.ident + '_opts');
		var $textContainer = $('#div_' + settings.ident + '_txt');
		$container.hide();
		$textContainer.mouseover(function() {
			$(this).addClass(settings.cssClass + '_txt_act');
		});
		$textContainer.mouseout(function() {
			$(this).removeClass(settings.cssClass + '_txt_act');
		});
		$textContainer.click(function() {
			if(!$container.css('display') || $container.css('display') == 'none') {
				$container.slideDown();
				jQuery._redrawSelectIdents['div_' + settings.ident + '_opts'] = true;
			} else {
				$container.slideUp();
			}
		});
		jQuery._index++;
		zind = parseInt($('#div_' + settings.ident + '_h').css('z-index'));
		if(!zind) {
			zind = 1000;
		} else {
			zind += 1000;
		}
		$('#div_' + settings.ident + '_h').css({zIndex: (zind - jQuery._index)});
		jQuery._redrawSelectIdents['div_' + settings.ident + '_opts'] = false;
		$('#div_' + settings.ident + '_opts div').each(function() {
			$(this).mouseover(function() {
				$(this).addClass(settings.cssClass + '_itm_hover');
			});
			$(this).mouseout(function() {
				$(this).removeClass(settings.cssClass + '_itm_hover');
			});
			$(this).click(function() {
				$container.slideUp();
				$(aSelect).val(optValues[$(this).attr('id')]);
				$textContainer.html($(this).html());
				$container.find('div.' + settings.cssClass + '_itm_act').addClass(settings.cssClass + '_itm').removeClass(settings.cssClass + '_itm_act');
				$(this).addClass(settings.cssClass + '_itm_act');
				if(typeof callBack == 'function') {
					callBack();
				}
			});
		});
	});
}
jQuery.fn.jScrollPane = function(settings) {
	var settings = jQuery.extend({
			scrollbarWidth : 10,
			scrollbarMargin : 5,
			wheelSpeed : 18,
			showArrows : false,
			arrowSize : 0,
			dragMinHeight : 1,
			dragMaxHeight : 99999,
			animateTo : false,
			animateInterval : 100,
			animateStep: 3
	}, settings);
	var rf = function() {
		return false;
	};
	return this.each(function() {
		$(this).css('overflow', 'hidden');
		console.log('aaa');
		if($(this).find('.jScrollPaneContainer').length) {
		} else {
			$(this).wrapInner($('<div></div>').attr({'className':'jScrollPaneContainer'}));
			$(document).bind('emchange', function(e, cur, prev) {
				$(this).jScrollPane(settings);
			});
			originalPadding = $(this).css('paddingTop') + ' ' + $(this).css('paddingRight') + ' ' + $(this).css('paddingBottom') + ' ' + $(this).css('paddingLeft');
			originalSidePaddingTotal = (parseInt($(this).css('paddingLeft')) || 0) + (parseInt($(this).css('paddingRight')) || 0);
			var cssToApply = {
				'height':'auto',
				'width': $(this).innerWidth() + settings.scrollbarWidth + settings.scrollbarMargin + originalSidePaddingTotal + 'px'
			};
			cssToApply.paddingRight = settings.scrollbarMargin + 'px';
			$(this).css(cssToApply);
			var percentInView = $(this).innerHeight() / $(this).outerHeight();
			var $container = $('>.jScrollPaneContainer', $(this));
			if(percentInView < .99) {
				$container.append(
					$('<div></div>').attr({className: 'jScrollPaneTrack'}).css({width: settings.scrollbarWidth + 'px'}).append(
						$('<div></div>').attr({className: 'jScrollPaneDrag'}).css({width: settings.scrollbarWidth + 'px'}).append(
							$('<div></div>').attr({className: 'jScrollPaneDragTop'}).css({width: settings.scrollbarWidth + 'px'}),
							$('<div></div>').attr({className: 'jScrollPaneDragBottom'}).css({width: settings.scrollbarWidth + 'px'})
						)
					)
				);
				var $track = $('>.jScrollPaneTrack', $container);
				var $drag = $('>.jScrollPaneTrack .jScrollPaneDrag', $container);
				if(settings.showArrows) {
					var currentArrowButton;
					var currentArrowDirection;
					var currentArrowInterval;
					var currentArrowInc;
					var whileArrowButtonDown = function() {
						if(currentArrowInc > 4 || currentArrowInc % 4 == 0) {
							positionDrag(dragPosition + currentArrowDirection * mouseWheelMultiplier);
						}
						currentArrowInc++;
					};
					var onArrowMouseUp = function(event) {
						$('html').unbind('mouseup', onArrowMouseUp);
						currentArrowButton.removeClass('jScrollActiveArrowButton');
						clearInterval(currentArrowInterval);
					};
					var onArrowMouseDown = function() {
						$('html').bind('mouseup', onArrowMouseUp);
						currentArrowButton.addClass('jScrollActiveArrowButton');
						currentArrowInc = 0;
						whileArrowButtonDown();
						currentArrowInterval = setInterval(whileArrowButtonDown, 100);
					};
					$container.append(
							$('<a></a>').attr({href: 'javascript:;', className: 'jScrollArrowUp'})
										.css({width: settings.scrollbarWidth + 'px'})
										.html('Scroll up')
										.bind('mousedown', function() {
											currentArrowButton = $(this);
											currentArrowDirection = -1;
											onArrowMouseDown();
											this.blur();
											return false;
										})
										.bind('click', rf),
							$('<a></a>').attr({href: 'javascript:;', className: 'jScrollArrowDown'})
										.css({width: settings.scrollbarWidth + 'px'})
										.html('Scroll down')
										.bind('mousedown', function() {
											currentArrowButton = $(this);
											currentArrowDirection = 1;
											onArrowMouseDown();
											this.blur();
											return false;
										})
										.bind('click', rf)
					);
					var $upArrow = $('>.jScrollArrowUp', $container);
					var $downArrow = $('>.jScrollArrowDown', $container);
					if(!settings.arrowSize) {
						settings.arrowSize = $upArrow.height();
					}
					trackHeight = $(this).outerHeight() - settings.arrowSize - $downArrow.height();
					$track.css({height: trackHeight + 'px', top: settings.arrowSize + 'px'});
				}
				var $pane = $(this).css({overflow: 'visible'});
				var currentOffset;
				var maxY;
				var mouseWheelMultiplier;
				var dragPosition = 0;
				var dragMiddle = percentInView * $(this).innerHeight() / 2;
				var getPos = function(event, c) {
					var p = ((c == 'X') ? 'Left' : 'Top');
					return event['page' + c] || (event['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p])) || 0;
				};
				var ignoreNativeDrag = function() {
					return false;
				};
				var initDrag = function() {
					ceaseAnimation();
					currentOffset = $drag.offset(false);
					currentOffset.top -= dragPosition;
					maxY = trackHeight - $drag[0].offsetHeight;
					mouseWheelMultiplier = 2 * settings.wheelSpeed * maxY / $(this).outerHeight();
				};
				var onStartDrag = function(event) {
					initDrag();
					dragMiddle = getPos(event, 'Y') - dragPosition - currentOffset.top;
					$('html').bind('mouseup', onStopDrag).bind('mousemove', updateScroll);
					if($.browser.msie) {
						$('html').bind('dragstart', ignoreNativeDrag).bind('selectstart', ignoreNativeDrag);
					}
					return false;
				};
				var onStopDrag = function() {
					$('html').unbind('mouseup', onStopDrag).unbind('mousemove', updateScroll);
					dragMiddle = percentInView * paneHeight / 2;
					if($.browser.msie) {
						$('html').unbind('dragstart', ignoreNativeDrag).unbind('selectstart', ignoreNativeDrag);
					}
				};
				var positionDrag = function(destY) {
					destY = ((destY < 0) ? 0 : (destY > maxY ? maxY : destY));
					dragPosition = destY;
					$drag.css({top: destY + 'px'});
					var p = destY / maxY;
					$pane.css({top: (($container.outerHeight() - $(this).outerHeight()) * p) + 'px'});
					$this.trigger('scroll');
					if(settings.showArrows) {
						$upArrow[((destY == 0) ? 'addClass' : 'removeClass')]('disabled');
						$downArrow[((destY == maxY) ? 'addClass' : 'removeClass')]('disabled');
					}
				};
				var updateScroll = function(e) {
					positionDrag(getPos(e, 'Y') - currentOffset.top - dragMiddle);
				};
				var dragH = Math.max(Math.min(percentInView * ($container.outerHeight() - settings.arrowSize * 2), settings.dragMaxHeight), settings.dragMinHeight);
				$drag.css({height: dragH + 'px'}).bind('mousedown', onStartDrag);
				var trackScrollInterval;
				var trackScrollInc;
				var trackScrollMousePos;
				var doTrackScroll = function() {
					if(trackScrollInc > 8 || trackScrollInc % 4 == 0) {
						positionDrag((dragPosition - ((dragPosition - trackScrollMousePos) / 2)));
					}
					trackScrollInc++;
				};
				var onStopTrackClick = function() {
					clearInterval(trackScrollInterval);
					$('html').unbind('mouseup', onStopTrackClick).unbind('mousemove', onTrackMouseMove);
				};
				var onTrackMouseMove = function(event) {
					trackScrollMousePos = getPos(event, 'Y') - currentOffset.top - dragMiddle;
				};
				var onTrackClick = function(event) {
					initDrag();
					onTrackMouseMove(event);
					trackScrollInc = 0;
					$('html').bind('mouseup', onStopTrackClick).bind('mousemove', onTrackMouseMove);
					trackScrollInterval = setInterval(doTrackScroll, 100);
					doTrackScroll();
				};
				$track.bind('mousedown', onTrackClick);
				$(this).bind('mousewheel', function(event, delta) {
					initDrag();
					ceaseAnimation();
					var d = dragPosition;
					positionDrag(dragPosition - delta * mouseWheelMultiplier);
					var dragOccured = d != dragPosition;
					return !dragOccured;
				});
				var _animateToPosition;
				var _animateToInterval;
				function animateToPosition() {
					var diff = (_animateToPosition - dragPosition) / settings.animateStep;
					if(diff > 1 || diff < -1) {
						positionDrag(dragPosition + diff);
					} else {
						positionDrag(_animateToPosition);
						ceaseAnimation();
					}
				}
				var ceaseAnimation = function() {
					if(_animateToInterval) {
						clearInterval(_animateToInterval);
						delete _animateToPosition;
					}
				};
				var scrollTo = function(pos, preventAni) {
					if(typeof pos == 'string') {
						$e = $(pos, $this);
						if(!$e.length) {
							return;
						}
						pos = $e.offset().top - $this.offset().top;
					}
					$(this).scrollTop(0);
					ceaseAnimation();
					var destDragPosition = -pos / ($container.outerHeight - $(this).outerHeight) * maxY;
					if(preventAni || !settings.animateTo) {
						positionDrag(destDragPosition);
					} else {
						_animateToPosition = destDragPosition;
						_animateToInterval = setInterval(animateToPosition, settings.animateInterval);
					}
				};
				$(this)[0].scrollTo = scrollTo;
				$(this)[0].scrollBy = function(delta) {
					var currentPos = -parseInt($pane.css('top')) || 0;
					scrollTo(currentPos + delta);
				};
				initDrag();
				scrollTo(-currentScrollPosition, true);
				// Deal with it when the user tabs to a link or form element within this scrollpane
				$('*', this).bind('focus', function(event) {
						var $e = $(this);
						// loop through parents adding the offset top of any elements that are relatively positioned between
						// the focused element and the jScrollPaneContainer so we can get the true distance from the top
						// of the focused element to the top of the scrollpane...
						var eleTop = 0;
						while($e[0] != $(this)[0]) {
							eleTop += $e.position().top;
							$e = $e.offsetParent();
						}
						var viewportTop = -parseInt($pane.css('top')) || 0;
						var maxVisibleEleTop = viewportTop + $(this).innerHeight();;
						var eleInView = eleTop > viewportTop && eleTop < maxVisibleEleTop;
						if (!eleInView) {
							var destPos = eleTop - settings.scrollbarMargin;
							if(eleTop > viewportTop) { // element is below viewport - scroll so it is at bottom.
								destPos += $(this).height() + 15 + settings.scrollbarMargin - $(this).innerHeight();;
							}
							scrollTo(destPos);
						}
					}
				)
				if(location.hash) {
					scrollTo(location.hash);
				}
				$(document).bind('click', function(e) {
					$target = $(e.target);
					if($target.is('a')) {
						var h = $target.attr('href');
						if(h.substr(0, 1) == '#') {
							scrollTo(h);
						}
					}
				});
				$.jScrollPane.active.push($(this)[0]);
			} else {
				$(this).css({
					height: $(this).innerHeight() + 'px',
					width: $(this).innerHeight() - originalSidePaddingTotal + 'px',
					padding: originalPadding
				});
				// remove from active list?
				$container.unbind('mousewheel');
			}
		}
	});
}

jQuery(document).ready(function() {
	$('body').click(function() {
		for(var i in jQuery._redrawSelectIdents) {
			if(jQuery._redrawSelectIdents[i]) {
				jQuery._redrawSelectIdents[i] = false;
			} else {
				$('#' + i).slideUp();
			}
		}
	});
});