(function($){

function getPageSize(){
  var de = document.documentElement;
  var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
  var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
  var t = (de&&de.scrollTop) || document.body.scrollTop;
  var l = (de&&de.scrollLeft) || document.body.scrollLeft;
  var sw =  (de&&de.scrollWidth) || document.body.scrollWidth;
  var sh =  (de&&de.scrollHeight) || document.body.scrollHeight;

  return {width:w, height:h, scrollTop:t, scrollLeft:l,
          wholeWidth: Math.max(w,sw), wholeHeight: Math.max(h,sh)};
};

function basename(file){
  var b = file.match(/[\/|\\]([^\\\/]+)$/);
  return b[1];
};

$.fn.enlarge = function(options){
  options = $.extend(options,
                     { show_toolbar : true });
  // loading preloading
  var loadingPreloaded = undefined;
  if(options.loading_image != undefined){
    loadingPreloaded = new Image();
    loadingPreloaded.src = options.loading_image;
  }
  // dark background
  var dark= $('<div></div>').get(0);
  $(dark).css({'position':'absolute', 
               'left':0, 'top':0 , 
               'width':'100%', 
               'min-height': '100%',
               'text-align': 'center',
               'background-color':'black', 
               'opacity':'0.5', 'filter':'alpha(opacity=50)' });
  $(dark).hide();
  $('body').append(dark);
  // loading image
  var loading_image = undefined;
  if(loadingPreloaded != undefined){
      var ps = getPageSize();
      loading_image = $('<img alt="loading" />').get(0);
      loading_image.src = loadingPreloaded.src;
      $(dark).append(loading_image);
  }
  // working div
  var image_div = $('<div></div>').get(0);
  $(image_div).css({ 'position':'absolute',
                     'display':'none',
                     'border':'2px solid #bbb',
                     'background-color':'white' });
  $(image_div).hide();
  $('body').append(image_div);

  // clean function
  var clean = function(all){
    $(image_div).empty();
    $(image_div).hide();
    if(all) $(dark).hide();
  };
  var clean_all = function(){
    clean(true);
  };
  // click on dark area will clean all
  $(dark).click(clean_all);

  var $papa = $(this);
  var sources = [];
  var names = [];

  function initialize(index){
      var ps = getPageSize();

      $(dark).css({'left':0, 'top':0 , 
                   'width':'100%', 
                   'height': ps.wholeHeight });

      $(dark).show();

      if(loading_image != undefined){ 
      $(loading_image).css({ 'position' : 'absolute',
                             'top' : ps.scrollTop,
                             'left' : Math.floor((ps.width-loadingPreloaded.width)/2) });
        $(loading_image).show();
      }

      var imgPreloader = new Image();

      imgPreloader.onload = function(){
          if(loading_image) $(loading_image).hide();
          imgPreloader.onload = null;

          var WIDTH  = ps.width;
          var HEIGHT = ps.height;
          var SCROLL_TOP = ps.scrollTop;

          var width  = imgPreloader.width;
          var height = imgPreloader.height;
          var ratio = width/height;

          if(height > HEIGHT-60){
              height = HEIGHT-60;
              width = Math.floor(height*ratio);
          }
          if(width > WIDTH-10){
              width = WIDTH-10;
              height = Math.floor(width/ratio);
          }

          // activate working div
          $(image_div).css({'left' : Math.floor((WIDTH - width)/2 + 2),
                             'top' : SCROLL_TOP + Math.floor((HEIGHT - height)/2 - (options.show_toolbar?12:2)) });
          $(image_div).width(width);
          
          $(image_div).show();

          var img = $('<img alt="enlarged image" class="hand"/>').get(0);

          img.src = imgPreloader.src;
          img.width = width;
          img.height = height;

          if(options.show_toolbar && index < $papa.size()-1){
            $(img).attr('title','next').click(function(){ clean(); initialize(index+1); });
          }
          else{
            $(img).attr('title','close').click(clean_all);
          }

          //upper toolbar 
          if(options.show_toolbar){
              var toolbar = $('<div style="background-color:white; text-align: center"></div>').get(0);
              var lnk = $('<a style="float:right">close</a>').get(0);
              $(lnk).click(clean_all);
              $(toolbar).append(lnk);

              $(toolbar).append('<b>'+(index+1)+'. </b>');
              var lnk = $('<a href="'+img.src+'" style="overflow-x: hidden;">'+unescape(names[index])+'</a>').get(0);
              $(toolbar).append(lnk);

              $(image_div).append(toolbar);
          }

          $(image_div).append(img).show();

          //bottom toolbar
          if(options.show_toolbar){
              var toolbar = $('<div style="background-color:white"></div>').get(0);
              if(index > 0){
                  var lnk = $('<a style="float:left">&laquo; previous</a>').get(0);
                  $(lnk).click(function(){
                     clean();
                     initialize(index-1);
                  });
                  $(toolbar).append(lnk);
              }
              if(index < $papa.size()-1){
                  var lnk = $('<a style="float:right">next &raquo;</a>').get(0);
                  $(lnk).click(function(){
                     clean();
                     initialize(index+1);
                  });
                  $(toolbar).append(lnk);
              }
              $(image_div).append(toolbar);
          }
      };
      // take source
      imgPreloader.src = sources[index];
  };

  // prepare each image
  return this.each(function(index){
    var me = $(this);
    var me_this = $(this).get(0);
    // check
    if(!me.is('img') || me.attr('enlarge') == 'on')return;
    // enable enlarge
    me.attr('enlarge','on');

    // replace parent link
    var papa = me.parent().get(0);
    var src = papa.href;
    if(src == undefined) return;
    $(papa).replaceWith(me_this);

    sources[index] = src;
    if(me.attr('name') != undefined && me.attr('name') != '')
      names[index] = me.attr('name');
    else
      names[index] = basename(src);

    me.addClass('hand');
    me.attr('title','show');

    me.click(function(){
      initialize(index);
    });
  });
};

$.fn.slideshow = function(options){
  if(!options.timeout) options.timeout = 5000;
  if(!options.speed) options.speed = 'slow';

  return this.each(function(){
     var me = $(this);
     var images = [];
     var current = 0;
     // call to get images
     $.get(options.address,[],init,'json');

     function init(infos){
       images = infos;
       load_next_slide();
     };

     function load_next_slide(){
       var info = images[current];

       var imgPreloader = new Image();
       imgPreloader.onload = function(){
         imgPreloader.onload = null;
         if($.isFunction(options.before)) options.before();

         var imgs = me.find('img');
         if(imgs.length > 0)
           imgs.animate({opacity:0}, options.speed, false, function(){ create_slide(info); });
         else
           create_slide(info);
       };

       function create_slide(info){

         me.empty();
         var img = $('<img alt=""/>').get(0);
         $(img).css({ 'opacity': 0 });
         $(img).width(me.width()-8);

         img.src = info.src;
         if(info.url != undefined){
           var a = $('<a href="'+info.url+'"></a>').get(0);
           $(a).append(img);
           me.append(a);
         }
         else{
           me.append(img);
         }

         $(img).animate({opacity:1}, options.speed, false, 
                        function(){ if($.isFunction(options.after)) options.after(info); });

         setTimeout(load_next_slide, options.timeout);
       };

       imgPreloader.src = info.src;
       current = (current+1)%images.length;
     };
  }); 
};


})($);
