var ImageShow = Class.create({
  initialize: function(thumbnailImg, previewOptions) {
    this.thumbnailImg = $(thumbnailImg);
    this.previewOptions = previewOptions || {};

    this.thumbnailImg.observe('mouseover', this.onMouseOver.bindAsEventListener(this));
    this.thumbnailImg.observe('mouseout', this.onMouseOut.bindAsEventListener(this));

    // Cache the bound onMouseMove handler for Event.stopObserving method
    this.onMouseMoveHandler = function(event) {
      PreviewWindow.getInstance().followMouse(event.pointerX(), event.pointerY());
    }.bindAsEventListener(this);
  },

  onMouseOver: function(event) {
    this.thumbnailImg.observe('mousemove', this.onMouseMoveHandler);
    PreviewWindow.getInstance().show(event.pointerX(), event.pointerY(), this.previewOptions);
  },

  onMouseOut: function(event) {
    this.thumbnailImg.stopObserving('mousemove', this.onMouseMoveHandler);
    PreviewWindow.getInstance().hide();
  }
});


var PreviewWindow = Class.create({
  initialize: function() {
    this.windowElement = new Element('div', {id:'imgPreview', style:'display:none; position:absolute;'});
    this.titleElement = new Element('small', {id:'imgPreviewTitle'});
    this.imageElement = new Element('img', {id:'imgPreviewImage'});
    this.progressBarElement = new Element('div', {id:'imgPreviewProgressBar', style:'display:none;'});

    this.windowElement.insert(
      this.titleElement
    ).insert(
      new Element('div', {id:'imgPreviewBody'}).insert(
        this.imageElement
      ).insert(
        this.progressBarElement.update('Download &nbsp;&nbsp;<img src="/images/wait.gif">')
      )
    );

    document.body.insert(this.windowElement);
  },

  loadPreview: function(options) {
	this.titleElement.update(options.title);
    var oldImg = this.imageElement;
    this.imageElement = new Element('img', {
      id: 'imgPreviewImage',
      src: options.src
	  ,style :"display:none;"
    });
	// Refresh this.width, this.height
	if (oldImg) oldImg.replace(this.imageElement);
	Object.extend(this, this.windowElement.getDimensions());
  }
  , checkPreview : function() {
	
	if (this.imageElement.complete == true) {
		var height = this.imageElement.getHeight();
		var width = this.imageElement.getWidth();
		var ratio = width / height;
		
		var v = document.viewport.getDimensions();
		var maxWidth = v.width / 2;
		var maxHeight = v.height / 2;
		
		if ((height > maxHeight) || (width > maxWidth)) {
		//alert("reset size");
			if (width > height) {
				width = maxWidth;
				height = width / ratio;
			}
			else {
				height = maxHeight;
				width = height * ratio;
			}
	
			this.imageElement.setStyle("width:" + width + "pw;height:" + height + "px"); //.style.width = width;
			//this.imageElement.style.height = height;
		}
		

		this.imageElement.show();
		this.width = this.windowElement.getDimensions().width;
		this.height = this.windowElement.getDimensions().height;
		this.progressBarElement.hide();
		this.followMouse();
		window.clearTimeout(this.timerId);
	}
	else {
		this.timerId = this.checkPreview.bind(this).delay(0.25);
	}
  },

  show: function(x, y, options) {
    var viewport = document.viewport.getDimensions();
    if (viewport.width < 600 || viewport.height < 450) {
      return;
    }

    if (typeof options == 'object') {
      this.loadPreview(options);
    }
	this.windowElement.show();
	this.width = this.windowElement.getDimensions().width;
	this.height = this.windowElement.getDimensions().height;
    this.followMouse(x, y);
	
	this.progressBarElement.show();
	
	this.timerId = this.checkPreview.bind(this).delay(0.25);
  },

  hide: function() {
    window.clearTimeout(this.timerId);
    this.windowElement.hide();
    this.windowElement.setStyle({
      top: '-' + this.height + 'px',
      left: '-' +  this.width + 'px'
    });
  },
  followMouse: function(mouseX, mouseY) {
    var x = 0, y = 0;
    var mouseOffset = 24;
    var mouseXpos = '', mouseYpos = '';
	
	mouseX = mouseX || this.mouseX || 0;
	mouseY = mouseY || this.mouseY || 0;
	
	this.mouseX = mouseX;
	this.mouseY = mouseY;

    var viewport = Object.extend(
      document.viewport.getDimensions(),
      document.viewport.getScrollOffsets()
    );
    mouseX -= viewport.left;
    mouseY -= viewport.top;
    if (mouseY + mouseOffset < (viewport.height - this.height) / 2) {
      mouseYPos = 'top';
      y = mouseY + mouseOffset;
    } else if (mouseY - mouseOffset > (viewport.height + this.height) / 2) {
      mouseYPos = 'bottom';
      y = mouseY - mouseOffset - this.height;
    } else {
      mouseYPos = 'middle';
      y = (viewport.height - this.height) / 2;
    }
    if (mouseYPos != 'middle'
        && ((mouseX + mouseOffset > (viewport.width - this.width) / 2)
         && (mouseX - mouseOffset < (viewport.width + this.width) / 2))) {
      mouseXPos = 'center';
      x = (viewport.width - this.width) / 2;
    } else if (mouseX > viewport.width / 2) {
      mouseXPos = 'right';
      x = mouseX - mouseOffset - this.width;
    } else {
      mouseXPos = 'left';
      x = mouseX + mouseOffset;
    }

    this.windowElement.setStyle({
      top: y + viewport.top + 'px',
      left: x + viewport.left + 'px'
    });
  }
});
PreviewWindow.getInstance = function() {
  if (PreviewWindow.instance == null) {
    PreviewWindow.instance = new PreviewWindow();
  }
  return PreviewWindow.instance;
}
