/*
*/

var gDSShufle = false;

var Utils =
{
    bind : function( fn, scope ) 
	{
		if ( typeof fn !== 'function' ) {
			return function() {};
		}
		scope = scope || this;
		return function() {
			return fn.apply( scope, Array.prototype.slice.call(arguments) );
		};
	},
	bindMethods: function(o)
	{
	    for(var fn in o)
	    {
	        var f = o[fn];
	        if(typeof f == 'function')
	        {
	            o[fn] = this.bind(f, o);
	        }
	    }
	},
	extend: function()
	{
	    if(arguments.length < 2)
	        return;
	    var self = arguments[0];
	    var o;
	    for(var i=1; i<arguments.length; i++)
	    {
	        o = arguments[i];
	        for(var m in o)
	        {
	            if(typeof o[m] == 'function')
	                self[m] = this.bind(o[m], self);
	            else
	                self[m] = o[m];
	        }
	    }
	}
	
}

function FlickrDataSource()
{
	this.name = "flickr";
	this.title = "Flickr";
	this.getJSON = function(per_page, page, callback)
	{ 
		var keys = new Array("fddd7bc223fe37295faace93a4f2d8fc", "6682e529b68ecbad4ffe38eb06c2a7b2");
		var k = Math.round(Math.random());
		var api_key = keys[k];
		var url = "http://api.flickr.com/services/rest/?format=json&jsoncallback=?";
		/*
		var params = {
			method: "flickr.interestingness.getList",
			//api_key: "e85cb5a69b4ea439d4471f36f8017007",
			'api_key': api_key,
			'per_page': per_page,
			'page': page,
			extras: 'url_m,url_t'
		};
		*/
		var params = {
			method: "flickr.photos.search",
			//api_key: "e85cb5a69b4ea439d4471f36f8017007",
			'api_key': api_key,
			'license': '1,2,4,5,7',
			'sort': "interestingness-desc",
			'per_page': per_page,
			'page': page,
			extras: 'url_m,url_t'
		};
		
		for(var p in params)
			url += '&' + p + "=" + params[p]; 
		
		var dataLoaded = Utils.bind(
		    function(data)
			{
				callback(data);
			},
			this);
		jQuery.getJSON(
			url,
			dataLoaded
		);
		
	};
	
	this.getPhoto = function(data, index)
	{
		var photo = data.photos.photo[index];
		if(!photo)
			photo = data.photos.photo[0];
		
		if(!photo)
		{
			return {
				'url_m': "images/blank.gif",
				'url_t': "images/blank.gif",
				'href': "images/blank.gif",
				'title': ""
			};
		}
		
		return {
			'url_m': photo.url_m,
			'url_t': photo.url_t,
			'href': ('http://www.flickr.com/photos/'+photo.owner+'/'+photo.id+'/'),
			'title': photo.title
		};
	};
	
	this.getTotal = function(data)
	{
		return data.photos.total;
	}
}

function PicasaDataSource()
{
	this.name = "picasa";
	this.title = "Picasa";
	//http://picasaweb.google.com/data/feed/base/featured?alt=rss&kind=photo&slabel=featured&hl=en_US&max-results=10&start-index=10
	this.getJSON = function(per_page, page, callback)
	{		
		//var url = "http://picasaweb.google.com/data/feed/base/featured?alt=json&kind=photo&slabel=featured&hl=en_US";
		var url = "http://picasaweb.google.com/data/feed/base/featured?alt=json-in-script&kind=photo&slabel=featured&hl=en_US&callback=?";
		var params = {
			'max-results': per_page,
			'start-index': page * per_page + 1
		};
		
		for(var p in params)
			url += '&' + p + "=" + params[p]; 
		
		//alert(url);
		jQuery.getJSON(
			url,
			function(data)
			{
				callback(data);
			}
		);
	};
	
	this.getPhoto = function(data, index)
	{
		var feed = data.feed;
		var entries = feed.entry || [];
	
		var entry = entries[index];
		
		
		return {
			'url_m': entry.media$group.media$content[0].url,
			'url_t': entry.media$group.media$thumbnail[1].url,
			'href': entry.link[2].href,
			'title': entry.title.$t
		};
	};
	
	this.getTotal = function(data)
	{
		var feed = data.feed;
		return feed.openSearch$totalResults.$t;
	}
}

(
function()
{
	var I = window.IM = 
	{
		loaded: false,
		currentPage: 1,
		selectImage: function(src, href, title)
		{
		    $("#selected-image-loading").show();
			
			var link = $("#selected-image-link");
			link.attr("href", href);
			link.attr("title", title);
			
			link = $("#image-info-link");
			var dsName = this.dataSource ? this.dataSource.title + " - ": "";
			link.text( dsName + title);
			link.attr("href", href);
			link.attr("title", title);
			
			var image = new Image();
			image.onload = function()
			{
				var imageElem = document.getElementById("selected-image");
				imageElem.src = this.src;
				
				if(this.width < this.height)
					$(imageElem).css({"width": "", "height": "100%"});
				else
					$(imageElem).css({"width": "100%", "height": ""});
				$("#selected-image-loading").hide();
				$(imageElem).show();								
			}
			image.src = src;
			image.title = title;
			image.alt = title;
			
			
		},
		showImage: function(index)
		{
			var photo = this.dataSource.getPhoto(this.data, index);
			this.selectImage(photo.url_m, photo.href, photo.title);
			
		},
		getItemHTML: function(index)
		{
			var photo = this.dataSource.getPhoto(this.data, index);
			var url = photo.url_t;
			
			var a = '<a href="#" title="'+photo.title+'" onclick="IM.showImage('+index+')"><img src="' + url + '" border="0" width="75" height="75" alt="'+photo.title+'" /></a>';
			
			return a;
		},
		pageLoaded: function(){	},
		itemAddCallback: function(carousel, first, last, data, page)
		{
			// Unlock
			carousel.unlock();

			this.data = data;
			// Set size
			var total = this.dataSource.getTotal(data);
			this.lastTotal = total;
			
			
			var per_page = carousel.last - carousel.first + 1;

			for (var i = first; i <= last; i++) 
			{
				var pos = i - 1;
				var idx = Math.round(((pos / per_page) - Math.floor(pos / per_page)) * per_page);

				carousel.add(i, this.getItemHTML(idx));
			}
			
			if(!this.loaded)
			{
				this.loaded = true;
				this.showImage(0);
			}
			
			this.pageLoaded();
		},
		makeRequest: function (carousel, first, last, per_page, page)
		{
			// Lock carousel until request has been made
			carousel.lock();
			
			this.dataSource.getJSON(
				per_page, 
				page, 
				Utils.bind(function(data)
				{
					this.itemAddCallback(carousel, first, last, data, page);
				}, this)
			);
		},
		itemLoadCallback: function(carousel, state)
		{
			var per_page = 6;
			var currPage = (carousel.first-1) / per_page + 1;
			var prevPage = 1;			
			
			if(carousel.prevFirst)
			{    
			    prevPage = (carousel.prevFirst-1) / per_page + 1; 				
			    
			    // Remove the last visible items to keep the list small
				for (var i = carousel.prevFirst; i <= carousel.prevLast; i++) 
				{
					// jCarousel takes care not to remove visible items
					carousel.remove(i);
				}
			}
			
			if(prevPage > currPage)
			{
			    this.currentPage--;
			    if(this.currentPage < 1)
			        this.currentPage = this.lastTotal;
			}
			if(prevPage < currPage)
			{
			    this.currentPage++;
			    if(this.currentPage > this.lastTotal)
			        this.currentPage = 1;
			}
			
			//alert(carousel.first + "; " + carousel.last + "; " + this.currentPage);
			
			this.makeRequest(carousel, carousel.first, carousel.last, per_page, this.currentPage);
		},
		initialize: function(carousel, ds, page)
		{
			var dataSource;
			if(!ds || ds == "flickr")
				dataSource = new FlickrDataSource();
			else if(ds == "picasa")
				dataSource = new PicasaDataSource();
			this.dataSource = dataSource || new FlickrDataSource();
			
			this.currentPage = page || 1;
			
			if(!this.loaded)
			    Utils.bindMethods(this);
			
			this.carousel = carousel;
			//initialize carousel
			jQuery(carousel).jcarousel({
				scroll: 6,
				size: 18,
				wrap: 'circular',
				itemLoadCallback: this.itemLoadCallback
			}); 
		},
		setDS: function(ds)
		{
			var dataSource;
			if(!ds || ds == "flickr")
				dataSource = new FlickrDataSource();
			else if(ds == "picasa")
				dataSource = new PicasaDataSource();
			this.dataSource = dataSource || new FlickrDataSource();
			
			this.loadPage(1);
			
		},
		loadRandom: function()
		{
		    var total = parseInt(this.lastTotal) || 100;
			var pages = Math.min(500, Math.round(total/6));
		    var pos = Math.floor(Math.random() * pages);
			//var pos =  Math.floor((total-1)/6);
			//alert(this.lastTotal);
		    this.currentPage = pos;
		    jQuery(this.carousel).jcarousel('reset');
		     
		},
		loadPage: function(page)
		{				
			var total = this.lastTotal || 100;
			if(total > page)
				this.currentPage = page;
			else
				this.currentPage = 1;			
		    jQuery(this.carousel).jcarousel('reset');
		}
	}
}
)();
