/*************************************************************
Damien Benier for iShopYouShop.com
(inspired by a Chris Campbell script: http://particletree.com)
*************************************************************/

Event.observe(document, 'dom:loaded', initializeLightbox, false);

var lightboxOnWindowLoaded = null;
var lightbox = {};

/* Initialize lightbox parameters */
lightbox.init = function(box, overlay, options)
{
  this.options = Object.extend({contentClass:'content', onLoadingCallback:null, onResizingCallback:null, onShowCallback:null, onReadyCallback:null, defaultWidth:270, defaultHeight:180, maxImageWidth:500, maxImageHeight:400, hMargin:0, vMargin:0}, options);
  this.box = $(box);
  this.boxContent = this.box.down('.' + this.options.contentClass);
  this.overlay = $(overlay);
  this.closingTime = 1;
  this.contentScripts = null;
  this.onCloseCallbacks = new Array();
}

/* Start a lightbox session and sets a callback for loading completion */
lightbox.load = function(target, method, parameters)
{ 
  MyLogger.log('lightbox load ' + target);

  if (!this.closingTime){ lightboxOnWindowLoaded = {func:'load', target:target, method:method, parameters:parameters}; return false; }
  
  this.target = target;
  this.method = method || 'get';
  this.parameters = parameters || '';
  this.image = null;
  this.imagesCollection = null;
  
  this.open();
  this.setLoading();
  
  var splitTarget = this.target.split('#');
  if (splitTarget.length > 1)
  {
    /* internal link */
    this.processResult({responseText:$(splitTarget[1]).innerHTML});
  }
  else
  {
    /* ajax link */
    var myAjax = new Ajax.Request(
      this.target,
      {
        method: this.method,
        parameters: this.parameters,
        onFailure: this.handleError.bindAsEventListener(this),
        onSuccess: this.processResult.bindAsEventListener(this)
      }
    );
  }
  
  return false;
}

/* Start a lightbox session that loads an image */
lightbox.loadImage = function(imageUrl, collectionClassName)
{
  MyLogger.log('lightbox loadImage ' + target);
  
  if (!this.closingTime){ lightboxOnWindowLoaded = {func:'loadImage', imageUrl:imageUrl}; return false; }
  
  this.target = '';
  this.method = '';
  this.parameters = '';
  this.image = new Image();
  this.imagesCollection = null;
  
  if (collectionClassName)
  {
    var firstCollectionElt = null;
    var nextCollectionElt = null;
    
    $$('a.' + collectionClassName).each(function(collectionElt)
    {
      if (!firstCollectionElt) firstCollectionElt = collectionElt;
      if (nextCollectionElt == firstCollectionElt) nextCollectionElt = collectionElt;
      if (collectionElt.href == imageUrl) nextCollectionElt = firstCollectionElt;
    });
    
    if (nextCollectionElt) this.imagesCollection = {className:collectionClassName, nextUrl:nextCollectionElt.href};
  }
  
  this.open();
  this.setLoading();
  
  Event.observe(this.image, 'load', this.processImage.bindAsEventListener(this));
  this.image.src = imageUrl;
  
  return false;
}

/* Set a callback that wiil be closed at the end of the ligthbox session */
lightbox.addOnCloseCallback = function(callback)
{
  this.onCloseCallbacks.push(callback);
}

/* Check if there already is a closeCallback */
lightbox.hasACloseCallback = function()
{
  return this.onCloseCallbacks.size() > 0;
}

/* Set lightbox size to the given width and height */
lightbox.setSize = function(width, height)
{
  var width = parseFloat(width);
  var height = parseFloat(height);
  
  var hStyle = {width: width + 'px', marginLeft: -Math.round(width / 2) + 'px'};
  var vStyle = {height: height + 'px', marginTop: -Math.round(height / 2) + 'px'};
  
  if (this.isVisible())
  {
    if (this.options.onResizingCallback) this.options.onResizingCallback();
    
    new Effect.Morph(this.box, { style: hStyle, duration: 0.5 });
    new Effect.Morph(this.box, { style: vStyle, duration: 0.5, queue: 'end', afterFinish: this.showContent.bindAsEventListener(this) });
  }
  else
  {
    this.box.setStyle(hStyle);
    this.box.setStyle(vStyle);
  }
  
  return;
}

lightbox.isVisible = function(display)
{
  return this.overlay  && (this.overlay.style.display  == 'block')
      && this.box && (this.box.style.display == 'block');
}
  
/* Called when Ajax request fails */
lightbox.handleError = function(response)
{
  MyLogger.log('lightbox handleError (target:' +  this.target + ')');

  var info = '<div align="center">Oops... error !</div>'
           + '  <!-- target=' + this.target + ' -->'
           + '  <!-- method=' + this.method + ' -->'
           + '  <!-- parameters=' + this.parameters + ' -->';
  this.setContent(info);
  this.showContent();
}

/* Process and Display Ajax response */
lightbox.processResult = function(response)
{
  var html = response.responseText;
  
  MyLogger.log('lightbox processResult:' + html.replace(/[\r\n]{2}/g, '').truncate(150));
  
  this.contentScripts = html.extractScripts();
  html = html.stripScripts();
  
  var givenSize = false;
  this.setContent(html);
  
  for(child = this.boxContent.firstChild; child; child = child.nextSibling)
  {
    if (child.style && child.style.width && child.style.height) // and child.class == 'lightboxContent'
    {
      this.setSize(parseFloat(child.style.width) + this.options.hMargin, parseFloat(child.style.height) + this.options.vMargin);
      givenSize = true;
      break;
    }
  }
  
  if (!givenSize) this.showContent();
}

/* Process and Display the Image */
lightbox.processImage = function()
{
  var previewWidth = Math.min(this.image.width, lightbox.options.maxImageWidth);
  var previewHeight = Math.min(this.image.height, lightbox.options.maxImageHeight);
  
  var imageRatio = (this.image.width / this.image.height);
  var previewRatio = (previewWidth / previewHeight);
  var isOriginalTooWide = (imageRatio > previewRatio);
  
  var displayWidth = isOriginalTooWide ? previewWidth : (previewHeight * this.image.width / this.image.height);
  var displayHeight = isOriginalTooWide ? (previewWidth * this.image.height / this.image.width) : previewHeight;
  
  var html  = '';
  var aAttributes = lightbox.imagesCollection ? ' href="' + lightbox.imagesCollection.nextUrl + '" onclick="return lightbox.loadImage(this.href, \'' + lightbox.imagesCollection.className + '\');"' : '';
 
  html += '<div align="center">';
  html +=   '<a' + aAttributes + '>';
  html +=     '<img src="' + this.image.src + '" width="' + displayWidth + '" height="' + displayHeight + '" style="margin:8px;" />';
  html +=   '</a>';
  html += '</div>';
  
  this.setContent(html);
  
  this.setSize(displayWidth + this.options.hMargin, displayHeight + this.options.vMargin);
}

/* Set the lightbox content */
lightbox.setContent = function(text)
{
  this.boxContent.update(text);
}

/* Set ready (content loaded and displayed) */
lightbox.setReady = function()
{
  if (this.contentScripts)
  {
    this.contentScripts.each(function(text){ eval(text); });
    this.contentScripts = null;
  }
  
  if (this.options.onReadyCallback) this.options.onReadyCallback(this.target);
}

/* Show content */
lightbox.showContent = function()
{
  if (this.options.onShowCallback) this.options.onShowCallback();
  
  if (browserIsIE)
  {
    this.boxContent.show();
    this.setReady();
  }
  else new Effect.Appear(this.boxContent, { afterFinish: this.setReady.bindAsEventListener(this) });
  
}

/* Set loading */
lightbox.setLoading = function()
{
  this.setContent('');
  this.boxContent.hide();
  if (this.options.onLoadingCallback) this.options.onLoadingCallback();
}

/* Open the lightbox */
lightbox.open = function()
{
  if (this.isVisible()) return;
  
  if (typeof document.body.style.maxHeight == 'undefined') $(document.body).setStyle({height: '100%', width: '100%'});
  
  var date = new Date();
  if (((date.getTime() - this.closingTime) > 3) && !this.isVisible()) this.setSize(lightbox.options.defaultWidth, lightbox.options.defaultHeight);
  
  this.overlay.style.display = 'block';
  this.box.style.display = 'block';
  
  return false;
}

/* Close the lightbox */
lightbox.close = function()
{
  if (!this.isVisible()) return;
  
  var date = new Date();
  this.closingTime = date.getTime();
  
  this.setContent('');
  this.boxContent.hide();
  this.overlay.style.display = 'none';
  this.box.style.display = 'none';
  
  this.onCloseCallbacks.each(function(callback){ callback(); });
  this.onCloseCallbacks.clear();
  
  return false;
}


/*-----------------------------------------------------------------------------------------------*/


function initializeLightbox()
{
  MyLogger.log('initializing Lightbox');

  htmlBody = document.getElementsByTagName('body')[0];
  
  var overlay = new Element('div', { id: 'lightbox-overlay', className: 'overlay'});
  if (browserIsIE6) overlay.innerHTML = '<iframe></iframe>'; /* ie6 hack */
  htmlBody.appendChild(overlay);

  var box = new Element('div', { id: 'lightbox', className: 'lightbox'});
  var html = '';
  html += '<a class="close" onclick="return lightbox.close();" href="#">&nbsp;</a>';
  html += '<div class="loading" id="lightbox-loading"><img src="' + imagesRepository + 'loading_blue.gif" /></div>';
  html += '<div class="content"></div>';
  box.innerHTML = html;
  htmlBody.appendChild(box);
  
  var onLightboxLoading = function(){ $('lightbox-loading').show(); };
  var onLightboxResizing = function(){ };
  var onLightboxShow = function(){ $('lightbox-loading').hide(); };
  var onLightboxReady = function(url){ if (url) document.trackAjaxPageLoad(url); };
  
  lightbox.init(box, overlay, {onLoadingCallback:onLightboxLoading, onResizingCallback:onLightboxResizing, onShowCallback:onLightboxShow, onReadyCallback:onLightboxReady, hMargin:34, vMargin:20});
  
  /* if lightbox url given in the url */
  if (target = getUrlArg('lightboxurl')) lightboxOnWindowLoaded = {func:'load', target:target, method:'get', parameters:''};
  
  if (lightboxOnWindowLoaded)
  {
    if (lightboxOnWindowLoaded['func'] == 'load')
      lightbox.load(lightboxOnWindowLoaded['target'], lightboxOnWindowLoaded['method'], lightboxOnWindowLoaded['parameters']);
    else
      lightbox.loadImage(lightboxOnWindowLoaded['imageUrl']);
  }
}

