/*
	general.js

	Created by John Hunter on 2008-09-07.
	Licence CC-BSD <http://creativecommons.org/licenses/BSD/>
	www.johnhunter.info
	
	@dependency	localstore.js (github.com/johnhunter/netcache/)
	
	
*/


/*
	Set browser forking classes on html element. Can be executed as soon as jQuery is loaded.
	@dependency jQuery 1.4
	flags are: webkit, opera, msie, mozilla, (safari flag not used), os-win, os-mac
*/
(function($, flags, app) {
	$.each($.browser, function(k, v) { 
		if (v === true && k !== 'safari') flags.push(k);
	});
	os('Win', 'os-win');
	os('Mac', 'os-mac');
	window.browserFlags = $('html').addClass(flags.join(' ')).attr('class');
	
	function os (s, f) { if (app.indexOf(s) !== -1) flags.push(f); }
	
})(jQuery, [], String(navigator && navigator.appVersion));



/*
	GA lazyload - depends on _gaq command queue defined in <head>
*/
(function() {
	var ga = document.createElement('script');
	ga.type = 'text/javascript';
	ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0];
	s.parentNode.insertBefore(ga, s);
})();


/*
	Prevent iOS scale bug on orientation change
*/
(function($) {
	
	if (navigator.userAgent.match(/iPhone/i)) {
		
		var meta = $('meta[name="viewport"]');
		
		meta.each(function () {
			this.content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
		});
		
		$('body').bind('gesturestart', function () {
			meta.attr('content', 'width=device-width, minimum-scale=0.25, maximum-scale=1.6');
		});	
	}
	
}(jQuery));


/**
 * Miscellaneous dom manipulation
 */
$(document).ready(function() {
	
	var contact = $('#contact, a.contact');
	contact.attr('href', decodeURI(contact.attr('href')).
		replace(' (at) ','@').
		replace(/ \(dot\) /g, '.'));
});



/*
	Module jsonService - abstract functionalty for loading and caching json services.
	@author	John Hunter
	created	2011-02-14
	
	@dependency	localstore.js
*/
var jsonService = (function ($) {
		
	var that = {
			lifetime: 20 * 60 * 1000,
			count: 0,
			src: ''
		},
		ls = localStore;
	
	
	that.getFeed = function () {
		var that = this,
			data = ls && ls.getItem(that.name);
		
		// we're going use a cached result if we can
		if (data) {
			that.render(data);
		}
		else {
			$.getJSON(that.src.replace('<count>', that.count), function (data) {
				ls && ls.setItem(that.name, data, that.lifetime);
				that.render(data);
			});
		}
		return that;
	};
	
	return that;
}(jQuery));



/**
 * Gets a json list of photos and displays them as thumbnails.
 * Inherits jsonService
 */
var twitterFeed = oo.create(jsonService, (function () {

	var that = {
		name: 'twitterFeed',
		selector: '#tweet',
		count: 5,
		src: 'http://twitter.com/statuses/user_timeline/johnhunter.json?count=<count>&callback=?'
	};
	
	that.render = function (data) {
		var ti,
			list = $('<ul></ul>');

		if (!data || !data.length) return;

		for (var i = 0; i < data.length; i++) {
			ti = data[i];
			list.append('<li><span>'+ makeHref(ti.text) +'</span> &raquo; <a href="http://twitter.com/'+ 
				ti.user.screen_name +'/statuses/'+ti.id+'">'+ 
				toRelative(ti.created_at) +'</a></li>');
		}
	
		$(this.selector).empty().append(list).css('min-height','');	
	};

	function makeHref (text) {
		return text.replace(/(http:\/\/)(\S*)\b/gi, '<a href="$1$2">$2</a>');
	}

	function toRelative (time, relTo) {
		var d,
			w = ' ',
			t = time.split(w),
			floor = Math.floor;

		time = Date.parse(t[1] + w + t[2] + w + t[5] + w + t[3]);
		relTo = relTo || new Date();
		d = floor((relTo.getTime() - time) / 1000);
		d += relTo.getTimezoneOffset() * 60;

		if (d < 60)         return 'less than a minute ago';
		if (d < 120)        return 'about a minute ago';
		if (d < (60*60))    return floor(d / 60) + ' minutes ago';
		if (d < (120*60))   return 'about an hour ago';
		if (d < (24*60*60)) return 'about ' + floor(d / 3600) + ' hours ago';
		if (d < (48*60*60)) return '1 day ago';
		return floor(d / 86400) + ' days ago';
	}
	
	return that;
}())).getFeed();



/**
 * Gets a json list of photos and displays them as thumbnails.
 * Inherits jsonService
 */
var photoList = oo.create(jsonService, (function () {
	
	var that = {
		name: 'photoList',
		selector: '#flickr-thumbnails',
		lifetime: 120 * 60 * 1000,
		count: 3,
		src: 'http://api.flickr.com/services/feeds/photos_public.gne?id=20287332@N00&lang=en-us&format=json&jsoncallback=?'
	};
	
	that.render = function (data) {
		var photoList = data.items,
			i,
			p,
			len,
			list;
		
		if (!photoList || !photoList.length) return;
		
		/*
			photoList[n] => { media.m, title, tags, date_taken, link }
		*/
		len = Math.min(this.count, photoList.length);
		list = $('<span></span>');

		for (i = 0; i < len; i++) {
			p = photoList[i];
			p.media.t = convertFlickrMediaSrc(p.media.m, 'square');
			list.append('<a href="'+ p.link +'"><img src="'+ p.media.t +'" alt="'+ p.title +' taken on '+ p.date_taken +'"></a>');
		}
		$(this.selector).empty().append(list);
	};
	
	function convertFlickrMediaSrc (source, size) {
		var suffixes = {
			square: '_s.jpg',thumbnail:'_t.jpg',small:'_m.jpg',medium:'.jpg',large:'_b.jpg',original:'_o.jpg'
		};
		return source.replace(/_[a-z].jpg|.jpg/, suffixes[size]);
	}
	
	return that;
}())).getFeed();



/**
 * Gets a json list of your LibraryThing books and displays them as thumbnails.
 * Requires a user key
 */
var libraryList = oo.create(jsonService, (function () {
	
	var that = {
		name: 'libraryList',
		selector: '#lt-wrapper',
		lifetime: 5 * 60 * 1000,
		count: 2,
		linkUrl: 'http://www.librarything.com/work/book/',
		src: 'http://www.librarything.com/api/json_books.php?userid=johnhunter&key=1196411901&max=<count>&callback=?'
	};
	
	that.render = function (data) {
		var books = data.books,
			i,
			b,
			container = $(this.selector),
			list = $('<span></span>');

		for (i in books) {
			b = books[i];
			list.append('<a href="'+ this.linkUrl + b.book_id +'" class="lt-item"><img src="'+ b.cover +'" alt="'+ b.title +'"></a>');
		}
		$('span', container).remove();
		container.prepend(list);
	};
	
	return that;
}())).getFeed();



