(function(){

  function orient(){
    var view = viewer.element(),
        img = view.find("img").hide(),
        image_r = (img.width() / img.height()),
        view_r  = (view.width() / view.height()),
        o   = ["100%", "auto"];

    o = (image_r >= view_r) ? o : o.reverse()
    img.css({width:o[0], height:o[1]});

    var d = view.find(".description");
    if(d.length > 0){
	    img.height(img.height()-d.height());
     }
        img.show();

  }
	
	window.image = {
		orient:orient
	}
	
})();

(function(){

  var viewer;

  function load(html){
    viewer.fadeOut(200,
      function(){
	viewer.html(html).show().css({visibility:"hidden"});
        viewer.find("img").load(function(){image.orient(); controller.resize(); viewer.css({visibility:"visible"}); viewer.hide().fadeIn(200)})
        
        controller.position(true);
      });
  }

  function element(){
    return viewer;
  }

  $(document).ready(function(){
    viewer = $("#viewer");
  })
  
	window.viewer = {
	  load:load,
	  element:element
	}

})();

(function(){

  var timer, running, speed;

  function init(){
    // FIXME place this value as a JS var
    speed = $("#viewer").attr("speed") * 1000;
    running = true;
    if(speed == 0) stop();
  }

  function update(){
    if(running){start();}
  }

  //////////////////////////////////////////////////////////////////////////////
  function start(){
    running = true;
    timer = setTimeout(function(){
      if(running){controller.advance(); controller.next_image();}}, speed);
  }

  //////////////////////////////////////////////////////////////////////////////
  function stop(){
    clearTimeout(timer);
    running = false;
  }
	
	window.slidetimer = {
		init:init,
		stop:stop,
		update:update
	}

})();

(function(){

  var images = {};

  function cache(position){
    position = position == null ? 0 : position;
    var e = data(position);

    if(e){
      get(position, function(image){cache(image.position+1)})
    }
  }

  function data(position){
    if(dock.thumbnails()[position] == null){ return null}
    var image = {};
    image.position  = position;
    image.thumbnail = dock.thumbnails()[position];
    image.id        = image.thumbnail.id.replace(/image_/,"");
    image.path      = $(image.thumbnail).find('img').attr("path");
    image.html      = images[image.id];
    return image;
  }

  function get(position, callback){
    var image = data(position);

    if(images[image.id] == null){
      $.get(image.path, null, function(d){
        images[image.id] = d;
        image.html = d;
        callback(image);
      })
    } else {
      callback(image);
    }
  }

	window.images = {
		cache:cache,
		get:get
	}

})();

(function(){

  var el_dock, el_table, el_thumnails, thumbnail_disabled;

  function init(){
    thumbnail_disabled = false;
    el_dock  = $("#dock");
    el_table = $("table.images");
    el_thumnails = el_table.find("td");
    setTimeout(size, 200);

    $.each(el_thumnails, function(position, el){
      $(el).click(function(){
          if(!thumbnail_disabled){slidetimer.stop(); controller.show(position);}
        }
        );
    })

  }

  function thumbnails(){
    return el_thumnails;
  }

  //////////////////////////////////////////////////////////////////////////////
  function size(){
    var total_width = 0,
        img,
        t;

    el_thumnails.each(function(){total_width += $(this).find("img").width()});
    el_thumnails.each(function(){
      t = $(this);
      img = t.find("img");

      t.css({width: (100 * (img.width()/total_width))+"%"})
    });

    // IE requires the size to be explicitly set
    el_table.css({width:total_width});
    controller.resize();
  }


  function el(){
    return el_dock;
  }

  function table(){
    return el_table;
  }

  //////////////////////////////////////////////////////////////////////////////
  function enable_scroll(){
    var w = $(window).width(),
        x = ((el_table.width()+16)-w);

    $(".drag_parent").css({
        width:(el_table.width()+x)+"px",
        left:-1*(x)});

    $(".show_drag").fadeIn(500)

    el_table.addClass("draggable").
        draggable("enable").
        draggable({
          start:function(){thumbnail_disabled = true},
          stop:function(){setTimeout(function(){thumbnail_disabled = false}, 10)},
          axis: 'x', containment: "parent" })
  }

  //////////////////////////////////////////////////////////////////////////////
  function disable_scroll(){
    $(".show_drag").fadeOut(500);
    $(".drag_parent").css({width:"100%", left:"0px"})

    el_table.removeClass("draggable").draggable("disable");
    el_table.css({left:0});
  }
	
	window.dock = {
		init:init,
		el:el,
		table:table,
		size:size,
		thumbnails:thumbnails,
		enable_scroll:enable_scroll,
		disable_scroll:disable_scroll
	}

})();

(function(){
  var navigation,
      footer,
      frame,
      blurb,
      thumbnail_selected,
      image_position =0;

  //////////////////////////////////////////////////////////////////////////////
  function init(){
    var width;

    // TODO necessary?
    slidetimer.stop();

    frame      = $("#frame");
    blurb      = $("#blurb");
    footer = $("#footer");
    dock.init();
    resize();
    next_image();
    slidetimer.init();
    images.cache(1);
    $("#viewer").live("click", image_click)
    $("#viewer").live("mousemove", image_cursor)
  }

  function rewind(){
    image_position--;
  }

  function advance(){
    image_position++;
  }

  function image_cursor(event){
    var c = (event.pageX > $(document).width()/2) ? "e-resize" : "w-resize"
    $("#viewer").css("cursor", c);
  }

  function image_click(event){
    slidetimer.stop();
    if(event.pageX > $(document).width()/2){
      advance();
      next_image();
    } else {
      rewind();
      previous_image();
    }
  }

  //////////////////////////////////////////////////////////////////////////////
  function show(position){
    images.get(position, function(image){
      if(thumbnail_selected){ thumbnail_selected.fadeTo(200, 1)}
      thumbnail_selected = $(image.thumbnail);
      thumbnail_selected.fadeTo(200, 0.5);
      draw_image(image.html);
      image_position = position;
    });
  }

  //////////////////////////////////////////////////////////////////////////////
  function draw_image(html){
    viewer.load(html);
    slidetimer.update();
  }

  //////////////////////////////////////////////////////////////////////////////
  function position(animate){
    if(thumbnail_selected == null) return false;

    var left  = thumbnail_selected.offset().left,
        right = thumbnail_selected.offset().left + thumbnail_selected.width(),
        p = parseInt(dock.table().css("left")),
        w = $(window).width(),
        d;

    p = (isNaN(p)) ? 0 : p;
    if(left < -1){ d = left;}
    if(right > w){ d = right - w}
    if(d){
      if(animate){
        dock.table().stop(true).animate({left:p-d}, 200)
      } else {
        dock.table().stop(true).css({left:p-d})
      }
    }
    image.orient();
  }

  //////////////////////////////////////////////////////////////////////////////
  function resize(){
    var h = $(window).height(),
        w = $(window).width(),
        t = footer.outerHeight()+$("#dock").outerHeight()+blurb.outerHeight(),
        viewer = $("#viewer"),
        ch= viewer.find(".description").outerHeight();

    dock.table().width() > w ? dock.enable_scroll() : dock.disable_scroll();

    dock.table().css({left:0})
    frame.height(h);
    viewer.height(Math.max(300,h-(t)));
    viewer.find("img").height(h-t-ch)
    viewer.width(Math.min(900,w));
    position(false);
    image.orient();
  }



  //////////////////////////////////////////////////////////////////////////////
  function next_image(){
    if(image_position > dock.thumbnails().length-1){ image_position = 0}
    show(image_position);
  }

  function previous_image(){
    if(image_position < 0){ image_position = dock.thumbnails().length-1}
    show(image_position);
  }
  
  window.controller = {
    init:init,
    next_image:next_image,
    show:show,
    position:position,
    resize:resize,
    advance:advance
  }

  $(document).ready(init);
  $(window).resize(resize);

})();
