$.fn.panView = function(width,height) {
	return this.each(function(){
		
		var panViewWidthType = 'static';
		var panViewHeightType = 'static';
		var panId = this.id + "Pan";
		var panMaskId = this.id + "PanMask";
		var mouseState = 'up';
		var mouseStartX = 0;
		var mouseStartY = 0;
		var mouseDropX = 0;
		var mouseDropY = 0;
		var cssWidth;
		var cssHeight;
		var eThis = this; 
		// show image
		$(this).css('display','block');

		// check arguments
		if(width == 'auto') {		
			width = (this.clientWidth < document.body.clientWidth) ? this.clientWidth : document.body.clientWidth;
			panViewWidthType = 'dynamic';
		}
		if(height == 'auto') {
			height = (this.clientHeight < document.body.clientHeight) ? this.clientHeight : document.body.clientHeight;
			panViewHeightType = 'dynamic';
		}
	
		var bounds = new GetElementBounds(eThis);

		function MouseEvent(e) {
			this.e = e ? e : window.event; 
			this.source = e.target ? e.target : e.srcElement;
			this.x = this.e.pageX ? this.e.pageX : this.e.clientX;
			this.y = this.e.pageY ? this.e.pageY : this.e.clientY;
			if(window.event) {
				this.x = (document.body.scrollLeft) ? this.x + document.body.scrollLeft : this.x;
				this.y = (document.body.scrollTop) ? this.y + document.body.scrollTop : this.y;
			}
		}

		function GetElementBounds(o) {
			this.width = o.clientWidth;
			this.height = o.clientHeight;
			this.minX = (width - this.width);
			this.minY = (height - this.height);
			this.maxX = 0;
			this.maxY = 0;
		}
		
		$(this).wrap('<div id="' + panId + '" style="width:' + width + 'px; height:' + height + 'px; overflow:hidden; position: relative;"><div id="' + panMaskId + '" style="left:0px;top:0px;position:relative;"></div></div>');
		
		$(document).resize(function(e) {
			alert('mosso');
			if(panViewWidthType == 'dynamic') {
				width = (this.clientWidth < document.body.clientWidth) ? this.clientWidth : document.body.clientWidth;
				$('div#' + panId).css('width',width + 'px');
			}
			if(panViewHeightType == 'dynamic') {
				height = (this.clientHeight < document.body.clientHeight) ? this.clientHeight : document.body.clientHeight;
				$('div#' + panId).css('height',height + 'px');
			}
			if(panViewWidthType == 'dynamic' || panViewHeightType == 'dynamic') {
				bounds = null;
				bounds = new GetElementBounds(eThis);
				
				mouseStartX = 0;
				mouseStartY = 0;
				mouseDropX = 0;
				mouseDropY = 0;
				
				$('div#' + panMaskId).css('left', 0 + 'px').css('top',0 + 'px');

			}

		});

		$('div#' + panId).mousedown(function(e) {
			
			mouseState = 'down';
			
			var me = new MouseEvent(e);
			
			mouseStartX = me.x;
			mouseStartY = me.y;	
		
			me = null;
			
			$(this).css('cursor','move');

			return false
		});

		$('div#' + panId).mouseup(function(e) {

			mouseState = 'up';
			
			mouseDropX = parseInt($('div#' + panMaskId).get(0).style.left);
			mouseDropY = parseInt($('div#' + panMaskId).get(0).style.top);
			$(this).css('cursor','default');

			var pixelX = e.pageX-$('div#' + panMaskId).position().left+Math.abs(mouseDropX);
			var pixelY = e.pageY-$('div#' + panMaskId).position().top+Math.abs(mouseDropY);
			//alert(e.x+' '+e.y);
		});

		$(document.body).mousemove(function(e) {
            if (!$.browser.msie && !$.browser.safari){
				var me = new MouseEvent(e);
				var ePan = $('#' + panId);
				var bounds = new GetElementBounds(eThis);
				if (ePan.length > 0) {
					//alert($('#imagePanPan').offset().top+' '+$('#imagePanPan').offset().left+' '+me.x+' '+me.y);
					// simple bound check.
					//if(me.x < ePan.offsetLeft || me.x > (ePan.offsetLeft + width) || me.y < ePan.offsetTop || me.y > (ePan.offsetTop + height)) {				
					if (me.x < ePan.offset().left || me.x > (ePan.offset().left + width) || me.y < ePan.offset().top || me.y > (ePan.offset().top + height)) {
						mouseState = 'up';
					}
					
					if (mouseState == 'down') {
	
						if (resetPan) {
							mouseDropX = mouseX;
							mouseDropY = mouseY;
							resetPan = false;				
						}				
					
						var iLeft = mouseDropX - (mouseStartX - me.x);
						var iTop = mouseDropY - (mouseStartY - me.y);
						
						if (iLeft < bounds.minX) {
							iLeft = bounds.minX;
						}
						else 
							if (iLeft > bounds.maxX) {
								iLeft = bounds.maxX;
							}
						
						if (iTop < bounds.minY) {
							iTop = bounds.minY;
						}
						else 
							if (iTop > bounds.maxY) {
								iTop = bounds.maxY;
							}
						
						$('div#' + panMaskId).css('left', iLeft + 'px').css('top', iTop + 'px');
						
					}
				}
				me = null;
	
				return false
			}
		});

	});
};
