/*
 * Facebox (for jQuery)
 * version: 1.2 (05/05/2008)
 * @requires jQuery v1.2 or later
 *
 * Examples at http://famspam.com/facebox/
 *
 * Licensed under the MIT:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
 *
*/

(function($) {
  //TODO refactor using data.content_klass
  $.facebox = function(data, klass) {
    $.facebox.loading();
    $.facebox.content_klass = klass;
    if (data.ajax) revealAjax(data.ajax);
    else if(data.image) revealImage(data.image);
    else if(data.images) revealGallery(data.images,data.initial,data.titles);
    else if(data.div) revealHref(data.div);
    else if($.isFunction(data)) data.call($);
    else $.facebox.reveal(data);
  }

  /*
   * Public, $.facebox methods
   */

  $.extend($.facebox, {
    //possible option: noAutoload --- will build facebox only when it is needed
    settings: {
      opacity      : 0.1,
      overlay      : true,
      modal        : false,
      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ]
    },

    html : function(){return '<div id="facebox" style="display:none;"><div class="popup"><table><tbody><tr><td class="tl"/><td class="b"/><td class="tr"/></tr><tr><td class="b"/><td class="body"><div class="content"></div><div class="footer"><a href="#" class="close"></a></div></td><td class="b"/></tr><tr><td class="bl"/><td class="b"/><td class="br"/></tr></tbody></table></div></div>'},

    loading: function() {
      init();
      if($('.loading',$('#facebox'))[0]) return true;
      showOverlay();
      $.facebox.wait();
      if (!$.facebox.settings.modal) {
        $(document).bind('keydown.facebox', function(e) {
          if(e.keyCode == 27) $.facebox.close();//ESC
        });
      }
      $(document).trigger('loading.facebox');
    },

    wait: function() {
      var $f = $('#facebox');
      $('.content',$f).empty();
      $('.body',$f).children().hide().end().append('<div class="loading">&nbsp;</div>');
      $.facebox.centralize();
      $f.show();
      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox');
    },

    centralize: function(){
      $('#facebox').css({
        top:	$(window).scrollTop() + ($(window).height() / 10),
        left: $(window).width() / 2 - (($('#facebox table').width() > 410 ? $('#facebox table').width() : 410) / 2)
      });
    },

    reveal: function(content){
      $(document).trigger('beforeReveal.facebox');
      var $f = $('#facebox');
      $('.content',$f).attr('class',($.facebox.content_klass||'')+' content').html(content);
      $('.loading',$f).remove();
      $('.body',$f).children().fadeIn('normal');
      $f.css('left', $(window).width() / 2 - ($('#facebox table').width() / 2));
      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox');
    },

    close: function() {
			$('#facebox .loading').remove();
      $(document).trigger('close.facebox');
      return false;
    }
  })

  /*
   * Public, $.fn methods
   */

  $.fn.facebox = function(settings) {
    if(settings)$.extend($.facebox.settings, settings);
    if(!$.facebox.settings.noAutoload) init();

    return this.bind('click.facebox',function(){
      $.facebox.loading();

      // support for rel="facebox.inline_popup" syntax, to add a class
      // also supports deprecated "facebox[.inline_popup]" syntax
      var klass = this.rel.match(/facebox\[?\.(\w+)\]?/);
      $.facebox.content_klass = klass ? klass[1] : '';
      revealHref(this.href);
      return false;
    })
  }

  /*
   * Private methods
   */
  // called one time to setup facebox on this page
  function init() {
    if($.facebox.settings.inited) return;
    else $.facebox.settings.inited = true;

    $(document).trigger('init.facebox');
    makeCompatible();

    var imageTypes = $.facebox.settings.imageTypes.join('|');
    $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i');

    $('body').append($.facebox.html());
    //if we did not autoload, so the user has just clicked the facebox and pre-loading is useless
    if(! $.facebox.settings.noAutoload)preloadImages();
    $('#facebox .close').click($.facebox.close);
  }

  function preloadImages(){
    //TODO preload prev/next ?
    $('#facebox').find('.b:first, .close, .bl, .br, .tl, .tr').each(function() {
      var i = $(this).css('background-image');
			if (i != '' && i != 'none') {
				var img = new Image();
      	img.src = i.replace(/url\((.+)\)/, '$1');
			}
    });
  }

  // Backwards compatibility
  function makeCompatible() {
    var $s = $.facebox.settings;
    $s.imageTypes = $s.image_types || $s.imageTypes;
    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml;
  }

  function revealHref(href) {
    if (href.match(/#/)) {
      var url    = window.location.href.split('#')[0];
      var target = href.replace(url,'');
      $.facebox.reveal($(target).show().replaceWith("<div id='facebox_moved'></div>"), $.facebox.content_klass);
    } else if (href.match($.facebox.settings.imageTypesRegexp)) {
      revealImage(href);
    } else { revealAjax(href)}
  }

  function revealGallery(hrefs, initial, titles) {
    var position=$.inArray(initial||0,hrefs);
    if(position==-1)position=0;

    $('#facebox div.footer').append($('<div class="navigation"><p class="title" /><div class="counter"></div></div>'));
		$('#facebox div.popup').append($('<div class="move"><a class="prev" /><a class="next" /></div>'));

    var $nav = $('#facebox .navigation');
		var $pop = $('#facebox .move');
    $(document).bind('afterClose.facebox',function(){$pop.remove();$nav.remove();});

    function change_image(diff){
      position = (position + diff + hrefs.length) % hrefs.length;
      revealImage(hrefs[position], true);
			if (titles) $('.title',$nav).html(titles[position]);
			if (position == 0) {$('.prev',$pop).addClass('disable');} else {$('.prev',$pop).removeClass('disable');}
			if ((position+1) == hrefs.length) {$('.next',$pop).addClass('disable');} else {$('.next',$pop).removeClass('disable');}
      $nav.find('.counter').html(position+1+" / "+hrefs.length);
    }
    change_image(0);

    //bind events
    $('.prev',$pop).click(function(){change_image(-1)});
    $('.next',$pop).click(function(){change_image(1)});
    $(document).bind('keydown.facebox', function(e) {
      if(e.keyCode == 39)change_image(1);  // right
      if(e.keyCode == 37)change_image(-1); // left
    });
		$(document).bind('afterReveal.facebox', function() {$('#facebox .image img').hover(function() {$(this).css({cursor:'pointer'});}, function() {$(this).css({cursor:'auto'});}).click(function(){change_image(1)});});
  }

  function revealImage(href, gallery) {
    $('#facebox .content').empty();
    $.facebox.loading();
    var image = new Image();
    image.onload = function() {
			$.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', $.facebox.content_klass);
		};
    image.src = href;
  }

  function revealAjax(href) {
    $.get(href, function(data) { $.facebox.reveal(data) });
  }

  function skipOverlay() {
    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
  }

  function showOverlay() {
    if(skipOverlay()) return;
    if($('#facebox_overlay').length == 0) $("body").append('<div id="facebox_overlay" class="facebox_hide"></div>');
    $('#facebox_overlay').hide().addClass("facebox_overlayBG").css('opacity', $.facebox.settings.opacity).fadeIn(200);
    if(!$.facebox.settings.modal) $('#facebox_overlay').click(function(){ $(document).trigger('close.facebox')});
    return false;
  }

  function hideOverlay() {
    if(skipOverlay()) return;
    $('#facebox_overlay').fadeOut(200, function() {$("#facebox_overlay").removeClass("facebox_overlayBG").addClass("facebox_hide").remove();})
    return false;
  }

  /*
   * Bindings
   */

  $(document).bind('close.facebox', function() {
    $(document).unbind('keydown.facebox');
    $('#facebox').fadeOut(function() {
			$('#facebox .loading').remove();
      $('#facebox_moved').replaceWith($('#facebox .content').children().hide());
      hideOverlay();
      $('#facebox .loading').hide();
    })
    $(document).trigger('afterClose.facebox');
  });

})(jQuery);