/**
 * @author landon
 * @date   10/06/2008
 */
(function($) {
	var defaults = {
		overlap: {
			x:40,
			y:40
		},
		nav: {
			margin:10,
			width:100,
			height:100
		},
		navContents:"<img src=\"images/office/nav.png\"/>"
    };
	$.fn.extend({
		scrollingPresentation:function(opts) {
			opts = $.extend(defaults, opts || {})
            $(this).each(function(){
				$.fn._scrollingPresentationInit.apply(this, new Array(opts));
            });
		},
		_scrollingPresentationInit:function(opts) {
			var self = this;
			// create navigation panel
			var tmpW = $(this).parent().css('width');
			$(this).parent().css({
				visibility: 'hidden',
				width:''
			});
			$(this).css({
				width:this.scrollWidth+'px',
				position: 'relative',
				top:'0px',
				left:'0px'
			});
			$(this).parent().css({
				overflow:'hidden',
				visibility:'visible',
				width: tmpW,
			});
			var c = $("<div></div>")
				.data('width',$(this).parent().width())
				.data('height',$(this).parent().height());
			opts.frames = {
				x:Math.round(($(this).width()-opts.overlap.x)/c.data('width')),
				y:Math.round(($(this).height()-opts.overlap.y)/c.data('height'))
			}
			c.css({
				position:'absolute',
				zIndex:1000,
				width:(c.data('width'))-2*opts.nav.margin+'px',
				height:(c.data('height'))-2*opts.nav.margin+'px',
				margin:opts.nav.margin
			}).insertBefore(this);
			$(this)
				.data('xFrame',(c.data('width')-opts.nav.width-2*opts.nav.margin)/(opts.frames.x-1))
				.data('yFrame',(c.data('height')-opts.nav.height-2*opts.nav.margin)/(opts.frames.y-1))
				.data('xRatio',((c.data('width')-opts.overlap.x)*(opts.frames.x-1))/(c.data('width')-2*opts.nav.margin-opts.nav.width))
				.data('yRatio',((c.data('height')-opts.overlap.y)*(opts.frames.y-1))/(c.data('height')-2*opts.nav.margin-opts.nav.height));
			var nav = $("<div></div>")
				.addClass('scrollingPresentationNav')
				.css({
					position:'absolute',
					top:'0px',
					left:'0px',
					width:opts.nav.width+'px',
					height:opts.nav.height+'px'
				})
				.appendTo(c)
				.draggable({
					containment:'parent',
					delay:100,
					opacity:.8,
					start:function() {
							$(self).data('running', true);
							$.fn._scrollingPresentationStart($(self));
					},
					stop:function() {
						$(self).data('running',false);
						// calculate snap target
						var left = parseFloat($(this).css('left').replace('px',''));
						var top = parseFloat($(this).css('top').replace('px',''));
						left = Math.round(left/$(self).data('xFrame'))*$(self).data('xFrame');
						top = Math.round(top/$(self).data('yFrame'))*$(self).data('yFrame');
						$.fn._scrollingPresentationMoveNav($(this),{top:top, left:left},$(self))
					},
					drag:function(e,ui) {
						$.fn._scrollingPresentationSetTarget(ui.position,$(self));
					},
					cancel:"[rel^='arrow']"
				})
			nav.html(opts.navContents);
			$(this)
				.data('nav',nav)
				.data('opts',opts);
			if(opts.arrowStateFunc) {
				var res = {
					left:false,
					right:true,
					up:false,
					down:true
				};
				opts.arrowStateFunc(res);
			}			
		},
		_scrollingPresentationSlideTo: function(m,o,force) {
			var nav = o.parent().parent();
			var o = nav.parent().next();
			var pos = {
				left:parseFloat(nav.css('left').replace('px','')),
				top:parseFloat(nav.css('top').replace('px',''))
			}
			pos.left += o.data('xFrame') * m.x;
			pos.top += o.data('yFrame') * m.y;
			if (o.data('moving') != true || force) {
				$.fn._scrollingPresentationMoveNav(nav, pos, o);
			}
		},
		_scrollingPresentationMoveNav:function(nav,position,o) {
			o.data('moving',true);
			nav.animate({
					left:position.left+'px',
					top:position.top+'px'
				},'fast',function() {
					clearInterval(o.data('timer'));
					$.fn._scrollingPresentationSetTarget(position,o);
					$.fn._scrollingPresentationStart(o);
					o.data('moving',false);
				});
			var res = {
				x:Math.floor(position.left/o.data('xFrame')),
				y:Math.floor(position.top/o.data('yFrame'))
			};
			res = {
				right:res.x+1<o.data('opts').frames.x,
				left:res.x>0,
				down:res.y+1<o.data('opts').frames.y,
				up:res.y>0
			}
			if(o.data('opts').arrowStateFunc) {
				o.data('opts').arrowStateFunc(res);
			}
		},
		_scrollingPresentationSetTarget: function(position,o) {
			o.data('targetX',position.left*o.data('xRatio'));
			o.data('targetY',position.top*o.data('yRatio'));
		},
		_scrollingPresentationStart:function(o) {
			var xDif, yDif, left, top;
			clearInterval(o.data('timer'));
			var t = setInterval(function() {
				left = parseFloat(o.css('left').replace('px',''));
				top = parseFloat(o.css('top').replace('px',''));
				xDif = (o.data('targetX')+left);
				yDif = (o.data('targetY')+top);
				//$("body").append("<div>("+o.css('left')+","+top+")</div>");
				//$("body").append("<div>("+xDif+","+yDif+")</div>");
				if(o.data('running')==false && Math.abs(xDif)<2 && Math.abs(yDif)<2) {
					clearInterval(o.data('timer'));
				} else {
					xDif *= .2;
					yDif *= .2;
				}
				o.css({
					left:left-xDif+'px',
					top:top-yDif+'px'
				});
			},10);
			o.data('timer',t);
		}
	})
})(jQuery);

