(function($) {
  
  var gallery = $.sammy(function() {
    this.element_selector = '#main';    
		this.use(Sammy.Storage);
		this.use(Sammy.Cache)
    this.use(Sammy.Template,'');
		this.cache_partials = true;
		
		this.log = function() {
			return null;
		}
		
    this.element_selector = '#main';    
		this.helpers({
			
			blank_out: function() {
				$('#content').hide()
        $('div.disclaimer').hide();
				this.app.image_display.children().remove();
				this.app.image_display.show()
			},
			
			load_image: function(img_elem,image) {
				var context = this;
				
				var $loading = img_elem.siblings('.loading');
				var $holder = img_elem.parent('.image_holder');
				
				if (image.loaded != true) {
					$loading.show();
				  img_elem.bind('load readystatechange',function(e) {
				    $loading.fadeOut(300)
						context.app.images[image.position].loaded = true
						
						//and now start preloading
						if (this.complete || (this.readyState == 'complete' && e.type =='readystatechange')) {	
							if (context.app.preload_active == false) {
								context.app.preload_active = true
								var to_cache = []
								for (count = 1; count <= 2; count++) {
									if (image.position-count > 0) to_cache.push(image.position-count)
									if (image.position+1 < context.app.images.length-1) to_cache.push(image.position+count)
								}
								$.each(to_cache, function(index,pos) {
									if (context.app.images[pos].loading != true) {
										context.app.images[pos].loading = true
										$img = $('<img/>')
										$img.bind('load readystatechange',function(ev) {
											if (this.complete || (this.readyState == 'complete' && ev.type =='readystatechange')) {
												context.app.images[pos].loaded = true
												context.app.images[pos].loading = false
												if (!(_.detect(context.app.images,function(img) { return img.loading == true }))) {
													context.app.preload_active = false
												}
											}
										})
										$img.attr('src',context.app.images[pos].url)
									}
								});
							}
						}
						//end of preload
						
				  })
				} 
				img_elem.attr('src', image.url);
			},
			
			recalculate_ratios: function(context,image) {
				var new_ratio = context.calculate_resize_ratios($('#image_display'),image);
				context.resize($('#image_display'),image,new_ratio);
			},
			
			calculate_resize_ratios: function(element,image) {
				var window_height = $(window).height();
				var window_width = $(window).width();
				var available_width = window_width-20; //buffer
				
				var prev_next_height = element.find('.prevnext').height();
        prev_next_height = prev_next_height + element.find('.gallery_display .disclaimer').height();
				if (prev_next_height == 0) {
					var layout_height = 190 + 90; //90 is a rough approx for prevnext until we know
				} else {					
					var layout_height = 90 + prev_next_height + 90 ; //20 for spacing
				}
				
				var available_height = window_height-layout_height;
				
				if (available_height < image.height) {
					var height_ratio = available_height / image.height;
				} else {
					var height_ratio = 1;
				}
				
				if (available_width < image.width) {
					var width_ratio = available_width / image.width;
				} else {
					var width_ratio = 1;
				}
				
				if (width_ratio == 1 && height_ratio == 1) {
					var safe = true
				} else {
					var safe = false
				}
				
				return {height: height_ratio, 
								width: width_ratio, 
								safe: safe, 
								available_width: available_width, 
								available_height: available_height}
			},
			
			
			resize: function(element,image,ratio) {
				if (ratio.width > ratio.height) {
					var working_ratio = ratio.height
				} else {
					var working_ratio = ratio.width
				}
				
				var target_width = working_ratio*image.width
				var target_height = working_ratio*image.height
				
				$space = element.find('.image_space')
				$holder = element.find(".image_holder")
				$image = element.find(".image_holder img")
				
				$image.width(target_width)
				$holder.width(target_width);
				
				$holder.height(target_height);
				$image.height(target_height)
								
				if (ratio.available_width < 1200) {
					$space.width(ratio.available_width);
				} else {
					$space.width(1200);
				}

				if (ratio.available_height < 800) {
					$space.height(ratio.available_height);
				} else {
					$space.height(800);
				}

				var center = ($space.height()-$holder.height())/2;
				$holder.css('marginTop',center);
				
				return element
			},
			
			social_links: function(id) {
				$twitter = $('#share_on_twitter')
				$facebook = $('#share_on_facebook')
				var twitter_string = $twitter.attr('href').replace(/\?image.*/,'')
				var facebook_string = $facebook.attr('href').replace(/\?image.*/,'')
				if (id != null) {
					var extra_string = "?image="+id
				} else {
					var extra_string = ''
				}
				$twitter.attr('href',twitter_string += extra_string)
				$facebook.attr('href',facebook_string += extra_string)
			},
			
			thumb_load: function() {
				NiceLoad.load($('ul.grid li'))
			}		
		})
		
		this.images = []
		this.preload_active = false
		this.thumbs_loaded = false
		
		this.bind('run', function() {
			//jack the links
			var context = this;
			
			$('.gallery li').each(function(index,li) {
				$li = $(li)
				
				$li.find('a').attr('href',"#/"+$li.attr('data-link'))
				context.app.images.push({
					link: $li.attr('data-link'),
					title: $li.attr('title'),
					url: $li.attr('data-url'), 
					caption: $li.attr('data-caption'),
					height: $li.attr('data-height'),
					width: $li.attr('data-width')  
				})
			});
			
			
			$('#main').append("<div class='open-container' id='image_display'></div>")
			this.app.image_display = $('#image_display')
			this.app.thumb_display = $('#content')
		});
		
    this.get('#/', function(context) {
			context.thumb_load()
			context.app.thumb_display.show()
      $('.disclaimer').show()
			context.app.image_display.hide()
			$(window).unbind('keyup')
			$(window).bind('keyup', function(e) {
				var code = (e.keyCode ? e.keyCode : e.which);
				if(code == 40) context.redirect('#/'+context.app.images[0].link) //down arrow
			});
			context.social_links(null)
		});
				
		this.get('#/:id', function(context) {
			context.blank_out()
			var images = context.app.images
			var image = _.detect(images, function(img){ return img.link == context.params.id });
			
			image.position = _.indexOf(images,image)
			image.total_images = images.length
			if (image.position != images.length-1) {
				image.next_link = images[image.position+1].link
			} else {
				image.next_link = images[0].link
			}
			
			if (image.position != 0) {
				image.prev_link = images[image.position-1].link
			} else {
				image.prev_link = images[images.length-1].link
			}
			
			context.partial('../javascripts/image.template', {image: image}, function(rendered) {
				var $rendered = $(rendered)
				var ratio = context.calculate_resize_ratios($rendered,image)
				
				context.resize($rendered,image,ratio);
				context.app.image_display.append($rendered);
				context.resize($('#image_display'),image,ratio);
				context.load_image($('.image_holder img'),image);
				
				$('.image_space .click_prev').click(function() { context.redirect('#/'+image.prev_link) });
				$('.image_space .click_next').click(function() { context.redirect('#/'+image.next_link) });
				
				$('body').bind('onorientationchange',function() {
					context.recalculate_ratios(context,image)
				})
				
				$(window).resize(function() { 
					context.recalculate_ratios(context,image)
				});
				
				$(window).unbind('keyup')
				$(window).bind('keyup', function(e) {
					var code = (e.keyCode ? e.keyCode : e.which);
					if(code == 37) context.redirect('#/'+image.prev_link)//left arrow
					if(code == 39) context.redirect('#/'+image.next_link) //right arrow
					if(code == 38) context.redirect('#/') //up arrow
				});
				context.social_links(context.params.id)

			});
			
		});
		
		
  });
  
  $(function() {
    gallery.run('#/');
  });
  
})(jQuery);

