var PreviewWindow = new Class({

	Implements: Options,
	options: {
		// This is the factor by which the preview window is scaled
		'scale': 10,	
		// This is the positioning
		'position': {'bottom': '5px', 'right': '5px'},
		'mapTop': 0,
		'mapLeft': 0
	},
	
	initialize: function(container,options) {
	
		// Be nice to the user, if they passed an ID or an element this will be fine
		container = $(container);
		
		// Set any non-default options when instantiated
		this.setOptions(options);
		
		// I don't see any way around what seems to be clunkiness here
		var scale = this.options.scale;
		var prefix = container.id;
		var mapTop = this.options.mapTop;
		var mapLeft = this.options.mapLeft;
		
		// At the moment the preview_image is coming from the background-image of the scrolling div
		var preview_image_src = container.getFirst().getStyle('background-image').replace('url("','').replace('")','').replace('url(','').replace(')','');

		
		// Ensure that the overflow of the container is hidden
		// and that the position is relative
		container.setStyle('overflow','hidden');
		container.setStyle('position','relative');
		
		// Ensure that the internal map is displayed as a block
		// and relatively position
		container.getFirst().setStyle('position','relative');
		container.getFirst().setStyle('display','block');
					
		 
		// This wrapper div is required to allow us to absolutely position
		// the navigation window without it being dragged around
		var wrapper = new Element('div', {
			'id': prefix+'_wrapper',
		    'styles': {
		        'position': 'relative',
		        'width': container.getStyle('width'),
		        'height': container.getStyle('height')
		    }
	    });
		
		// The preview window itself
		var preview_window = new Element('div', {
			'id': prefix+'_preview_window',
		    'styles': {
		        'overflow': 'hidden',
		        'position': 'absolute',
		        'width': container.getFirst().getStyle('width').toInt()/scale,
		        'height': container.getFirst().getStyle('height').toInt()/scale,
		        'border': '1px solid black',
		        'background': 'white'
		    }
	    });

		// Set the position of the preview_window from the options
		preview_window.setStyles(this.options.position);
		
		// The preview image
		var preview_image = new Element('img', {
			'id': prefix+'_preview_image',
			'alt': '',
			'src': preview_image_src,
			'styles': {
				'width': container.getFirst().getStyle('width').toInt()/scale,
				'height': container.getFirst().getStyle('height').toInt()/scale
			}	
		}); 
		
		// The preview mask
		var preview_mask = new Element('div', {
			'id': prefix+'_preview_mask',
		    'styles': {
		        'background': 'black',
		        'opacity': '0.3',
		        'left': container.scrollLeft/scale,
		        'top': container.scrollTop/scale,
		        'position': 'absolute',
		        'width': container.getStyle('width').toInt()/scale,
		        'height': container.getStyle('height').toInt()/scale        
		    }
	    });
	    
	  	// Wrap the map in the wrapper 
	 	wrapper.wraps(container);   
	    // The preview window is injected into the bottom of the wrapper
	    preview_window.inject(wrapper);
	    // Then the preview_image is injected into the bottom of the preview_window
	    preview_image.inject(preview_window);    
	    // The then preview_mask is injected into the bottom of the preview_window
	  	preview_mask.inject(preview_window);    
	    		
		// Preview window with limiter
		new Drag(prefix+'_preview_mask', {
			limit: {
				'x': [0,$(prefix+'_preview_window').getStyle('width').toInt()-$(prefix+'_preview_mask').getStyle('width').toInt()], 
				'y': [0,$(prefix+'_preview_window').getStyle('height').toInt()-$(prefix+'_preview_mask').getStyle('height').toInt()]
			},	
		    onDrag: function(el){       
				el.addClass('dragging');
		        container.scrollLeft = $(prefix+'_preview_mask').getStyle('left').toInt()*scale;
		        container.scrollTop = $(prefix+'_preview_mask').getStyle('top').toInt()*scale;	      
		    },
		    onComplete: function(el){
		        el.removeClass('dragging');	       
				el.getStyle('left').toInt()*scale;		
		    }		    
		});
		
		//create an Adobe reader style drag to scroll container
		new Drag(container, {
		    style: false,
		    invert: true,
		    modifiers: {x: 'scrollLeft', y: 'scrollTop'},
		    snap: 0,		   
		    onDrag: function(el){
		        el.addClass('dragging');
		        $(prefix+'_preview_mask').setStyle('left',el.scrollLeft/scale);
		        $(prefix+'_preview_mask').setStyle('top',el.scrollTop/scale);
		    },
		    onComplete: function(el){
		        el.removeClass('dragging');
		    }		    
		});
				
		$(prefix+'_preview_mask').setStyle('left',mapTop/scale);
		$(prefix+'_preview_mask').setStyle('top',mapLeft/scale);
		        	
		// Establish the scrollable map
		new Fx.Scroll(container, {
		    offset: {'x': 0,'y': 0},
		    'transition':Fx.Transitions.linear,
	        'duration':200,	    
		    wheelStops : false
		}).set(mapTop,mapLeft);
		
				
	}
	
});

