var Gallery = {};

// Information on each gallery we are showing.
// Some of this I could discover but it is easier to just tell the program.
// folder: where the iPhoto Export/web folder is. This contains the images
//     and the thumbnails. We also assume a folder in the same directory
//     but with "Big" at the end of the name where the larger images are
//     kept. The normal images are 640x480 and the larger images are 1280x960.
// title: of the gallery. This can include HTML tags, like <strong>
// numPhotoes: the number of images in the path: folder/Images. They are
//     assumedto be numbered 1.jpg, 2.jpg, etc.
// preview: the image number (starting with 1) of the thumbnail to use as
//     a preview for the gallery in the gallery index.

Gallery.galleryInfo = [
{folder:"../Photos/Portland09"
,title:"Portland Trip 2009"
,tag:"recent"
,numPhotos:26,
reduceThumbs:false,
preview:4},

{folder:"../Photos/PatJohn40th"
,title:"Pat & John's 40th<br/>Anniversary Party"
,tag:"recent"
,numPhotos:54,
reduceThumbs:false,
preview:13},

{folder:"../Photos/LAJune2009"
,title:"Visting LA<br/>June 2009"
,tag:"recent"
,numPhotos:7,
reduceThumbs:false,
preview:4},

{folder:"../Photos/SanDiego2009"
,title:"Visiting San Diego<br/>June 2009"
,tag:"recent"
,numPhotos:30,
reduceThumbs:false,
preview:18},

{folder:"../Photos/Eng09Fab"
,title:"England 2009<br/>Fab Photos"
,tag:"older"
,numPhotos:31,
reduceThumbs:false,
preview:26},

{folder:"../Photos/Eng09R5"
,title:"England 2009<br/>*****"
,tag:"older"
,numPhotos:124,
reduceThumbs:false,
preview:67},

{folder:"../Photos/Eng09R4"
,title:"England 2009<br/>****"
,tag:"older"
,numPhotos:36,
reduceThumbs:false,
preview:11},

{folder:"../Photos/Eng09R3"
,title:"England 2009<br/>***"
,tag:"older"
,numPhotos:50,
reduceThumbs:false,
preview:25},

{folder:"../Photos/Eng09R2"
,title:"England 2009<br/>**"
,tag:"older"
,numPhotos:40,
reduceThumbs:false,
preview:1},

{folder:"../Photos/Eng09BB"
,title:"England 2009<br/>B&Bs"
,tag:"older"
,numPhotos:94,
reduceThumbs:false,
preview:22},

{folder:"../Photos/PatABQ08"
,title:"Pat's NM Visit<br/>2008"
,tag:"archive"
,numPhotos:31,
reduceThumbs:false,
preview:23},

{folder:"../Photos/LAWeddingParty"
,title:"Wynette and Charlie's<br/>LA Wedding Party"
,tag:"archive"
,numPhotos:53,
reduceThumbs:false,
preview:9},

{folder:"../Photos/LAAug08"
,title:"LA Visit<br/>Aug 2008"
,tag:"archive"
,numPhotos:20,
reduceThumbs:false,
preview:9},

{folder:"../Photos/Oregon08"
,title:"Oregon<br/>2008"
,tag:"archive"
,numPhotos:42,
reduceThumbs:false,
preview:36},

{folder:"../Photos/Italy08"
,title:"Italy 2008"
,tag:"archive"
,numPhotos:127,
reduceThumbs:false,
preview:110},

{folder:"../Photos/ABQSnowJan2007"
,title:"Snow in Albuquerque<br/>Jan 2007"
,tag:"archive"
,numPhotos:14,
reduceThumbs:true,
preview:1},

{folder:"../Photos/ChicagoAugust2006"
,title:"Chicago 2006"
,tag:"archive"
,numPhotos:16,
reduceThumbs:true,
preview:1},

{folder:"../Photos/Fall2006"
,title:"Fall in Albuquerque<br/>2006"
,tag:"archive"
,numPhotos:31,
reduceThumbs:true,
preview:1},

{folder:"../Photos/LAXmas2004"
,title:"Christmas in LA<br/>2004"
,tag:"archive"
,numPhotos:27,
reduceThumbs:true,
preview:1},

{folder:"../Photos/PlitviceLakes"
,title:"Plitvice Lakes<br/>in Croatia"
,tag:"archive"
,numPhotos:38,
reduceThumbs:true,
preview:1},

{folder:"../Photos/LibbiesGraduation"
,title:"Libbie's Graduation"
,tag:"archive"
,numPhotos:58,
reduceThumbs:true,
preview:1},

{folder:"../Photos/Xmas2006"
,title:"Christmas in Hobbs<br/>2006"
,tag:"archive"
,numPhotos:94,
reduceThumbs:true,
preview:1},
];

// This is called first, after the page is loaded.
$(document).ready(function() {
	Gallery.createGalleryIndex();
});

// This is the first function called.
// It sets up the gallery index page.
Gallery.createGalleryIndex = function() {
	var galleryIndexDiv = $('#album-index');
	for(var i=0; i<Gallery.galleryInfo.length; ++i)
	{
		var info = Gallery.galleryInfo[i];
		var previewPath = info.folder+'/Thumbnails/'+info.preview+'.jpg';
		var imgHtml = '<img src="'+previewPath+'"/><br/>';
		if(info.reduceThumbs) {
			imgHtml = '<img width="120" height="90" src="'+previewPath+'"/><br/>';
		}
		var html = '<div class="gallery-box">'
		+imgHtml
		+info.title+' ('+info.numPhotos+')'
		+'</div>';
		var box = $(html)
		.data('info', info)
		.click(Gallery.boxClicked);
		var set;
		switch(info.tag) {
			case "recent": set = $('#recent-albums'); break;
			case "older": set = $('#older-albums'); break;
			default:
			case "archive": set = $('#archive-albums'); break;
		}
		set.append(box);
	}
	
	// Set up getting back to the index from a gallery
	$('#backToIndex').click(function(){
		$('#container').hide();
		$('#thumbs ul.thumbs').empty();
		$('#caption').empty();
		$('#slideshow').empty();
		$('#controls').empty();
		$('#album-index').show();
	});
	
	$('#large-image-dialog').dialog({
		autoOpen:false
		,position: ['left','top']
		,width:1350
		,dialogClass:'large-image-dialog'
		,buttons:{"Close":function(){$(this).dialog("close");}}
		,hide:'blind'
		,show:'blind'
	});

};
// Set the parameters for the Gallery plugin.
Gallery.startGallery = function() {
	// Initialize Advanced Galleriffic Gallery
	$('#gallery').galleriffic('#thumbs', {
		delay:                  2000,
		numThumbs:              15,
		preloadAhead:           15,
		enableTopPager:         true,
		enableBottomPager:      true,
		imageContainerSel:      '#slideshow',
		controlsContainerSel:   '#controls',
		captionContainerSel:    '#caption',
		loadingContainerSel:    '#loading',
		renderSSControls:       true,
		renderNavControls:      true,
		playLinkText:           'Play Slideshow',
		pauseLinkText:          'Pause Slideshow',
		prevLinkText:           '&lsaquo; Previous Photo',
		nextLinkText:           'Next Photo &rsaquo;',
		nextPageLinkText:       'Next &rsaquo;',
		prevPageLinkText:       '&lsaquo; Prev',
		enableHistory:          false,
		autoStart:              false
	});
};

// This is called when a gallery index box is clicked on.
// It hides the index and displays the gallery.
Gallery.boxClicked = function(event) {
	// Hide the gallery index.
	$('#album-index').hide();
	
	// Extract the gallery info and display that gallery.
	var info = $(this).data('info');
	Gallery.showGallery(info)
};

// this displays a single gallery.
Gallery.showGallery = function(info)
{
	// Set up all the variables we need to use.
	Gallery.info = info;
	Gallery.nextImageIndex = 1;
	Gallery.numFilenames = info.numPhotos;
	Gallery.bigPhotoPath = info.folder+'Big/Images/';
	Gallery.photoPath = info.folder+'/Images/';
	Gallery.thumbPath = info.folder+'/Thumbnails/';
	Gallery.htmlPath = info.folder+'/Pages/';
	
	// Set the title
	var title = info.title+' ('+info.numPhotos+')'
	title = title.replace(/\<br\/\>/, ' ');
	$('#gallery-title').text(title);
	
	// Show the gallery DIV.
	$('#container').show();
	
	// Start fetching the gallery images.
	Gallery.getImageTitles();
};

// Start the fetching of all the images.
// All the fetches go on at the same time and the order of
// completion is not predictable.
Gallery.getImageTitles = function() {
	Gallery.titles = [];
	Gallery.tags = [];
	
	for(var i=1; i<=Gallery.numFilenames; ++i) {
		$.get( Gallery.photoPath+i+'.jpg',
		function(ii){
			return function(data){Gallery.processImage(ii,data);};
		}(i));
		// Note we use a function call to get the current value
		// of "i" in the call stack so it can be accessed by
		// the closure created by the one statement of the called function.
		// We cannot rely of the "i" in this function because it changes
		// in the loop and the location of the "i" is stored in the
		// closure, not the current value.
	}
};

// The callback when an image is loaded.
Gallery.processImage = function(index, data) {
	var info = Gallery.decodeJPEGTitleAndTags(data);
	Gallery.titles[index] = info.title;
	Gallery.tags[index] = info.tags;
	
	// Are we done yet?
	++(Gallery.nextImageIndex);
	
	if(Gallery.nextImageIndex > Gallery.numFilenames) {
		Gallery.setupImages()
		Gallery.startGallery()
	}
};

// Extract information from the iPhoto web export.
Gallery.decodeJPEGTitleAndTags = function(s)
{
	var ret = {title:'', tags:[]};
	
	// skip the first 68 characters, start at char 69
	var index = 68;
	
	// Get the two byte length field
	var length = s.charCodeAt(index)*256 + s.charCodeAt(index+1);
	index += 2;
	// Get the title string
	var title = s.substring(index, index+length);
	ret.title = title;
	index += length;
	
	// Loop through the keywords
	while(true) {
		// Get the next three bytes
		var b0 = s.charCodeAt(index+0);
		var b1 = s.charCodeAt(index+1);
		var b2 = s.charCodeAt(index+2);
		index += 3;
		//console.log('LOOP b0='+b0+' b1='+b1+' b2='+b2);
		// Drop out unless with see the 3-byte code for the next tag
		if((b0!=034) || (b1!=002) || (b2!=031)) {
			break;
		}
		// Get the length of the tag
		var length = s.charCodeAt(index)*256 + s.charCodeAt(index+1);
		index += 2;
		// Get the tag string
		var tag = s.substring(index, index+length);
		index += length;
		ret.tags.push(tag);
	}
	return ret;
}

// Create the thumbnails images as buttons.
Gallery.setupImages = function() {
	var ulist = $('#thumbs ul.thumbs');
	ulist.empty();
	
	// Fill in the path to the images and thumbnails.

	for(var i=1; i<=Gallery.numFilenames; ++i) {
		var filename = ''+i;
		var url = 'http://wynchar.com/'
			+Gallery.photoPath.substring(3)+filename+'.jpg';
		var tags = Gallery.tags[i].join(' ');
		
		var imgHtml = '<img src="'+Gallery.thumbPath+filename+'.jpg" />';
		
		var bigImageHtml = '<div class="image-bigger-link">'
		+'<a onclick="Gallery.showBigImage('
		+'\''+Gallery.bigPhotoPath+filename+'.jpg\','
		+'\''+Gallery.titles[i]+'\','
		+'this);">Show larger image</a>'
		+'</div>';
		
		if(Gallery.info.reduceThumbs) {
			imgHtml = '<img width="120" height="90" src="'
			+Gallery.thumbPath+filename+'.jpg" />';
			bigImageHtml = '';
		}
		var lihtml = 
			'<li>'
			+'<a class="thumb" href="'+Gallery.photoPath+filename+'.jpg">'
			+imgHtml
			+'</a>'
			+'<div class="caption">'
			+'<div class="image-title">'+Gallery.titles[i]+'</div>'
			+'<div class="image-tags">'+tags+'</div>'
			+bigImageHtml
			+'<div class="image-url">'+url+'</div>'
			+'</div>'
			+'</li>';
		ulist.append($(lihtml));
	}
};

// Show a larger version of an image as a jQuery UI dialog box.
Gallery.showBigImage = function(path, title, aElement) {
	//var dialogDiv = $('<div><img src="'+path+'" alt="'+title+'"></div>');
	var dialogDiv = $('#large-image-dialog');
	$('img', dialogDiv).attr('src', path);
	dialogDiv.dialog('open');
};

// For debugging. Not relaly needed with Safari web inspector and Firebug.
function objectToString(o, levels) {
    if(o==null) return "null";
    if(!levels) levels = 0;
    if(typeof o != "object") return o.toString();
    var result = "{";
    for(var prop in o) {
        var value = o[prop];
        if(levels>0) value = objectToString(value, levels-1);
        result += prop+": "+value+"; ";
        //result += prop+": "+objectToString(o[prop])+"; ";
    }
    return result+"}";
}
function o2s(o, levels) {return objectToString(o, levels);}
