var Flickr = function() {
  var api_base_url = "http://api.flickr.com/services/rest",
      api_key = "fb136c1b3e5f776a6e0aeac462ee5a84",
      flickr_response, photos;
      
  window.jsonFlickrApi = parseResponse;
  function parseResponse (response) { Flickr.response = response; }
  
  function get (method, args) {
    var data = $.extend({}, {api_key: api_key, method: method, format: 'json'}, args);
    var url = api_base_url + "?" + $.param(data);
    $.getScript(url, function() {
      if (Flickr.response.stat === "ok") {
        Flickr.photos = Flickr.response.photoset.photo;
        $(document).trigger('flickr.photos.received');
      };
    });
  }
  
  function getPhotos () {
    return get("flickr.photosets.getPhotos", {
      photoset_id: "72157622804158172", 
      media: "photos",
      extras: "date_taken,owner_name"
    });
  }

  return {
    photos: photos,
    getPhotos: getPhotos
  };
}();

Flickr.Gallery = function() {
  var current_index = 0, collection = [], 
      photo_container, photo_badge_container,
      item, current_item, next_item,
      interval;
  
  function init () {
    $('body').append('<div id="flickr_image_hider" />').append('<div id="flickr_images" />');
    photo_container = $('#flickr_images');

    photo_container.append("<div id='flickr_badge' />");
    photo_badge_container = $("#flickr_badge");
    
    $(document).bind('flickr.photos.received', start);
    Flickr.getPhotos();
    item = Flickr.Gallery.Item;
  }
  
  function start () {
    collection = Flickr.photos;
    next();
    interval = setInterval(next, 8000);
  }
  
  function stop () {
    clearInterval(interval);
    interval = null;
  }

  function next ()      { return move("forward"); }
  function prev ()      { return move("backward"); }
  function end ()       { return current_index + 1 >= collection.length; }
  function beginning () { return current_index == 0; }
  
  function move (direction) {
    if (direction == "backward" && beginning()) { current_index = collection.length-1; }
    else if (direction == "forward" && end()) { current_index = 0; };
    
    next_item = new item(collection[current_index]);
    if (next_item) {
      transition_to(next_item);
      direction == "forward" ? current_index++ : current_index--;
    };
    
    return next_item;
  }
  
  function transition_to (next_item) {
    photo_container.queue(function() {
      next_item.ready(function() { photo_container.dequeue(); });
      next_item.insert(photo_container, photo_badge_container);    
      if (current_item) { current_item.fadeOut(); };
      next_item.fadeIn();      
      current_item = next_item;
    });
  }
  
  return {
    init: init, 
    start: start,
    stop: stop,
    next: next,
    prev: prev
  };
}();

Flickr.Gallery.Item = function(data) {
  var photo            = $("<img class='photo' />").attr({src: photo_url('large')}).css({opacity: 0}),
      flickr_photo_url = "http://flickr.com/photos/" + data.ownername + "/" + data.id,
      badge            = $("<h3><a href='" + flickr_photo_url + "' target='_blank'>" + data.title + "</a></h3>").css({opacity: 0}),
      ready            = photo.ready;
  
  function insert (photo_container, photo_badge_container) {
    photo_container.append(photo);
    photo_badge_container.append(badge);
  }
  
  function fadeOut () {
    photo.animate({opacity: 0}, 1500, function() { photo.remove(); });
    badge.animate({opacity: 0}, 1500, function() { badge.remove(); });
  };
  
  function fadeIn () {
    center();
    $(window).resize(center);
    photo.animate({opacity: 1}, 1500);
    badge.animate({opacity: 1}, 1500);
  };
  
  function center () {
    var header_height = $('#header').height(),
        win_width     = $(window).width(),
        win_height    = $(window).height() - header_height,
        photo_width   = photo.width(),
        photo_height  = photo.height(),
        
        new_height, new_width, new_top, new_left, ratio;
    
    function match_height () {
      ratio      = photo_width / photo_height;
      new_height = win_height;
      new_width  = win_height * ratio;
    }
    
    function match_width () {
      ratio      = photo_height / photo_width;
      new_width  = win_width;
      new_height = win_width * ratio;
    }
    
    match_height();
    if (new_width < win_width) { match_width(); }
    else if (new_height < win_height) { match_height(); };
    
    new_top = ((new_height - win_height) / 2) - header_height;
    new_left = (new_width - win_width) / 2;
    
    photo.height(new_height);
    photo.width(new_width);
    photo.css({ top: -new_top, left: -new_left });
  }
  
  function photo_url (size) {
    var farm   = data.farm,
        server = data.server,
        id     = data.id,
        secret = data.secret;
        
    return ["http://farm", farm, ".static.flickr.com/", server, "/", id, "_", secret, "_", size_char_for(size), ".jpg"].join("");
  };
  
  function size_char_for (size) {
    var c = 'm';
    if      (size == 'square')   { c = 's'; }
    else if (size == 'thumb')    { c = 't'; } 
    else if (size == 'small')    { c = 'm'; } 
    else if (size == 'medium')   { c = '-'; } 
    else if (size == 'large')    { c = 'b'; }
    else if (size == 'original') { c = 'o'; };
    return c;
  };

  return {
    badge: badge,
    flickr_photo_url: flickr_photo_url,
    photo: photo, 
    insert: insert,
    ready: ready,
    fadeOut: fadeOut,
    fadeIn: fadeIn
  };
};

$(document).ready(function() {
  Flickr.Gallery.init();
});