$.fn.scrollbar = function(){
	if(typeof arguments[0] == 'string'){
		switch(arguments[0]){
			case 'pos': return this.trigger('getPos').data('curPos');
		}
	}else{
		if(typeof arguments[0] != 'object') var options = {};
		var options = $.extend({
			size: 0.5,
			position: 0,
			scroll: $.noop,
			start:	$.noop,
			stop:	$.noop,
			load:	$.noop,
			vert:	false
		}, arguments[0])
		return this.each(function(){
			//BUILD
			var vert = options.vert;
			var size = vert?'height':'width';
			var pos = vert?'top':'left';
			var mouseV = vert?'pageY':'pageX';
			var box = $(this).addClass('scrollbar-box').addClass(vert?'scrollbar-vertical':'scrollbar-horizontal').css('overflow', 'hidden')
					.css('position', ($(this).css('position') == 'static')?'relative':$(this).css('position'));
			var track = $('<div />', {'class': 'scrollbar-track'}).css('position', 'relative')
					.css(size, box[size]() * (1 - options.size));
			var handle = $('<div />', {'class': 'scrollbar-handle'})
					.css('position','relative')
					.css(size, box[size]() * options.size)
					.css(pos, 0).css('display', (options.size > 1) ? 'none' : 'block');
			var pack = {
					box: box,
					track: track,
					handle: handle
				};
			box.data('curPos', 0);
			var getPos = function(){
				var pos = box.data('curPos');
				return $.extend({pos:pos}, pack)
			}
			//LINKING
			box.append(track.append(handle));
			
			//EVENTS
			handle.bind('mousedown', function(e){
				var start = e[mouseV], first = false;
				$(document).bind({
					'mousemove.scroll'	:	function(e){
						if(!first){
							first = true;	
							box.trigger('start', [getPos()]);
						}
						var x = (e[mouseV] - start) / track[size]();
						start = e[mouseV];
						box.trigger('move', [x, false, $.browser.msie ? false : true]);
						//console.log('x='+x);
					},'mouseup.scroll'	:	function(){ $(this).unbind('.scroll'); box.trigger('stop', [getPos()]); }
				});	
			});
			box.bind({
				click	:	function(e){
					if( e[mouseV] > handle.offset()[pos] + handle[size]() )
						box.trigger('move', [handle[size]() / track[size](), true, true]);
					else if(e[mouseV] < handle.offset()[pos]) box.trigger('move', [- handle[size]() / track[size](), true, true]);
					return false;
				},
				progressScroll:	options.scroll,
				startScroll:	options.start,
				stopScroll: 	options.stop,
				load: options.load,
				move:			function(event, position, animate, scrollAn){
					if(typeof position == "undefined") return;
					if(options.size >= 1) return false;
					var curPos = $(this).data('curPos'),
						maxPos = 1,
						minPos = 0;
					var newPos = curPos + position;
					if(typeof animate == 'undefined') var animate = true;
					if(typeof scrollAn == 'undefined') var scrollAn = animate;
					newPos = Math.max(newPos, minPos);
					newPos = Math.min(newPos, maxPos);
					if(newPos == curPos) return false;
					var newAnPos = {}; newAnPos[pos] = newPos * 100 + '%';
					if(animate && !$.browser.msie)	handle.stop(true).animate	(newAnPos, animate.duration || 'fast', animate.easing || 'easeOutExpo');
					else		handle.stop(true).css		(newAnPos);
					$(this).data('curPos', newPos).trigger('progressScroll', [{pos: newPos}, scrollAn]);
				},
				refresh:		function(e, opt, refreshPos){
					options = $.extend({
						size: options.size,
						length: 1
					}, opt);	
					if(options.length != 1){
						options.size /= options.length;
						options.pos = (options.pos || getPos().pos) / options.length;
						if(options.pos > 1) options.pos = 1;
					}
					handle.css(size, box[size]() * options.size)
					if(options.pos) handle.css(pos, options.pos * 100 + '%').stop(true);
					track.css(size, box[size]() * (1-options.size));
					if(typeof refreshPos == "boolean" && refreshPos) $(this).trigger('progressScroll', [{pos: getPos().pos}]);
					box.data('curPos', options.pos);
				}
			});
			if(options.position != 0)
				box.trigger('move', [options.position, false]);
				
			//init complete
			box.trigger('load');
		});
	}
}




	 $.fn.hl = function(){
		return this.each(function(){
			var coords = $(this).offset();
			var width = $(this).width();
			var height = $(this).height();
			var obj = $('<div style="display:none; background-color:#ff0; position:absolute; z-index:999; top:'+coords.top+'px; left:'+coords.left+'px; width:'+width+'px; height:'+height+'px;"></div>');
			obj.prependTo('body');
			obj.fadeIn(1000, function(){ $(this).remove(); })
		});
	 }
	 
$.fn.moving = function(target, speed, easing, func, callback){
	var func = func || $.noop;
	var callback = callback || $.noop;
	
	return this.each(function(){
		this.moving = this.moving || null;
		var obj = $(this);
		var plain = this;
		
		var set = function(first){
			if(first) 
				plain.moving = {
					pos: {},
					current:{},
					target:{},
					vector:{},
					css:{}
				}		
			$.extend(plain.moving, {
					easing: easing || 'linear',
					speed: speed || 400,
					k: $.fx.interval / speed
			});
			$.each(target, function(index, value){
				if(first) plain.moving.pos[index] = {
					val: $.moving[index].get(obj),
					units: $.getUnits(target[index])
				}
				else plain.moving.pos[index].val = plain.moving.current[index];
				if(first) plain.moving.current[index] = plain.moving.pos[index].val;
				plain.moving.target[index] = $.moving[index].get(obj, target[index]);
				plain.moving.vector[index] = plain.moving.target[index] - plain.moving.pos[index].val;
			});
			plain.moving.percent = 0;
			plain.moving.start = $.now();
		}
		
		if(plain.moving == null){
			set(true);	
			obj.queue(function(){});
			
			/* START TIMER */		
			plain.moving.timer = setInterval(function(){
				plain.moving.percent += plain.moving.k;
				var t = $.now() - plain.moving.start;
				var end = false;
				if(1-plain.moving.k < plain.moving.percent || plain.moving.percent == 1) end=true;
				
				$.each(plain.moving.current, function(index, value){
					if(!end) plain.moving.current[index] = $.easing[plain.moving.easing](plain.moving.percent, t, plain.moving.pos[index].val, plain.moving.vector[index], plain.moving.speed);
					else plain.moving.current = plain.moving.target;
					plain.moving.css[index] = String(plain.moving.current[index].toFixed(2)) + plain.moving.pos[index]['units'];
				});
				obj.css(plain.moving.css);
				func(plain.moving.css);
				
				if(end){
					callback();
					clearInterval(plain.moving.timer);
					obj.dequeue();
					plain.moving = null;
				}
			}, $.fx.interval);
		}else set();	
	});
}

$.getUnits = function(val){
	if(/[\d\.]+px$/.test(val)) return 'px';
	if(/[\d\.]+%$/.test(val)) return '%';
	return '';
}

$.moving = $.extend($.moving,{
	left:{
		get:function(obj, from){
			var par = typeof from == 'undefined';
			var val = (par) ? obj.css('left') : from;
			val = parseFloat(val);
			val = isNaN(val) ? 0 : val;
			return val;
		}
	},
	top:{
		get:function(obj, from){
			var par = typeof from == 'undefined';
			var val = (par) ? obj.css('top') : from;
			val = parseFloat(val);
			val = isNaN(val) ? 0 : val;
			return val;
		}
	},
	'text-indent':{
		get:function(obj, from){
			var par = typeof from == 'undefined';
			var val = (par) ? obj.css('text-indent') : from;
			val = parseFloat(val);
			val = isNaN(val) ? 0 : val;
			return val
		}
	},
	width:{
		get:function(obj, from){
			var par = typeof from == 'undefined';
			var val = (par) ? obj.width() : from;
			val = parseInt(val);
			val = isNaN(val) ? 0 : val;
			return val
		}
	},
	height:{
		get:function(obj, from){
			var par = typeof from == 'undefined';
			var val = (par) ? obj.height() : from;
			val = parseInt(val);
			val = isNaN(val) ? 0 : val;
			return val
		}
	}
});

	 $.sOn = function(){
		 document.body.onselectstart = null;
		// log('select_on');
	 }
	 $.sOff = function(){
		 document.body.onselectstart = function() { return false }
		// log('select_off');
	 }
	 $.fn.selectHover = function(){
	 	return this.each(function(){ $(this).hover($.sOff, $.sOn); });
	 }
	$.fn.active = function(a){
		if(typeof(a)!='undefined'){
			if(a===true  || a===1) a='set';
			if(a===false || a===0) a='del'
		}else var a = "get";
		
		switch(a){
			case "get": return this.hasClass('active');
			case "del": return this.removeClass('active');
			default: return this.addClass('active');
		}
	}
function log(text){
	console.log(text);	
}
