// Textile JS lib, based on http://philwilson.org/blog/2005/03/textile-your-textareas-with-greasemonkey
function textile(s){var r=s;qtags=[['\\*','strong'],['\\?\\?','cite'],['\\+','ins'],['~','sub'],['\\^','sup'],['@','code']];for(var i=0;i<qtags.length;i++){ttag=qtags[i][0];htag=qtags[i][1];re=new RegExp(ttag+'\\b(.+?)\\b'+ttag,'g');r=r.replace(re,'<'+htag+'>'+'$1'+'</'+htag+'>');}re=new RegExp('\\b_(.+?)_\\b','g');r=r.replace(re,'<em>$1</em>');re=new RegExp('[\s\n]-(.+?)-[\s\n]','g');r=r.replace(re,'<del>$1</del>');re=new RegExp('"\\b(.+?)\\(\\b(.+?)\\b\\)":([^\\s]+)','g');r=r.replace(re,'<a href="$3" title="$2">$1</a>');re=new RegExp('"\\b(.+?)\\b":([^\\s]+)','g');r=r.replace(re,'<a href="$2">$1</a>');re=new RegExp('!\\b(.+?)\\(\\b(.+?)\\b\\)!','g');r=r.replace(re,'<img src="$1" alt="$2">');re=new RegExp('!\\b(.+?)\\b!','g');r=r.replace(re,'<img src="$1">');re=new RegExp('(.*)\n([^#\*\n].*)','g');r=r.replace(re,'$1<br />$2');re=new RegExp('\n<br />','g');r=r.replace(re,'\n');lines=r.split('\n');nr='';for(var i=0;i<lines.length;i++){line=lines[i].replace(/\s*$/,'');changed=0;if(line.search(/^\s*bq\.\s+/)!=-1){line=line.replace(/^\s*bq\.\s+/,'\t<blockquote>')+'</blockquote>';changed=1;}if(line.search(/^\s*h[1-6]\.\s+/)!=-1){re=new RegExp('h([1-6])\.(.+)','g');line=line.replace(re,'<h$1>$2</h$1>');changed=1;}if(line.search(/^\s*\*\s+/)!=-1){line=line.replace(/^\s*\*\s+/,'\t<liu>')+'</liu>';changed=1;}if(line.search(/^\s*#\s+/)!=-1){line=line.replace(/^\s*#\s+/,'\t<lio>')+'</lio>';changed=1;}if(!changed&&(line.replace(/\s/g,'').length>0))line='<p>'+line+'</p>';lines[i]=line+'\n';}inlist=0;listtype='';for(var i=0;i<lines.length;i++){line=lines[i];if(inlist&&listtype=='ul'&&!line.match(/^\t<liu/)){line='</ul>\n'+line;inlist=0;}if(inlist&&listtype=='ol'&&!line.match(/^\t<lio/)){line='</ol>\n'+line;inlist=0;}if(!inlist&&line.match(/^\t<liu/)){line='<ul>'+line;inlist=1;listtype='ul';}if(!inlist&&line.match(/^\t<lio/)){line='<ol>'+line;inlist=1;listtype='ol';}lines[i]=line;}r=lines.join('\n');r=r.replace(/li[o|u]>/g,'li>');return r;}
// jQuery Delay plugin
jQuery.fn.delay = function(time,func){ this.each(function(){ setTimeout(func,time); }); return this; };
// jQuery color animation plugin
(function(jQuery){jQuery.each(['backgroundColor','borderBottomColor','borderLeftColor','borderRightColor','borderTopColor','color','outlineColor'],function(i,attr){jQuery.fx.step[attr]=function(fx){if(fx.state==0){fx.start=getColor(fx.elem,attr);fx.end=getRGB(fx.end);}fx.elem.style[attr]="rgb("+[Math.max(Math.min(parseInt((fx.pos*(fx.end[0]-fx.start[0]))+fx.start[0]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[1]-fx.start[1]))+fx.start[1]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[2]-fx.start[2]))+fx.start[2]),255),0)].join(",")+")";}});function getRGB(color){var result;if(color&&color.constructor==Array&&color.length==3)return color;if(result=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))return[parseInt(result[1]),parseInt(result[2]),parseInt(result[3])];if(result=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))return[parseFloat(result[1])*2.55,parseFloat(result[2])*2.55,parseFloat(result[3])*2.55];if(result=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))return[parseInt(result[1],16),parseInt(result[2],16),parseInt(result[3],16)];if(result=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))return[parseInt(result[1]+result[1],16),parseInt(result[2]+result[2],16),parseInt(result[3]+result[3],16)];return colors[jQuery.trim(color).toLowerCase()];}function getColor(elem,attr){var color;do{color=jQuery.curCSS(elem,attr);if(color!=''&&color!='transparent'||jQuery.nodeName(elem,"body"))break;attr="backgroundColor";}while(elem=elem.parentNode);return getRGB(color);};var colors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]};})(jQuery);
// jQuery cookie plugin
jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options.expires=-1;}var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;}expires='; expires='+date.toUTCString();}var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i]);if(cookie.substring(0,name.length+1)==(name+'=')){cookieValue=decodeURIComponent(cookie.substring(name.length+1));break;}}}return cookieValue;}};

var frontpageLoaded = false;
var sectionPhotoLoaded = false;
var sectionVideoLoaded = false;
var sectionTextLoaded = false;
var PLAYER_SKIN_URL = MEDIA_URL + "flash/stylish_slim.swf";

function startup() {
	$.ajaxSetup({
		timeout: 5000,
		type: 'get',
		dataType: 'jsonp',
		contentType: "application/json; charset=utf-8"
	});
	
	// Ajax load indicator {{{
	$("#ajax_loader").hide();
	$("#ajax_loader").ajaxStart(function() { $("#ajax_loader").show(); });
	$("#ajax_loader").ajaxStop(function() { $("#ajax_loader").hide(); });
	// }}}
	
	$('#tabcontent_error').ajaxError(function(event, XMLHttpRequest, ajaxOptions, thrownError) {
		showErrorMessage(thrownError);
	});
	
	window.basket = new Basket();
	basket.update();
	
	// Tab hooks
	$(".tab").click(function() {
		var tabname = this.id.toString().replace("tab_", "");
		
		showTab(tabname);
		showTabContent(tabname);
		
		$.address.value('/'+tabname+'/');
	});
	
	$('#terms_link').click(function() {
		var terms = '<div id="terms_container"><ul>';
		terms += '<li>The copenhagenmediacenter.com must always be accredited and the photographer\'s name shall    always be stated against a photo used (or in the colophon</li>';
		terms += '<li>Please note that you must have a special permit if you wish to use photos of the Little Mermaid. You can contact Eriksen Arvinger about these photos at +45 4817 7825 or erling.e@mail.dk.</li>';
		terms += '<li>The photos may only be used in connection with the promotion of Copenhagen, including promotion in all written media, Danish as well as foreign (e.g. advertisements, brochures, magazines, newspapers), in all electronic and digital media, including CD-ROM versions and on the Internet.</li>';
		terms += '<li>The photo material may only be cropped and adjusted with due regard to the photographer\'s copyright as laid down in section 3 of the Danish Copyright Act.</li>';
		terms += '<li>The photo material may not be used in an offensive way or in an offensive context. By way of example, it is considered offensive if a photo appears with products sold with a view of profit (i.a. posters, postcards, maps, games, key rings and the like).</li>';
		terms += '<li>If the photo material includes depictions of works of art or other copyright protected works, the written consent for the use of the photo material shall be obtained from the artist or other copyright holders.</li>';
		terms += '<li>The right of use for the photo material is granted on the condition that the terms and conditions outlined above are accepted.</li>';
		terms += '</ul></div>';
		flashmessage('Terms & copyright information', terms);
		clearTimeout(flashmessageTimer); // keep the popup permanently for reading
		return false;
	});
	$("#tabcontent_frontpage .section form.search").add("#tabcontent_frontpage .findmedia form.search").helptexts({
		query: 'Search terms'
	});
	$("#tabcontent_basket #basket_download_form").helptexts({
		email: 'example@example.com'
	});
	
	$("#basket_remove_selected").click(function() {
		var items = [];
		$("#tabcontent_basket .items input.select:checked").each(function() { items.push(this.value); });
		basket.removeMedia(items);
		return false;
	});
	$("#basket_download_all").click(function() {
		$("#basket_download_email_container").slideToggle(200, function() {
			$(this).find("#basket_download_email").focus();
		});
		return false;
	});
	
	$("#basket_download_form").submit(function() {
		
		if($('#terms_checkbox').is(':checked')) {
			var args = {
				action: 'downloadzip',
				email: $("#basket_download_email").val(),
				submedia: ''
			}
			
			if(!args.email) {
				flashmessage('Error', 'Please enter your e-mail');
				return false;
			}
			
			// fetch the items and selected subitems
			var media = $("#tabcontent_basket .items select").map(function() {
				var pair = $(this).val().split(",");
				return [[$(this).data('media_id'), pair[0], parseInt(pair[1])]]
			}).get();
			args.items = JSON.stringify(media);
			
			$.getJSON(MEDIASERVER_URL + 'api/basket/?callback=?', args, function(data) {
				checkForError(data);
				
				if(data.errorcode == 0) {
					flashmessage('Processing', 'Your ZIP file is being processed. You will receive an email shortly with a link to the download.<br/>Check your inbox.');
				} else {
					flashmessage('Error', 'Please add some media to your selection');
				}
			});
		} else {
			flashmessage('Error', 'You must agree to the terms and copyright information before downloading.');
		}
		return false;
	});
	$("#findmedia_search_form").submit(function() {
		$.address.value("/search/");
		$("#searchresult_search_category ul").replaceWith($("#findmedia_categories").clone());
		loadSearch({
			query: this.query.value,
			categories: $.map($("#findmedia_categories input:checked"), function(e) { return parseInt(e.value) }),
			media_type: '' // search all types
		}, {
			keep_categories: true
		});
		return false;
	});
	$("#section_photo_form").submit(function() {
		$.address.value("/search/photo/");
		loadSearch({
			query: this.query.value,
			categories: [],
			media_type: 'photo'
		}, true);
		return false;
	});
	$("#section_video_form").submit(function() {
		$.address.value("/search/video/");
		loadSearch({
			query: this.query.value,
			categories: [],
			media_type: 'video'
		}, true);
		return false;
	});
	$("#section_text_form").submit(function() {
		$.address.value("/search/text/");
		loadSearch({
			query: this.query.value,
			categories: [],
			media_type: 'text'
		}, true);
		return false;
	});
	$("#search_form").submit(function() {
		window.f = this;
		$.address.value("/search/");
		loadSearch({
			query: this.query.value,
			query_type: $("input[name=querytype]:checked", this).val(),
			categories: $.map($("#searchresult_search_category input:checked"), function(e) { return parseInt(e.value) }),
			formats: $.map($("#searchresult_search_formats input:checked"), function(e) { return parseInt(e.value) }),
			tags: $.map($(this).find(".tagsearches input:checked"), function(e) { return e.value }),
			media_type: $('#searchresult_media_type').val() // search all types
		}, false);
		return false;
	});
	$("#sectionsearch_photo_form").submit(function() {
		$.address.value("/search/photo/");
		$("#searchresult_search_category ul").replaceWith($("#sectionsearch_photo_category ul").clone());
		loadSearch({
			query: $('#sectionsearch_photo_query').val(),
			query_type: $("input[name=querytype]:checked", this).val(),
			categories: $.map($("#sectionsearch_photo_category input:checked"), function(e) { return parseInt(e.value) }),
			formats: $.map($("#sectionsearch_photo_formats input:checked"), function(e) { return parseInt(e.value) }),
			tags: $.map($(this).find(".tagsearches input:checked"), function(e) { return e.value }),
			media_type: 'photo' // search all types
		}, {
			keep_categories: true
		});
		return false;
	});
	$("#sectionsearch_video_form").submit(function() {
		$.address.value("/search/video/");
		$("#searchresult_search_category ul").replaceWith($("#sectionsearch_video_category ul").clone());
		loadSearch({
			query: $('#sectionsearch_video_query').val(),
			query_type: $("input[name=querytype]:checked", this).val(),
			categories: $.map($("#sectionsearch_video_category input:checked"), function(e) { return parseInt(e.value) }),
			formats: $.map($("#sectionsearch_video_formats input:checked"), function(e) { return parseInt(e.value) }),
			tags: $.map($(this).find(".tagsearches input:checked"), function(e) { return e.value }),
			media_type: 'video' // search all types
		}, {
			keep_categories: true
		});
		return false;
	});
	$("#sectionsearch_text_form").submit(function() {
		$.address.value("/search/text/");
		$("#searchresult_search_category ul").replaceWith($("#sectionsearch_text_category ul").clone());
		loadSearch({
			query: $('#sectionsearch_text_query').val(),
			query_type: $("input[name=querytype]:checked", this).val(),
			categories: $.map($("#sectionsearch_text_category input:checked"), function(e) { return parseInt(e.value) }),
			tags: $.map($(this).find(".tagsearches input:checked"), function(e) { return e.value }),
			media_type: 'text' // search all types
		}, {
			keep_categories: true
		});
		return false;
	});
	
	// Placeholder HTML should be hidden. Just used to ease mark-up generation.
	$(".placeholder").hide();
	
	// Load frontpage per default
	if(location.hash=='')
		loadFrontpage(); // using $.address.value causes frontpage to load twice
}

// All results are expected to be a dictionary. Anothing other means error (usually a string)
function checkForError(result) {
	if(typeof(result) != 'object') {
		showErrorMessage('Unexpected result:<br/><pre>' + result + '</pre>');
		throw 'Unexpected data format';
	}
}

function showErrorMessage(msg, url) {
	showTabContent('error');
	if(url != undefined)
		$("#error_message").html('Error from URL <b>'+settings.url+'</b><br/>' + msg + '\n<br/>\n');
	else
		$("#error_message").html(msg);
}

function roundNumber(no, places) {
	return Math.round(no * Math.pow(10, places)) / Math.pow(10, places)
}

$.address.change(function(event) {
	if(event.pathNames.length < 1)
		return;
	
	var args = [];
	for(i in event.pathNames) {
		args.push(event.pathNames[i].toLowerCase())
	}
	
	switch(args[0].toLowerCase()) {
		case 'frontpage':
			loadFrontpage();
			break;
			
		case 'photo':
			loadPhoto(args[1]);
			break;
			
		case 'video':
			loadVideo(args[1]);
			break;
			
		case 'text':
			loadText(args[1]);
			break;
		
		case 'search':
			loadSearch({ media_type: args[1] });
			break;
		
		case 'search_text':
			loadTextSearch($('#section_text_query').val());
			break;
			
		case 'basket':
			loadBasket();
			break;
			
		case 'section_photo':
			loadSectionPhoto();
			break;
			
		case 'section_video':
			loadSectionVideo();
			break;
			
		case 'section_text':
			loadSectionText();
			break;
			
		case 'html':
			loadHTML(args);
			break;
			
		case 'tag':
			loadTagSearch(args[1], '');
			break;
	}
	try {
		// Track all page changes in Google Analytics
		if(ipAddress == undefined)
			ipAddress = '0.0.0.0';
		var is_internal = (ipAddress == '84.16.169.34');
		pageTracker._setCustomVar(1, "InternalExternal", is_internal ? 'true' : 'false', 1);
		pageTracker._trackPageview('/' + event.pathNames.join('/'));
	} catch(e) {
		// ignore errors possibly created since stats not ready yet
	}
});


function showTab(tabname) {
	// if no tab is specified, we activate all tags (designers choice)
	if(tabname) {
		$("#tab_" + tabname).addClass('active');
		$(".tab:not(#tab_" + tabname+")").removeClass('active');
	} else {
		$(".tab").addClass('active');
	}
}


function showTabContent(tabname) {
	$("#tabcontent_" + tabname).show();
	$(".tabcontent:not(#tabcontent_" + tabname+")").hide();
	
	$("object, embed").each(function() {
		if(this.sendEvent)
			this.sendEvent('STOP');
	});
}


var generatedInputNo = 0;
function generateCheckboxList(putinto, items) {
	// Attempt to re-use parent id on children for niceness effect
	var baseId = '';
	if(putinto.attr('id') != '')
		baseId = putinto.attr('id') + '_item_';
	else {
		var parentWithId = putinto.parent('[id]:first');
		if(parentWithId)
			baseId = parentWithId.attr('id') + '_item_';
		else
			baseId = 'input_id_';
	}
	
	putinto.find('li').remove();
	if(items.length > 0) {
		for(var i in items) {
			var cat = items[i];
			var html = '';
			html += '<input type="checkbox" id="' + baseId + cat.id + '" value="' + cat.id + '" />';
			html += '<label class="" for="' + baseId + cat.id +'"> ' + cat.name + '</label>';
			putinto.append('<li class="item">'+html+'</li>');
		}
	} else {
		putinto.append('<li class="item empty-message">None available</li>');
	}
}

function generateTagSearchList(putinto, tagsearches) {
	// Attempt to re-use parent id on children for niceness effect
	var baseId = '';
	if(putinto.attr('id') != '')
		baseId = putinto.attr('id') + '_item_';
	else {
		var parentWithId = putinto.parent('[id]:first');
		if(parentWithId)
			baseId = parentWithId.attr('id') + '_item_';
		else
			baseId = 'input_id_';
	}
	
	putinto.find(".sub-section").remove();
	for(var i in tagsearches) {
		var search = tagsearches[i];
		var searchDiv = $(document.createElement('div'));
		searchDiv.addClass('sub-section');
		searchDiv.append('<h2>'+search.title+'</h2>')
		searchDiv.append('<div class="checkbox-attributes"><ul></ul></div>');
		
		var search_ul = searchDiv.find(".checkbox-attributes ul");
		search_ul.find('li').remove();
		var items = search.tags;
		if(items.length > 0) {
			for(var i in items) {
				var s = items[i];
				var html = '';
				html += '<input type="checkbox" id="' + baseId + s.name + '" value="' + s.name + '" />';
				html += '<label class="" for="' + baseId + s.name +'"> ' + s.name + '</label>';
				search_ul.append('<li class="item">'+html+'</li>');
			}
		} else {
			search_ul.append('<li class="item empty-message">None available</li>');
		}

		putinto.append(searchDiv);
	}
}


/* JW Flash player onReady hook {{{ */
var playerListeners = [];
function playerReady(obj) {
	for(var i=0;i<playerListeners.length;i++) {
		listener = playerListeners[i];
		if(listener.id == obj['id'])
			listener.callback(obj);
	}
};
function addPlayerListener(id, callback) {
	cb = function(obj) {
		//$("#"+this.id).parent().find(".overlay");
		//$("#"+this.id).before('<a class="flash-overlay" href="#" onclick="dummy()">&nbsp;</a>');
		callback(obj);
	}
	cb.id = id;
	playerListeners.push({ id: id, callback: cb });
}
/* }}} */

function loadFrontpage() {
	if(frontpageLoaded) {
		showTab('');
		showTabContent('frontpage');
		return;
	}
	
	$("#findmedia_thumbs .item").remove();
	
	// Set-up handlers for frontpage
	// Load frontpage content
	$.getJSON(MEDIASERVER_URL + 'api/frontpage/?callback=?', {}, function(data) {
		checkForError(data);
		
		showTab('');
		showTabContent('frontpage');
		
		frontpageLoaded = true;
		
		// Set-up photo section preview
		var photo = data.section_photo;
		if(photo) {
			$("#section_photo img").attr("src", MEDIASERVER_MEDIA_URL + photo.thumbnails.normal).attr('title', photo.title);
			$("#tabcontent_frontpage #section_photo .thumbnail").click(function() {
				$.address.value('/photo/'+photo.id);
				return false;
			});
		}
		
		// Reset video and show now video
		// Must be re-embedded to maintain settings after hiding and showing
		var video_media = data.section_video;
		var video = data.section_video_video;
		
		$("#frontpage_section_video_player").html("");
		
		addPlayerListener('frontpage_section_video_player_embed', function() {
			$("#section_video .flash-overlay")
			.show()
			.unbind()
			.mouseenter(function() {
				try{
				$("#frontpage_section_video_player_embed").get(0).sendEvent('PLAY', true);
				}catch(e){}
				return false;
			}).mouseout(function() {
				try{
				$("#frontpage_section_video_player_embed").get(0).sendEvent('PLAY', false); // actually, this is pause
				}catch(e){}
				return false;
			}).click(function() {
				try{
				$("#frontpage_section_video_player_embed").get(0).sendEvent('STOP');
				}catch(e){}
				$.address.value('/video/'+video_media.id);
				return false;
			});
		});
		
		var s1 = new SWFObject(MEDIA_URL + 'flash/player.swf', 'frontpage_section_video_player_embed',"280", "160",'9'); 
		s1.addParam('allowfullscreen','true');
		s1.addParam('allowscriptaccess','always');
		s1.addParam('wmode','transparent');
		var fv = {};
		fv.skin = PLAYER_SKIN_URL;
		fv.file = MEDIASERVER_MEDIA_URL + video.preview_file;
		fv.image = MEDIASERVER_MEDIA_URL + video_media.thumbnails.normal;
		fv.controlbar = 'none';
		s1.addParam('flashvars', dictToQuerystring(fv));
		s1.write('frontpage_section_video_player'); 
		
		// Set-up video section preview
		var text = data.section_text;
		if(text) {
			$("#section_text img").attr("src", MEDIASERVER_MEDIA_URL + text.thumbnails.normal).attr('title', text.title);
			$("#tabcontent_frontpage #section_text .thumbnail").click(function() {
				$.address.value('/text/'+text.id);
			});
		}
		$("#tabcontent_frontpage .sections .section").fadeIn(500);
		
		// Set-up findmedia area
		//$("#tabcontent_frontpage .findmedia .items").hide();
		var thumbs_div = $("#findmedia_thumbs");
		for(var i in data.findmedia) {
			var media = data.findmedia[i];
			if(media.thumbnails) {
				thumbs_div.append('<a title="'+ media.title +'" style="display:none" href="#/'+media.def_type+'/'+media.id+'" class="item '+media.def_type+'"><span></span><img src="' + MEDIASERVER_MEDIA_URL + media.thumbnails.tiny + '" alt="" /></a>');
			}
		}
		
		var sqmax = Math.sqrt(7*3);
		thumbs_div.find(".item").each(function(i) {
			var quotient = (Math.sqrt(i) / sqmax);
			$(this).fadeIn(parseInt(3000 * quotient)+1000);
		});
			
		// Set-up findmedia categories
		generateCheckboxList($("#findmedia_categories"), data.categories);
	});
}

function loadPhoto(photoId) {
	$.getJSON(MEDIASERVER_URL + 'api/media/' + photoId + '?callback=?', {}, function(data) {
		checkForError(data);
		
		$("#photo_related_items .item").remove();
		$("#photo_metadata_table tr").remove();
		$("#photo_tags").html('');
		
		showTab('section_photo');
		showTabContent('photo');
		
		var photo = data.submedia;
		var media = data.media;
		
		$("#photo_title").text(media.title);
		$("#photo_description").html(textile(media.description));
		if(media.author)
			$("#photo_author").text(media.author).parent().parent().show();
		else
			$("#photo_author").text(media.author).parent().parent().hide();
		$("#photo_image").attr("src", MEDIASERVER_MEDIA_URL + media.thumbnails.large).attr('title', media.title);
		$("#photo_available_formats").text(media.formats.length > 0 ? media.formats.join(', ').toUpperCase() : 'Only original');
		$("#photo_filesize").text(displayFilesize(photo.info.filesize));
		
		var w_inch = photo.info.width / photo.info.dpi;
		var h_inch = photo.info.height / photo.info.dpi;
		var w_cm = roundNumber(w_inch * 2.54, 2); // 2.54 is inch-to-cm ratio
		var h_cm = roundNumber(h_inch * 2.54, 2);
		$("#photo_dimensions").text(w_cm + " x " + h_cm + " cm. (" + photo.info.width + " x " + photo.info.height + " px) / "+photo.info.dpi+" DPI");
		
		for(var i in data.related_media) {
			var rm = data.related_media[i];
			$("#photo_related_items").append('<a href="#/'+media.def_type+'/'+rm.id+'" title="'+rm.title+'" class="item '+rm.def_type+'"><img src="'+(MEDIASERVER_MEDIA_URL + rm.thumbnails.tiny)+'" /></a>');
		}
		
		var n = 0;
		for(var key in data.metadata) {
			n++;
			var val = data.metadata[key];
			$("#photo_metadata_table").append('<tr><td>'+val[0]+'</td><td>'+val[1]+'</td></tr>');
		}
		
		if(n > 0)
			$("#photo_show_metadata").show();
		else
			$("#photo_show_metadata").hide();
		
		$("#photo_basket_add").unbind('click').click(function() {
			basket.addMedia(media.id);
		});
		
		$("#photo_categories").html('');
		category_names = [];
		for(var i in media.categories) {
			category_names.push('<span class="category">'+media.categories[i].name+'</span>');
		}
		$("#photo_categories").append(category_names.join(', '));

		// Show tags
		for(var i = 0; i < media.tags.length; i++) {
			var tag = media.tags[i];
			$("#photo_tags").append('<a href="#" class="tag">' + tag.name + '</a>');
			if(i != media.tags.length-1)
				$("#photo_tags").append(", ");
		}
		$("#photo_tags .tag").click(function() {
			loadTagSearch($(this).text(), 'photo');
			return false;
		});
	});
}


function loadVideo(videoId) {
	$.getJSON(MEDIASERVER_URL + 'api/media/' + videoId + '?callback=?', {}, function(data) {
		checkForError(data);
		
		showTab('section_video');
		showTabContent('video');
		
		var media = data.media;
		var video = data.submedia;
		$("#video_title").text(media.title);
		$("#video_description").html(textile(media.description));
		
		// Attributes
		var w = video.info.width;
		var h = video.info.height;
		$("#video_dimensions").text(w + " x " + h + " px");
		$("#video_duration").text(video.info.duration);
		$("#video_available_formats").text(media.formats.join(', ').toUpperCase());
		$("#video_filesize").text(displayFilesize(video.info.filesize));
		
		// Add to basket
		$("#video_basket_add").unbind('click').click(function() {
			basket.addMedia(media.id);
			return false;
		});
		
		$("#video_categories").html('');
		category_names = [];
		for(var i in media.categories) {
			category_names.push('<span class="category">'+media.categories[i].name+'</span>');
		}
		$("#video_categories").append(category_names.join(', '));

		// Attributes: Tags
		$("#video_tags").html('');
		for(var i = 0; i < media.tags.length; i++) {
			var tag = media.tags[i];
			$("#video_tags").append('<a href="#" class="tag">' + tag.name + '</a>');
			if(i != media.tags.length-1)
				$("#video_tags").append(", ");
		}
		$("#video_tags .tag").click(function() {
			loadTagSearch($(this).text(), 'video');
			return false;
		});
		
		// Related media
		$("#video_related_items .item").remove();
		for(var i in data.related_media) {
			var r_media = data.related_media[i];
			$("#video_related_items").append('<a href="#/'+r_media.def_type+'/'+r_media.id+'" title="'+r_media.title+'" class="item '+r_media.def_type+'"><span></span><img src="'+(MEDIASERVER_MEDIA_URL + r_media.thumbnails.tiny)+'" /></a>');
		}
		
		// Reset video and show now video
		// Must be re-embedded to maintain settings after hiding and showing
		$("#video_player").html("");
		var s1 = new SWFObject(MEDIA_URL + 'flash/player.swf', 'video_player_embed',"480", "360",'9'); 
		s1.addParam('allowfullscreen','true');
		s1.addParam('allowscriptaccess','always');
		s1.addParam('wmode','transparent');
		var fv = {};
		fv.skin = PLAYER_SKIN_URL;
		fv.file = MEDIASERVER_MEDIA_URL + video.preview_file;
		fv.image = MEDIASERVER_MEDIA_URL + media.thumbnails.large;
		s1.addParam('flashvars', dictToQuerystring(fv));
		s1.write('video_player');
	});
}


function loadText(textId) {
	$.getJSON(MEDIASERVER_URL + 'api/media/' + textId + '?callback=?', {}, function(data) {
		checkForError(data);
		
		showTab('section_text');
		showTabContent('text');
		
		var text = data.submedia;
		var media = data.media;
		
		$("#text_title").text(media.title);
		$("#text_description").html(textile(media.description));
		
		$("#text_filesize").text(displayFilesize(text.info.filesize));
		$("#text_categories").html('');
		category_names = [];
		for(var i in media.categories) {
			category_names.push('<span class="category">'+media.categories[i].name+'</span>');
		}
		$("#text_categories").append(category_names.join(', '));
		$("#text_available_formats").text(media.formats.length > 0 ? media.formats.join(', ').toUpperCase() : 'Only original');

		// Attributes: Tags
		$("#text_tags").html('');
		for(var i = 0; i < media.tags.length; i++) {
			var tag = media.tags[i];
			$("#text_tags").append('<a href="#" class="tag">' + tag.name + '</a>');
			if(i != media.tags.length-1)
				$("#text_tags").append(", ");
		}
		$("#text_tags .tag").click(function() {
			loadTagSearch($(this).text(), 'text');
			return false;
		});
		
		// Related media
		$("#text_related_items .item").remove();
		for(var i in data.related_media) {
			var r_media = data.related_media[i];
			$("#text_related_items").append('<a href="#/'+media.def_type+'/'+r_media.id+'" title="'+r_media.title+'" class="item '+r_media.def_type+'"><span></span><img src="'+(MEDIASERVER_MEDIA_URL + r_media.thumbnails.tiny)+'" /></a>');
		}
		
		// Add to basket
		$("#text_basket_add").data('media_id', media.id).unbind('click').click(function() {
			basket.addMedia($(this).data('media_id'));
			return false;
		});
	});
}


function apply_text_fade(item) {
	item.css('position', 'relative');
	item.append('<div style="position: absolute; width: 30px; height: 14px; bottom: 0px; right: 0px; background: transparent url(/~seph/woco/images/text-fade.png) no-repeat right bottom; z-index: 9999;"></div>');
}

function loadBasket() {
	var args = {
		action: 'get'
	};
	
	$.ajax({
		dataType: 'jsonp',
		url: MEDIASERVER_URL + 'api/basket/?callback=?',
		data: args,
		success: function(data) {
			checkForError(data);
			
			showTab('');
			showTabContent('basket');
			
			var basketItems = data.items;
			
			$("#tabcontent_basket .primary .items").html("");
			var items = $("#tabcontent_basket .primary .items");
			var placeholder = $("#tabcontent_basket .primary .placeholder");
			
			$("#tabcontent_basket .primary .items .item").remove();
			if(basketItems && basketItems.length > 0) {
				for(var i in basketItems) {
					var bi = basketItems[i];
					var item = placeholder.clone();
					
					item.removeClass("placeholder").addClass("item").show();
					item.find("img").attr('src', MEDIASERVER_MEDIA_URL + bi.thumbnails.small).attr('title', bi.title);
					item.find(".title").text(bi.title);
					item.find(".description").text(truncate(bi.description, 30));
					item.find(".select").val(bi.id);
					
					var dropdown = item.find(".format select").html('');
					dropdown.data('media_id', bi.id)
					for(var si in bi.submedia) {
						var sm = bi.submedia[si];
						dropdown.append('<option value="'+sm.subtype+','+sm.id+'">'+sm.title+' ('+displayFilesize(sm.info.filesize)+')</option>');
					}
					
					items.append(item);
					item.find("a").attr("href", "#/"+bi.def_type+"/"+bi.id);
				}
			} else {
				items.html('<b>No results.</b>');
			}
		}
	});
}

function loadSectionPhoto() {
	if(sectionPhotoLoaded) {
		showTab('section_photo');
		showTabContent('section_photo');
		return;
	}
	
	var args = {
		action: 'get'
	};
	
	$.getJSON(MEDIASERVER_URL + 'api/section/photo/?callback=?', args, function(data, textstatus) {
		checkForError(data);
		
		sectionPhotoLoaded = true;
		showTab('section_photo');
		showTabContent('section_photo');
		
		var media = data.media;
		
		var section = $("#tabcontent_section_photo");
		
		$("#section_photo_title a").text(media.title).attr('href', '#/'+media.def_type+'/'+media.id);
		$("#section_photo_description").html(textile(media.description));
		section.find(".pick a").attr('href', '#/'+media.def_type+'/'+media.id);
		$("#section_photo_image").attr('src', MEDIASERVER_MEDIA_URL + media.thumbnails.large).attr('title', media.title);
		
		// Popular tags
		section.find(".taglist ul").html("");
		for(var i = 0; i < data.popular_tags.length; i++) {
			var tag = data.popular_tags[i];
			var li_html = '<li><a href="#" onclick="loadTagSearch(\''+tag.name+'\', \'photo\'); return false">'+tag.name+'</a></li>';
			section.find(".taglist ul").append(li_html);
		}
		
		// Search categories
		var cat_ul = section.find("#sectionsearch_photo_category ul");
		generateCheckboxList(cat_ul, data.categories);
		
		// Search formats
		var fmt_ul = section.find("#sectionsearch_photo_formats ul");
		generateCheckboxList(fmt_ul, data.formats);
		
		// Tag searches
		var tagsearches_div = $("#sectionsearch_photo_tagsearches");
		generateTagSearchList(tagsearches_div, data.tagsearches);
		
		// Focus on
		section.find(".focus .items").html("")
		for(var i in data.focus_on) {
			var media = data.focus_on[i];
			var item_html = '';
			item_html += '<a href="#/'+media.def_type+'/'+media.id+'" title="'+media.title+'" class="item '+media.def_type+'"><span></span>';
			item_html += '<img src="' + MEDIASERVER_MEDIA_URL + media.thumbnails.tiny + '" alt="" />';
			item_html += '</a>';
			section.find(".focus .items").append(item_html);
		}
	});
}

function loadSectionVideo() {
	if(sectionVideoLoaded) {
		showTab('section_video');
		showTabContent('section_video');
		return;
	}
	
	var args = {
		action: 'get'
	};
	
	$.getJSON(MEDIASERVER_URL + 'api/section/video/?callback=?', args, function(data, textstatus) {
		checkForError(data);
		
		sectionVideoLoaded = true;
		
		showTab('section_video');
		showTabContent('section_video');
		
		var media = data.media;
		var video = data.video;
		var tags = data.tags;
		
		$("#section_video_title a").text(media.title).attr('href', '#/'+media.def_type+'/'+media.id);
		$("#section_video_image").attr('src', MEDIASERVER_MEDIA_URL + media.thumbnails.large).attr('title', media.title);
		
		var section = $("#tabcontent_section_video");
		
		// Popular tags
		section.find(".taglist ul").html("");
		for(var i = 0; i < data.popular_tags.length; i++) {
			var tag = data.popular_tags[i];
			var li_html = '<li><a href="#" onclick="loadTagSearch(\''+tag.name+'\', \'video\'); return false">'+tag.name+'</a></li>';
			section.find(".taglist ul").append(li_html);
		}

		// Search categories
		var cat_ul = section.find("#sectionsearch_video_category ul");
		generateCheckboxList(cat_ul, data.categories);
		
		// Search formats
		var fmt_ul = section.find("#sectionsearch_video_formats ul");
		generateCheckboxList(fmt_ul, data.formats);
		
		// Tag searches
		var tagsearches_div = $("#sectionsearch_video_tagsearches");
		generateTagSearchList(tagsearches_div, data.tagsearches);
		
		// Set-up focus on area
		$("#section_video_focus_on .items").html("");
		for(var i in data.focus_on) {
			var f_media = data.focus_on[i];
			var item_html = '';
			item_html += '<a href="#/'+f_media.def_type+'/'+f_media.id+'" title="'+f_media.title+'" class="item '+f_media.def_type+'"><span></span>';
			item_html += '<img src="' + MEDIASERVER_MEDIA_URL + f_media.thumbnails.tiny + '" alt="" />';
			item_html += '</a>';
			$("#section_video_focus_on .items").append(item_html);
		}
		
		// Reset video and show now video
		// Must be re-embedded to maintain settings after hiding and showing
		$("#section_video_player").html("");
		var s1 = new SWFObject(MEDIA_URL + 'flash/player.swf', 'section_video_player_embed', "480", "360", '9'); 
		s1.addParam('allowfullscreen','true');
		s1.addParam('allowscriptaccess','always');
		s1.addParam('wmode','transparent');
		var fv = {};
		fv.skin = PLAYER_SKIN_URL;
		fv.file = MEDIASERVER_MEDIA_URL + video.preview_file;
		fv.image = MEDIASERVER_MEDIA_URL + media.thumbnails.large;
		s1.addParam('flashvars', dictToQuerystring(fv));
		s1.write('section_video_player');
	});
}

function loadSectionText() {
	if(sectionTextLoaded) {
		showTab('section_text');
		showTabContent('section_text');
		return;
	}
	
	var args = {
		action: 'get'
	};
	
	$.getJSON(MEDIASERVER_URL + 'api/section/text/?callback=?', args, function(data, textstatus) {
		checkForError(data);
		
		sectionTextLoaded = true;
		
		showTab('section_text');
		showTabContent('section_text');
		
		var media = data.media;
		
		if(media) {
			$("#section_text_title a").text(media.title).attr('href', '#/'+media.def_type+'/'+media.id);
			$("#section_text_description").html(textile(media.description));
			$("#section_text_image").attr('src', MEDIASERVER_MEDIA_URL + media.thumbnails.large).attr('title', media.title);
			
			var section = $("#tabcontent_section_text");
			
			section.find(".pick a").attr('href', '#/'+media.def_type+'/'+media.id);
			
			// Popular tags
			section.find(".taglist ul").html("");
			for(var i = 0; i < data.popular_tags.length; i++) {
				var tag = data.popular_tags[i];
				var li_html = '<li><a href="#" onclick="loadTagSearch(\''+tag.name+'\', \'text\'); return false">'+tag.name+'</a></li>';
				section.find(".taglist ul").append(li_html);
			}
			
			// Search categories
			var cat_ul = section.find(".criteria .categories ul");
			generateCheckboxList(cat_ul, data.categories);
			
			// Search formats
			var fmt_ul = section.find("#sectionsearch_text_formats ul");
			generateCheckboxList(fmt_ul, data.formats);
			
			// Tag searches
			var tagsearches_div = $("#sectionsearch_text_tagsearches");
			generateTagSearchList(tagsearches_div, data.tagsearches);
		
			// Focus on
			section.find(".focus .items").html("")
			for(var i in data.focus_on) {
				var f_media = data.focus_on[i];
				var item_html = '';
				item_html += '<a href="#/'+f_media.def_type+'/'+f_media.id+'" title="'+f_media.title+'" class="item '+f_media.def_type+'"><span></span>';
				item_html += '<img src="' + MEDIASERVER_MEDIA_URL + f_media.thumbnails.tiny + '" alt="" />';
				item_html += '</a>';
				section.find(".focus .items").append(item_html);
			}
		}
	});
}

// Shorthand function for searching just one tag
function loadTagSearch(tag, media_type) {
	// * Use regular query search but set type to tags
	// * Regular query search will make the tagname visible in
	//   the query input, but using 'tags' array will not
	$.address.value("/search/"+media_type+"/");
	loadSearch({
		query: tag,
		query_type: 'tags',
		type: 'tags',
		tags: [],
		media_type: media_type
	}, true);
	return false;
}


function loadSearch(query, resetsearch) {
	var items = $('#tabcontent_search .search-results');
	
	// Do not call showTab() since search may be invoked from different places
	if(query != undefined && query.query != undefined) {
		items.html('<p><b>Loading results...</b></p>');	
		
		var categories = query.categories ? query.categories : [];
		var formats = query.formats ? query.formats : [];
		var tags = query.tags ? query.tags : [];
		var querytext = query.query ? query.query : '';
		var querytype = query.query_type ? query.query_type : 'text';
		var media_type = query.media_type ? query.media_type : '';
		var page = query.page ? query.page : 1;
		
		// Save media type for subsequent searches
		$("#searchresult_media_type").val(media_type);
		
		var args = {
			query: querytext,
			query_type: querytype,
			categories: categories.join(','),
			formats: formats.join(','),
			tags: tags.join(','),
			page: page
		}
		
		if(resetsearch == undefined)
			resetsearch = true;
		
		if(resetsearch) {
			$("#searchresult_search_query").val(querytext);
			$("#search_form .search-type input[value="+querytype+"]").get(0).checked = true;
		}
		
		$.getJSON(MEDIASERVER_URL + 'api/search/'+media_type+'/?callback=?', args, function(data) {
			checkForError(data);
			
			var results = data.results;
			
			if(resetsearch) {
				if(!resetsearch.keep_categories)
					generateCheckboxList($("#searchresult_search_category ul"), data.categories);
				if(!resetsearch.keep_formats)
					generateCheckboxList($("#searchresult_search_formats ul"), data.formats);
				if(!resetsearch.keep_tagsearches)
					generateTagSearchList($("#searchresult_search_tagsearches"), data.tagsearches);
			}
			
			reloadSearchResults(data, $('#tabcontent_search'), query)
			
			showTabContent('search');
		});
	} else {
		showTabContent('search');
		log('no query specified');
	}
}

function reloadSearchResults(data, node, query) {
	var results = data.results;
	var pager = data.pager;
	
	var items = $(node).find(".search-results");
	var placeholder = $(node).find(".placeholder");
	var pagerDiv = $(node).find(".search-pager");
	node.find("h1:first").text('Search results ('+pager.count+' result'+(pager.count!=1?'s':'')+')');
	
	items.html('');
	items.data('query', query);
	if(results.length > 0) {
		var pagerItems = pagerDiv.find("ul");

		pagerItems.find(".page-previous").data('page', pager.page-1);
		pagerItems.find(".page-next").data('page', pager.page+1);
		
		pagerItems.find(".page-link").remove();
		for(var i = 0; i < pager.page_range.length; i++) {
			var page = pager.page_range[i];
			var li = $(document.createElement('li'));
			li.data('page', page);
			li.append('<a href="#">'+page+'</a>');
			li.addClass('page-link');
			if(pager.page == page)
				li.addClass('active');
			pagerItems.find('.page-next').before(li.get(0));
		}
		
		pagerItems.find(".page-link a, .page-previous a, .page-next a").unbind().click(function() {
			var q = query;
			var p = $(this).parent().data('page'); // li item
			q.page = p;
			loadSearch(q, false);
			return false;
		});
		
		var n = 0;
		for(var i in results) {
			var m = results[i];
			
			n++;
			var item_id = 'searchresult_item_'+n;
			var preview_id = item_id+"_preview";
			
			var item = placeholder.clone();
			item.data('media_id', m.id);
			item.attr('id', item_id);
			item.removeClass("placeholder").addClass("item").addClass(m.def_type);
			item.show();
			item.find("img").attr('src', MEDIASERVER_MEDIA_URL + m.thumbnails.small).attr('title', m.title);
			item.find(".title").text(m.title);
			item.find(".description").text(truncate(m.description, 40));
			item.find(".preview").attr("id", preview_id);
			apply_text_fade(item.find(".description"));
			
			item.find("a").attr('href', '#/'+m.def_type+'/'+m.id);
			items.append(item);
			
			item.find(".add-to-basket")
				.data("id", m.id)
				.unbind('click')
				.click(function() { basket.addMedia($(this).data("id")); return false; });
			
			// Note: Flash must be applied after element is appended to DOM tree
			if(m.def_type == 'video') {
				/* load video ... */
				//$("#"+preview_id).html("");
				
				addPlayerListener(preview_id+'_embed', function(obj) {
					var item = $("#"+obj.id).parents('.item:first');
					var media_id = item.data('media_id');
					item.find(".flash-overlay")
					.unbind()
					.show()
					.mouseenter(function() {
						try{
						$("#"+obj.id).get(0).sendEvent('PLAY', true);
						}catch(e){}
						return false;
					}).mouseout(function() {
						try{
						$("#"+obj.id).get(0).sendEvent('PLAY', false); // actually, this is pause
						}catch(e){}
						return false;
					}).click(function() {
						try{
						$("#"+obj.id).get(0).sendEvent('STOP');
						}catch(e){}
						$.address.value('/video/'+media_id);
						return false;
					});
				});
				
				// Reset video and show now video
				// Must be re-embedded to maintain settings after hiding and showing
				//$("#"+preview_id).html("");
				var s1 = new SWFObject(MEDIA_URL + 'flash/player.swf', preview_id+'_embed', "155", "155", '9'); 
				s1.addParam('allowfullscreen','true');
				s1.addParam('allowscriptaccess','always');
				s1.addParam('wmode','transparent');
				var fv = {};
				fv.skin = PLAYER_SKIN_URL;
				fv.file = MEDIASERVER_MEDIA_URL + m.def_media.preview_file;
				fv.image = MEDIASERVER_MEDIA_URL + m.thumbnails.small;
				fv.controlbar = 'none';
				s1.addParam('flashvars', dictToQuerystring(fv));
				s1.write(preview_id);
			}
		}
		
		pagerDiv.show();
	} else {
		pagerDiv.hide();
		items.html('<p><b>No results.</b></p><p>A few tips:<ul><li>Widen your search by being less restrictive.</li><li>Include more categories or formats</li><li>Type less words in the text search area</li></ul></p>');
	}
	
	// animate them in
	/*items.find(".item").each(function(i) {
		$(this).fadeIn(250*i+250);
	});*/
}

function loadHTML(path) {
	path = path.slice(1);
	$('#tabcontent_html').load(path.join('/'), {}, function() {
		$(this).append('<br class="clear"/>');
	});
	
	showTab('');
	showTabContent('html');
}

function basketSelect(state) {
	$("#tabcontent_basket .items input[type=checkbox]").each(function() {
		this.checked = state;
	});
	
	return false;
}

// TODO: handler server errors, err 500

var flashmessageTimer = null;
function flashmessage(title, body) {
	var html = '<div><h1>'+title+'</h1>';
	html += '<p>'+body+'</p>';
	html += '<a class="close" href="javascript:closeflashmessage()">Close</a></div>';
	$("#flashmessage").html(html).fadeIn(250);
	
	flashmessageTimer = setTimeout(function() { $("#flashmessage").html(html).fadeOut(500); }, 10000);
}

function checkCheckboxList(id, state) {
	$("#"+id+" input[type=checkbox]").each(function() { this.checked = state });
}

function closeflashmessage() {
	clearTimeout(flashmessageTimer);
	$("#flashmessage").fadeOut(250);
}

function roundNumber(no, places) {
	return Math.round(no * Math.pow(10, places)) / Math.pow(10, places)
}

function displayFilesize(bytes) {
	var B = 1; //byte
	var KB = 1024 * B; //kilobyte
	var MB = 1024 * KB; //megabyte
	var GB = 1024 * MB; //gigabyte

	var result = '';
	if(bytes > GB)
		result = roundNumber(bytes / GB, 2) + ' GB'
	else
		if(bytes > MB)
			result = roundNumber(bytes / MB, 2) + ' MB';
		else
			if(bytes > KB)
				result = roundNumber(bytes / KB, 2) + ' KB';
			else
				result = bytes + ' bytes';
	return result;
}

function dictToQuerystring(dict) {
	var result = "";
	var i = 0;
	for(var key in dict) {
		i++;
		result += key+'='+dict[key]+'&';
	}
	return result;
}

// Dummy hook used for form submission
function dummy() {
	flashmessage('Error', 'The function you tried to activated seems to have failed.');
}

function truncate(str, limit) {
	if(str.length > limit) {
		return str.substring(0, limit) + '...';
	} else {
		return str;
	}
}

function log(msg) {
	if(window.console && window.console.log) {
		console.log(msg);
	} else {
		$("#console").append("<li>"+msg+"</li>");
	}
}

$(document).ready(startup);
