var gallery = {
  path:   'xx',
  image:  new Image(),
  idx:    0,
  scroll: 0
};

var gallery_set = function(p) {
    gallery.path = p;
}

$(function() {
  var buttonOpacity = 0.3;
  var thumbOpacity  = 0.5;
  var thumbWidth    = 128;
  var thumbHeight   = 128;
  var thumbSpacing  = 20;
  var visibleThumbs = 5;
  var galleries     = {};

  gallery.frame = $('#gallery-img');
  gallery.thumbframe = $('#gallery-thumbnails');

  function thumb_url(p,f)
  { return 'gallery.php?p='+p+'&t=t&f='+f; }

  function image_url(p,f)
  { return 'gallery.php?p='+p+'&t=i&f='+f; }

  function loadImage(url)
  {
      gallery.image = new Image();
      gallery.image.src = url;
      if (gallery.image.complete)
      {
        imageLoaded();
        return true;
      }
      else
      {
        $(gallery.image).load(imageLoaded);
        return false;
      }
  }

  function preview_offsetof(idx, scrolling)
  {
    var mod = 1;
    var off = thumbSpacing/2;
    if (scrolling)
    { mod = -1; off = 0; }
    return off + mod*(thumbWidth+thumbSpacing)*idx;
  }

  function canstepto(idx)
  {
    return (
      galleries[gallery.path]
      && idx < galleries[gallery.path].length
      && idx >= 0
    );
  }
  function scrollto(idx)
  {
    if (idx < 0) idx = 0;
    else if (idx >= galleries[gallery.path].length)
      idx = galleries[gallery.path].length - 1;

    if (idx >= gallery.scroll + visibleThumbs
      || idx < gallery.scroll)
    {
      // if not already visible.
      var scroll = visibleThumbs*Math.floor (idx/visibleThumbs);
      if (scroll + visibleThumbs >= galleries[gallery.path].length)
        scroll = galleries[gallery.path].length - visibleThumbs;
      if (scroll < 0)
        scroll = 0;
      if (scroll != gallery.scroll)
      {
        gallery.scroll = scroll;
        gallery.thumbframe
          .animate({left: preview_offsetof(scroll, true)+'px'});
      }
      else
      { // otherwise just make sure it is where it's supposed to be.
        gallery.thumbframe
          .css({left: preview_offsetof(gallery.scroll, true)+'px'});
      }
    }
    else
    { // otherwise just make sure it is where it's supposed to be.
      gallery.thumbframe
        .css({left: preview_offsetof(gallery.scroll, true)+'px'});
    }
  }
  function stepto(idx)
  {
    if (idx != gallery.idx)
    {
      var thumbs = $('.thumbnail', gallery.thumbframe)
      if (gallery.idx >= 0)
        thumbs.eq(gallery.idx)
          .fadeTo('fast', thumbOpacity);
      gallery.idx = idx;
      if (! loadImage(image_url(gallery.path,
                          galleries[gallery.path][gallery.idx])))
        gallery.frame.fadeOut(); // will be handled by 'load' event.
      scrollto(idx);
      thumbs.eq(gallery.idx)
        .fadeTo('fast', 1);
    }
  }

  function canstep(d)
  { return canstepto (gallery.idx + d); }
  function step(d)
  { if (canstep(d)) { stepto (gallery.idx+d); } }
  function scroll(d)
  { scrollto (gallery.scroll + d); }

  function imageLoaded()
  {
    gallery.frame
        .queue(function() {
          $(this)
            .css({'background-image': 'url('+gallery.image.src+')'})
            .fadeIn();
          $(this).dequeue();
        });
  }

  gallery_set = function(p) {
    gallery.path = p;
    gallery.idx = -1;
    gallery.scroll = 0;
    gallery.frame.hide();
    gallery.thumbframe.empty();

    if (galleries[p])
    {
      for (var i = 0; i < galleries[p].length; i++)
      {
        (function(i) {
        var thumb = new Image();
        thumb.src = thumb_url(p, galleries[p][i]);
        $("<div/>")
        .css({
          width: thumbWidth+'px',
          height: thumbHeight+'px',
          position: 'absolute',
          left: preview_offsetof(i)
        })
        .click(function() { stepto(i); })
        .addClass('thumbnail')
        .append(thumb)
        .fadeTo(0, thumbOpacity)
        .appendTo(gallery.thumbframe);
        })(i);
      }

      stepto(0);
    }
  };

  $.ajax({
    url: 'gallery.php',
    dataType: 'json',
    data: {t: 'idx'},
    cache: false,
    success: function(data) {
      galleries = data;
      if (galleries[gallery.path])
      { // if something happened before we got here.
        gallery_set(gallery.path);
      }
    }
  });

  $('#gallery-prev')
    .fadeTo('fast', buttonOpacity)
    .click( function() { step(-1); })
    .hover(
      function()
      { if (canstep(-1)) $(this).stop().fadeTo('fast', 1); },
      function()
      { $(this).stop().fadeTo('fast', buttonOpacity); }
    );
  $('#gallery-next')
    .fadeTo('fast', buttonOpacity)
    .click( function() { step(1); })
    .hover(
      function()
      { if (canstep(1)) $(this).stop().fadeTo('fast', 1); },
      function()
      { $(this).stop().fadeTo('fast', buttonOpacity); }
    );
  $('#gallery-rwnd')
    .fadeTo('fast', buttonOpacity)
    .click( function() { scroll(-visibleThumbs); })
    .hover(
      function()
      { $(this).stop().fadeTo('fast', 1); },
      function()
      { $(this).stop().fadeTo('fast', buttonOpacity); }
    );
  $('#gallery-ffwd')
    .fadeTo('fast', buttonOpacity)
    .click( function() { scroll(visibleThumbs); })
    .hover(
      function()
      { $(this).stop().fadeTo('fast', 1); },
      function()
      { $(this).stop().fadeTo('fast', buttonOpacity); }
    );
});

