try {
	if (!window.jQuery) {
		throw 'jQuery 1.3.2 required';
	}
}
catch(e){
	alert(e)
}

var app = {};

$(document).ready(function(){
	app.modal = $(".modal");
	$(".prompt").prompt();
	$("ul.promo").each(function(){
		var promo = new Promo();
		promo.init($("li", this));
	});
	$("[rel='external']").click(function(e){
		e.preventDefault();
		window.open(this.href);
	})
});

app.forgot_pwd = function(elem){
	var link = $(elem);
	var form = link.closest("form");
	var old_html = form.closest(".module").html();
	link.hide();
	form.removeAttr('onsubmit');
	form.bind('submit', function(e){
		e.preventDefault();
		app.clear_errors(form);
		app.retrieve_pwd(this, old_html);
	});
	$("input[type=password]", form).parent().prev().andSelf().hide();

	form.parent().prev().children('h3').text('ENTER YOUR EMAIL ADDRESS');
	link.next().removeClass('btn_login').addClass('btn_send');
};


function show_years(elem){
	var years = {
		bondi: [2009, 2008],
		cottesloe: [2009],
		aarhus: [2009]
	};

	var location = $(elem).val().toLowerCase();
	var html = '';
	for (var i=0,l=years[location].length; i<l; i++) {
		html += '<option value="'+years[location][i]+'">'+years[location][i]+'</option>';
	}
	$('select#year').html(html);
}


app.retrieve_pwd = function(form, old_html){
	app.mask.load();
	$.ajax({
		type: 'get',
		dataType: 'json',
		url: '/SOAPjr',
		data: { json: '{"HEAD":{"service_type":"users","action_type":"reset_password"},"BODY":{"email_address":"'+form.elements['username'].value+'"}}' },
		success: function(json){
			if (json.HEAD.result) {
				$(form).unbind('submit').closest('.module').html(old_html);
				app.mask.finish();
				app.show_modal({title:'Forgotten Password',html:'<p>A new password has been sent to the specified email address.</p>'});
			}
			else {
				app.display_errors(json.HEAD.errors, form)
			}
		},
		error: app.ajax_fail
	});
}

app.ajax_fail = function(){
	app.mask.off();
	alert('request failed');
}
app.clear_errors = function(form) {
	$("dt.error, dd.error:not(.error_msg)", form).removeClass('error');
	$("dd.error_msg, p.error").remove();
}
app.display_errors = function(errors, form){
	if (errors.BODY) { errors = errors.BODY}
	else if (errors.HEAD) { errors = errors.HEAD}

	if (form) {
		app.clear_errors(form)
		// attach the errors to a form element
		for (var i in errors) {
			if ($("[name='"+i+"']", form).length) {
				$("[name='"+i+"']", form).parent().addClass('error').prev().addClass('error').insertBefore('<dd class="error error_msg">'+errors[i].message+'</dd>');
			}
			else { // global errors - not directly related to any input
				if ($("dl", form).length) {
					$("dl", form).eq(0).prepend('<dd class="error error_msg error_global">'+errors[i].message+'</dd>');
				}
				$(form).prepend('<p class="error error_msg error_global">'+errors[i].message+'</p>');
			}
		}
	}
	else if (errors) {
		var text = '';
		for (var i in errors) {
			text += i+': '+errors[i].message+'; code: '+errors[i].code+'\n';
		}
		alert(text);
	}
	app.mask.off();
};

app.show_modal = function(data) {
	app.mask.load();
	$("h3", app.modal).text(data.title);
	app.modal.addClass(data.class_name);
	if (data.fragment) {
		$(".bd", app.modal).load('/modals/'+data.fragment, function(){
			app.mask.finish();
			app.modal.show();
			window.scrollTo(0,0);
		});	
	}
	else {
		$(".bd", app.modal).html(data.html);
		app.mask.finish();
		app.modal.show();
		window.scrollTo(0,0);
	}
};

app.hide_modal = function(data) {
	app.modal.hide().attr('class','modal');
	app.mask.off();
	$("h3", app.modal).text('');
	$(".bd", app.modal).text('');
};


app.chooseFile = function(form) {
	var gal = parseInt($("input[name='gallery']:checked", form).val(), 10);
	var abn = parseInt($("input[name='abn']:checked", form).val(), 10) * 2;
	var gst = parseInt($("input[name='gst']:checked", form).val(), 10) * 4;
	var url;
	switch(gal+abn+gst) {
		case 0: url = '/files/form1.pdf'; break; // all answers no
		case 1: url = '/files/form1.pdf'; break; // gallery repr. yes
		case 2: url = '/files/form2.pdf'; break; // abn yes
		case 3: url = '/files/form3.pdf'; break; // gallery repr. yes and abn yes
		case 4: url = '/files/form1.pdf'; break; // gst yes
		case 5: url = '/files/form1.pdf'; break; // gallery repr. yes and gst yes
		case 6: url = '/files/form4.pdf'; break; // abn yes and gst yes
		case 7: url = '/files/form5.pdf'; break; // all answers yes
	}
	window.open(url);
}

function load_panel(el){
	if (!el || app.locked) {
		return false;
	} 
	app.locked = true;
	var href = $(el).attr('href');
	if (app.panel_open) {
		// slide up open panel
		close_panel(function(){ app.mask.load(); get_panel(href); });
	}
	else {
		app.mask.load();
		get_panel(href);
	}
}

function get_panel(href){
//	$("head").append('<script type="text/javascript" src="https://dev.sculpturebythesea.com/js/login.js"></script>');
	$.ajax({
		type: 'get',
		dataType: 'html',
		url: href,
		cache: false,
		success: function(html){
			if (app.cache_panels) {
				app.panel_html[href] = html;
			}
			open_panel(html);
			app.mask.off();
		},
		error: app.ajax_fail
	});
}

function open_panel(html) {
	// inject into DOM and slideDown
	app.panel = $(html).prependTo('body');
	if (!app.grey_mask) {
		app.grey_mask = new Mask({'bg_color': '#000', opacity: 0.6, zIndex: 20});
	}
	app.grey_mask.on();
	app.panel.slideDown();
	app.panel_open = true;
}

function close_panel(callback) {
	// inject into DOM and slideDown
	if (app.panel) {
		app.panel.slideUp(function(){
			$(this).remove();
			app.panel_open = false;
			if (callback && typeof(callback) == 'function') {
				callback();
			}
			app.grey_mask.off();
			app.locked = false;
		});
	}
}


/*
 * login 
 */

app.login = function(form){ 
	app.mask.load();
  var host = window.location.hostname; 
	$.getScript('https://'+host+'/SOAPjr?json={"HEAD":{"service_type":"users","action_type":"login"},"BODY":{"email_address":"'+form.elements['username'].value+'","password":"'+form.elements['password'].value+'"}}&callback=login_callback');
	app.clear_errors(form); 
	app.login_form = form;
}

function login_callback(json){
	if (json.HEAD.result) {
		close_panel();
		window.location.reload();
	}
	else {
		app.display_errors(json.HEAD.errors, app.login_form);
	}
	app.mask.off();
	app.login_form = null;
}


app.logout = function(){ 
	app.mask.load();
  var host = window.location.hostname; 
	$.getScript('https://'+host+'/SOAPjr?json={"HEAD":{"service_type":"users","action_type":"logout"},"BODY":{}}&callback=logout_callback');
}

function logout_callback(json){
	if (json.HEAD.result) {
		window.location.reload();
	}
	else {
		app.display_errors(json.HEAD.errors, app.login_form);
		app.mask.off();
	}
}


/*
 * subscribe / unsubscribe
 */

app.subscribe = function(form){ 
	app.mask.load();
	var set = {
		type: 'post',
		dataType: 'json',
		url: '/SOAPjr',
		data: 'json={"HEAD":{"service_type":"users","action_type":"subscribe"},"BODY":{"email_address":"'+form.elements['email_address'].value+'","first_name":"'+form.elements['first_name'].value+'","last_name":"'+form.elements['last_name'].value+'","mobile":"'+form.elements['mobile'].value+'"}}',
		success: function(json){
			if (json.HEAD.result) {
				$(form).closest(".bd").html("You have been successfully subcribed to our e-newsletter.");
			}
			else {
				app.display_errors(json.HEAD.errors, form);
			}
			app.mask.off();
		},
		error: app.ajax_fail
	};
	app.clear_errors(form);
	$.ajax(set);
	return false;
}


/*
 *  * media_access 
 *   */

app.media_access = function(form){
  app.mask.load();
  var host = window.location.hostname;
  var fe = form.elements;
  if (fe['password'].value !== fe['password2'].value) {
    alert("Oops...both passwords don't match");
  } else if (!fe['first_name'].value || !fe['last_name'].value || !fe['phone'].value || !fe['email_address'].value || !fe['organisation'].value || !fe['job_title'].value || !fe['password'].value || !fe['password2'].value) {
    app.mask.off();
    alert("Please complete all fields");
  } else {
    $.getScript('https://'+host+'/SOAPjr?json={"HEAD":{"service_type":"users","action_type":"add"},"BODY":{"roles":[200],"first_name":"'+fe['first_name'].value+'","last_name":"'+fe["last_name"].value+'","phone":"'+fe['phone'].value+'","email_address":"'+fe['email_address'].value+'","organisation":"'+fe['organisation'].value+'","job_title":"'+fe['job_title'].value+'","password":"'+fe['password'].value+'","password2":"'+fe['password2'].value+'"}}&callback=media_access_callback');
    app.clear_errors(form);
    app.media_access_form = form;
  }
}

function media_access_callback(json){
  if (json.HEAD.result) {
    close_panel();
    window.location.reload();
  }      
  else {  
    app.display_errors(json.HEAD.errors, app.media_access_form);
  }     
  app.mask.off();
  app.media_access_form = null;
}     


/*
 * send message
 */

app.send_message = function(form){ 
	app.mask.load();
	var set = {
		type: 'post',
		dataType: 'json',
		url: '/SOAPjr',
		data: 'json={"HEAD":{"service_type":"users","action_type":"contact"},"BODY":{"email_address":"'+form.elements['email_address'].value+'","first_name":"'+form.elements['first_name'].value+'","last_name":"'+form.elements['last_name'].value+'","comment":"'+form.elements['comment'].value+'"}}',
		success: function(json){
			if (json.HEAD.result) {
				$(form).closest(".bd").html("Your message has been sent.");
			}
			else {
				app.display_errors(json.HEAD.errors, form);
			}
			app.mask.off();
		},
		error: app.ajax_fail
	};
	app.clear_errors(form);
	$.ajax(set);
	return false;
}


/* semi transparent overlay constructor */
function Mask(opts){
	var self = this;
	this.opts = $.extend({}, Mask.defaults, opts)
	$(document).ready(function(){
		self.mask = $('<div style="z-index:'+self.opts.zIndex+';display:none;width:100%;height:100%;background-color:'+self.opts.bg_color+';position:fixed;top:0;left:0;"></div>').appendTo("body").css({opacity:self.opts.opacity});
	});
}
Mask.prototype = {
	on: function(){
		this.mask.show();
		return this;
	},
	off: function(){
		this.finish();
		this.mask.hide();
		return this;
	},
	load: function(){
		this.mask.show().addClass(this.opts.loading).css({'z-index':'999'});
		return this;
	},
	finish: function(hide){
		this.mask.removeClass(this.opts.loading).css({'z-index':this.opts.zIndex});
		return this;
	}
};
Mask.defaults = {
	bg_color: '#000',
	opacity: '0.6',
	zIndex: '150',
	loading: 'loading'
};

app.mask = new Mask();

/* auto-rotate promo slots constructor */
function Promo(settings){
	this.settings = $.extend({}, Promo.defaults, settings);
}
Promo.prototype = {
	init: function(items){ 
		if (items.length) {
			this.items = items.hide().removeClass('hidden');
			items.eq(0).show();
			this.visible = 0;
			this.go();
		}
	},
	swap: function(){
		this.items.eq(this.visible).hide();
		if (this.visible < this.items.length-1) {
			this.visible++;
		}
		else {
			this.visible = 0;
		}
		this.items.eq(this.visible).show();
	},
	go: function(){
		var self = this;
		this.interval = setInterval(function(){self.swap()}, this.settings.speed);
	},
	stop: function(){
		clearInterval(this.interval)
	}
};
Promo.defaults = {
	speed: 7000	
}


/* auto-rotate promo slots constructor */
function Rotator(settings){
	this.settings = $.extend({}, Rotator.defaults, settings);
}
Rotator.prototype = {
	init: function(items){ 
		if (items.length) {
			this.items = items.hide().removeClass('hidden');
			items.eq(0).show();
			this.visible = 0;
			this.go();
		}
	},
	swap: function(){
		var self = this;
		this.items.eq(this.visible).fadeOut(800, function(){
		if (self.visible < self.items.length-1) {
			self.visible++;
		}
		else {
			self.visible = 0;
		}
		self.items.eq(self.visible).fadeIn(800);
		});
	},
	go: function(){
		var self = this;
		this.interval = setInterval(function(){self.swap()}, this.settings.interval);
	},
	stop: function(){
		clearInterval(this.interval)
	}
};
Rotator.defaults = {
	interval: 60000	
}


/* image gallery constructor */
function Gallery(settings){
	this.settings = $.extend({}, Gallery.defaults, settings);
}
Gallery.prototype = {
	setTemplate: function(template){
		this.settings.template = template;
		return this;
	},

	setYear: function(year){
		this.settings.year = year;
		this.reset_slideshow = true;
		return this;
	},

	resetYear: function(){
		this.settings.year = '2009';
		this.reset_slideshow = true;
		return this;
	},

	setLocation: function(location){
		this.settings.location = location;
		this.reset_slideshow = true;
		return this;
	},

	resetLocation: function(){
		this.settings.location = 'Bondi';
		this.reset_slideshow = true;
		return this;
	},

	setQuery: function(query){
		this.settings.query = query;
		$('.clear_filter').removeClass('hidden');
		this.reset_slideshow = true;
		return this;
	},

	resetQuery: function(){
		this.settings.query = '';
		$('.clear_filter').addClass('hidden');
		this.reset_slideshow = true;
		return this;
	},

	setPage: function(page){
		this.settings.page = page;
		return this;
	},

	getPage: function(){
		return this.settings.page;
	},

	resetPage: function(){
		this.settings.page = 1;
		return this;
	},

	setPageNext: function(){
		this.settings.page++;
		return this;
	},

	setPagePrev: function(){
		this.settings.page--;
		return this;
	},

	setPageSize: function(pageSize){
		this.settings.pageSize = pageSize;
		return this;
	},

	setPageSize: function(pageSize){
		this.settings.pageSize = pageSize;
		return this;
	},

	getPageSize: function(){
		return this.settings.pageSize;
	},

	resetPageSize: function(){
		this.settings.pageSize = 15;
		return this;
	},

	setForSale: function(forSale){
		this.settings.forSale = forSale;
		this.reset_slideshow = true;
		return this;
	},

	resetForSale: function(){
		this.settings.forSale = false;
		this.reset_slideshow = true;
		return this;
	},

	setOutside: function(){
		this.settings.where = 'outside';
		this.reset_slideshow = true;
		return this;
	},

	setInside: function(){
		this.settings.where = 'inside';
		this.reset_slideshow = true;
		return this;
	},

	update: function(){
		$("#gallery_query").text(this.settings.query || 'available images');
		$("#gallery_location").text(this.settings.location.toLowerCase());
		$("#gallery_year").text(this.settings.year);
	},

	show: function(){
		var self = this;
		app.mask.load();
		$.ajax({
			type: 'get',
			url: '/SOAPjr',
			data: 'json={"HEAD":{"service_type":"image_gallery","action_type":"search","output_type":"posh","page_size":'+this.settings.pageSize+',"page":'+this.settings.page+'},"BODY":{"query":"'+this.settings.query+'","gallery":"'+this.settings.where+'","location":"'+this.settings.location+'","year":"'+this.settings.year+'","for_sale":'+this.settings.forSale+',"template":"'+this.settings.template+'"}}',
			dataType: 'json',
			success: function(json){
				if (json.HEAD.result) {
					$("#gallery").html(json.BODY.content);
					self.update();
 					app.slideshow.addItemsHTML($("#gallery .thumbnail"));
					if (self.reset_slideshow) {
						app.slideshow.clear_items();
						self.reset_slideshow = false;
						app.slideshow.set_items($("#gallery .thumbnail"));
					}
				}
				app.mask.off();
			},
			error: app.ajax_fail
		});
		return this;
	},

	resetAll: function(){
		return this.resetForSale().resetPage().resetPageSize().resetQuery().resetLocation().resetYear();
	}

};
Gallery.defaults = {
	year: '2009',
	location: 'Bondi',
	query: '',
	page: 1,
	pageSize : 10,
	where: 'outside',
	inside : false,
	template: 'simple_image_gallery',
	forSale: false
}

app.gallery = new Gallery();


/* gallery slideshow constructor */
function Slideshow(io){
	this.panel = $(".gallery_overlay");
	this.name = io.name;
	this.items = {};
	this.rawItems = io.items;
	this.service_type = io.service_type || 'image_gallery';
	this.total = null;

	this.start_index = app.gallery.getPageSize() * (app.gallery.getPage()-1);
	this.max = this.start_index + io.items.length;
	for (var i=0, l=io.items.length; i<l; i++){
		var elem = io.items.eq(i),
			pc_url = elem.attr('href'),
			sculpture = $(".sculpture", elem).text(),
			photographer = $(".photographer", elem).text(),
			artist = $(".artist", elem).text(),
			year = $(".year", elem).text(),
			taken = $(".taken", elem).text(),
			location = $(".location", elem).text(),
			url = $(".url", elem).text(),
			pc_ss_thumb_url = $(".miniature", elem).text(),
			image_id = elem.attr('id').replace('image_',''),
			index = i+this.start_index,
			dimensions= $(".dimensions", elem).text();

		this.items[image_id] = {
			pc_url: pc_url,
			sculpture: sculpture,
			photographer: photographer,
			artist: artist,
			year: year,
			location: location,
			taken: taken,
			url: url,
			dimensions: dimensions,
			pc_ss_thumb_url: pc_ss_thumb_url,
			image_id: image_id,
			index: index
		};
	}
	this.settings = $.extend({}, Slideshow.defaults, io.settings);

	this.preload();
}
Slideshow.prototype = {

	inited: false,
	running: false,

	init: function(){
		$(".container").addClass("slideshow");

		this.scroller = $(".scroller", this.panel);
		this.stop_checking_images = false;
		this.clear_scroller();
		this.buildScroller(); 
		this.inited = true;
		return this;
	},

	clear_items: function(){
		this.items = {};
	},

	set_items: function(items){
		for (var i=0, l=items.length; i<l; i++){
		var elem = items.eq(i),
			pc_url = elem.attr('href'),
			sculpture = $(".sculpture", elem).text(),
			photographer = $(".photographer", elem).text(),
			artist = $(".artist", elem).text(),
			year = $(".year", elem).text(),
			taken = $(".taken", elem).text(),
			location = $(".location", elem).text(),
			url = $(".url", elem).text(),
			pc_ss_thumb_url = $(".miniature", elem).text(),
			image_id = elem.attr('id').replace('image_',''),
			index = i+this.start_index,
			dimensions= $(".dimensions", elem).text();

		this.items[image_id] = {
			pc_url: pc_url,
			sculpture: sculpture,
			photographer: photographer,
			artist: artist,
			year: year,
			location: location,
			taken: taken,
			url: url,
			pc_ss_thumb_url: pc_ss_thumb_url,
			image_id: image_id,
			dimensions: dimensions,
			index: index
		};
		}

	},

	close: function(){
		$(".container").removeClass("slideshow");
		this.stop();
		if (this.ajaxcall) {
			this.ajaxcall.abort();
		}
		app.scrollable.stop_checking_images = true;
		this.clear_scroller();
		this.inited = false;
		return this;
	},

	preload: function(){
		this.rawItems.each(function(){
			var i = new Image();
			i.src = this.href; 
		});
		return this;
	},

	show: function(image_id, prev) {
		app.cur_slideshow = this;
		if (!this.inited) { this.init(); }
		if (!image_id) {
			image_id = $("li", this.scroller).eq(0).attr('id').replace('thumb_','');
		}
		this.current = image_id; 
		img_object = this.items[image_id];
		this.selectThumb(image_id, prev);
		$("#current_photo", this.overlay).attr({'src':''});
		$("#current_photo", this.overlay).attr({'src': img_object.pc_url, 'alt': img_object.sculpture, 'title': img_object.sculpture});
		$("#current_photo", this.overlay).unbind('click').css({cursor: 'default'});
		if (img_object.url) {
			$("#current_photo", this.overlay).css({cursor:'pointer'}).bind('click', function(){
				window.location.href = img_object.url;
			})
		}
		$("#current_description", this.overlay).html('<p>'+(img_object.artist ? img_object.artist+'.' : '')+' <em>'+img_object.sculpture+(this.settings.sales && img_object.dimensions? ' '+img_object.dimensions : '')+'. Sculpture by the Sea</em>'+(img_object.location || img_object.year ? ', ' :'')+(img_object.location || '' )+' '+(img_object.year || '')+(img_object.photographer ? '. Photo '+img_object.photographer : '')+(img_object.taken ? '. Taken '+img_object.taken : '')+(this.settings.sales? ' <a href="mailto:katherine@sculpturebythesea.com" class="clr_yellow">&gt; Enquire about this sculpture</a>' : '')+'</p>');
		return this;
	},

	toggle: function(){
		if (this.running){ 
			this.stop();
		}
		else {
			this.start();
		}
		return this;
	},

	start: function(){
		var self = this;
		this.running = true;
		this.interval = setInterval(function(){self.next(1)}, this.settings.interval);
		$(".toggle", this.overlay).text('pause slideshow').removeClass('play').addClass('pause');
		return this;
	},

	stop: function(){
		this.running = false;
		clearInterval(this.interval);
		$(".toggle", this.overlay).text('play slideshow').addClass('play').removeClass('pause');
		return this;
	},

	next: function(auto){ 
		var next = $("li#thumb_"+this.current, this.scroller).next(), jump = 0;
		var allNext = next.nextAll()
		var allNextHidden = allNext.filter(":obscured");
		if (next.length) {
			this.current = parseInt(next.attr('id').replace('thumb_',''), 10);
			if (allNext.length != allNextHidden.length) {
				jump = 1;
			}
		}
		else {
			this.current = parseInt($("li", this.scroller).eq(0).attr('id').replace('thumb_',''), 10);
			jump = 2;
		}
		this.show(this.current, jump);
		if (!auto && this.running) {
			this.stop();
		}
		return this;		
	},

	prev: function(auto){
		var prev = $("li#thumb_"+this.current, this.scroller).prev(), jump = 0;
		if (prev.length) {
			this.current = parseInt(prev.attr('id').replace('thumb_',''), 10);
			jump = 1;
		}
		else {
			this.current = parseInt($("li:last", this.scroller).attr('id').replace('thumb_',''), 10);
			jump = 3;
		}
		this.show(this.current, jump);
		if (!auto && this.running) {
			this.stop();
		}
		return this;
	},

	buildScroller: function(){
		var self = this;
		var html = '<a href="javascript:void(0)" class="prev" onclick="app.scrollable.prev()"></a><a href="javascript:void(0)" onclick="app.scrollable.next()" class="next"></a><div class="scroll_wrap"><ul class="scroller_list">', cl = '';
		for (var i in this.items) { 
			cl = (this.current == i) ? ' class="active"' : ''; 
			html += '<li'+ cl +' id="thumb_'+this.items[i].image_id+'"><a href="javascript:void(0)" onclick="app.cur_slideshow.show('+this.items[i].image_id+')"><img src="'+this.items[i].pc_ss_thumb_url+'" /></a></li>';
		}
		html += '</ul></div>';
		this.scroller.html(html); 
		app.scrollable = new Scrollable({
			root: this.scroller,
			items: "li",
			service_type: this.service_type,
			template: 'image_gallery1',
			pass_data: self,
			where: self.settings.where,
			year: self.settings.year,
			location: self.settings.location,
			query: self.settings.query,
			itemsRoot: $("ul", this.scroller)
		});
		app.scrollable.page = app.gallery.getPage();
	},

	clear_scroller: function(){
		this.scroller.html(''); 
	},

	selectThumb: function(id, prev){
		$("li.active", this.scroller).removeClass('active');
		var sel = $("li#thumb_"+id, this.scroller).addClass('active');
		if (sel.is(":obscured") && app.scrollable) {
			if (prev === 1) { 
				app.scrollable.prev();
			}
			else if (prev === 2) {
				app.scrollable.prev(1);
			}
			else if (prev === 3) {
				app.scrollable.next(1);
			}
			else {
				app.scrollable.next();
			}
		}
		return this;
	},
	
	get_total: function(){	
		var self = this;
		this.ajaxcall = $.ajax({
			type: 'get',
			url: '/SOAPjr',
			data: 'json={"HEAD":{"service_type":this.service_type,"action_type":"search","output_type":"json","page_size":10,"page": 1},"BODY":{"query":"'+app.gallery.settings.query+'","location":"'+app.gallery.settings.location+'","year":"'+app.gallery.settings.year+'","for_sale":'+app.gallery.settings.forSale+'}}',
			dataType: 'json',
			success: function(json){
				if (json.HEAD.result) {
					self.total = json.BODY.total_hits;
					//self.fetch_all();
				}
			},
			error: app.ajax_fail
		});
		return this;
	},
	
	addItemsHTML: function(items){ 
		for (var i=0, l=items.length; i<l; i++){ 
			var elem = items.eq(i),
				pc_url = elem.attr('href'),
				sculpture = $(".sculpture", elem).text(),
				photographer = $(".photographer", elem).text(),
				artist = $(".artist", elem).text(),
				year = $(".year", elem).text(),
				location = $(".location", elem).text(),
				pc_ss_thumb_url = $(".miniature", elem).text(),
				taken = $(".taken", elem).text(),
				image_id = elem.attr('id').replace('image_',''),
				url = $(".url", elem).text(),
				dimensions = $(".dimensions", elem).text(),
				index = i+this.start_index;

			this.items[image_id] = {
				pc_url: pc_url,
				sculpture: sculpture,
				photographer: photographer,
				artist: artist,
				year: year,
				taken: taken,
				location: location,
				dimensions: dimensions,
				url : url ,
				pc_ss_thumb_url: pc_ss_thumb_url,
				image_id: image_id,
				index: index
			};
		}
		return this;
	},

	addItems: function(json){
		var items = this.translate(json);
		$.extend(this.items, items);
	},

	translate: function(json){
		var output = {};
		for (var i=0,l=json.length;i<l;i++) {
			var id = json[i].image_id || json[i].photo_id
			output[id] = {
				pc_url: json[i].pc_url || json[i].image_url,
				url: json[i].url,
				photographer: json[i].photographer,
				sculpture: json[i].sculpture || json[i].title,
				year: json[i].year,
				taken: json[i].taken,
				artist: json[i].artist,
				location: json[i].location,
				dimensions: json[i].dimensions,
				pc_ss_thumb_url: json[i].pc_ss_thumb_url || json[i].thumb_sm_url,
				photographer: json[i].photographer || json[i].realname,
				image_id: id
			}
		}
		return output;
	},

	fetch_all: function(){ // fetch and cache all data 
		var self = this;
		this.ajaxcall = $.ajax({
			type: 'get',
			url: '/SOAPjr',
			data: 'json={"HEAD":{"service_type":this.service_type,"action_type":"search","output_type":"json","page_size":'+(this.total+1)+',"page": 1},"BODY":{"query":"'+app.gallery.settings.query+'","location":"'+app.gallery.settings.location+'","year":"'+app.gallery.settings.year+'","for_sale":'+app.gallery.settings.forSale+'}}',
			dataType: 'json',
			success: function(json){
				if (json.HEAD.result) {
					self.items = self.translate(json.BODY.results);
					self.buildScroller();
				}
			},
			error: app.ajax_fail
		});
		return this;
	}

};
Slideshow.defaults = {
	interval: 6000,
	where: 'outside',
	year: '2009',
	location: 'bondi'
};

/* pagination */
function Pager(settings){
	this.settings = $.extend({}, Pager.defaults, settings);
}
Pager.prototype = {
	
	setQuery: function(query){
		this.settings.query = query;
		return this;
	},

	setPage: function(page){
		this.settings.page = page;
		return this;
	},

	getPage: function(){
		return this.settings.page;
	},

	resetPage: function(){
		this.settings.page = 1;
		return this;
	},

	setPageNext: function(){
		this.settings.page++;
		return this;
	},

	setPagePrev: function(){
		this.settings.page--; 
		return this;
	},

	setPageSize: function(pageSize){
		this.settings.pageSize = pageSize;
		return this;
	},

	getPageSize: function(){
		return this.settings.pageSize;
	},

	resetPageSize: function(){
		this.settings.pageSize = 15;
		return this;
	},

	show: function(){
		var self = this;
		app.mask.load();
		this.ajaxcall = $.ajax({
			type: 'get',
			url: '/SOAPjr',
			data: 'json={"HEAD":{"service_type":"page_search","action_type":"search","output_type":"posh","page_size":'+this.settings.pageSize+',"page":'+this.settings.page+'},"BODY":{"query":"'+this.settings.query+'","template":"search_results"}}',
			dataType: 'json',
			success: function(json){
				if (json.HEAD.result) {
					$("#search_results").html(json.BODY.content);
				}
				app.mask.off();
			},
			error: app.ajax_fail
		});
		return this;
	}

};

Pager.defaults = {
	page: 1,
	pageSize: 10
}
app.pager = new Pager();

function Scrollable(settings){ 
	this.settings = $.extend({}, Scrollable.defaults, settings);
	this.locked = false;
	this.root = settings.root;
	//this.items = $(settings.items, settings.itemsRoot);
	this.itemsRoot = settings.itemsRoot;
	this.scrollWidth = settings.root.width();
	this.loadedImages = {};

	this.service_type = settings.service_type;
	this.template = settings.template;

	this.pageSize = 10;
	this.page = 1;

	this.init();
		
	this.removed = [];
}
Scrollable.defaults = {
	speed: 300,
	MAX: 500,
	where: 'outside',
	query: '',
	location: 'bondi',
	year: '2009'
};
Scrollable.prototype = {
	
	appendLoadedItems: function(json){
		var self = this;
		var newItems = $(json.BODY.content).appendTo(self.itemsRoot);
		//self.items = self.itemsRoot.children();
		self.fixWidth(newItems); 
		self.checkTotal();
		self.checkImages();
		if (self.settings.pass_data) { 
			self.settings.pass_data.addItems(json.BODY.data.results);
		}
	},
	
	reportLoadedImg: function(json){
		this.allImgLoaded--;
		if (this.allImgLoaded === 0) {
			this.appendLoadedItems(json);			
		}
		return this;
	},

	reportErrorImg: function(){
		this.allImgLoaded--;
		if (this.allImgLoaded === 0) {
			this.appendLoadedItems(json);			
		}
		return this;
	},
	
	preloadImages: function(json){
		var items = json.BODY.data.results, self = this;
		this.allImgLoaded = items.length;
		for (var i=0, l=items.length; i<l; i++) {
			var sm = new Image(); 
			sm.onload = function(){ self.reportLoadedImg(json); };
			sm.onerror = function(){ self.reportErrorImg(json); }; 
			sm.src = items[i].pc_ss_thumb_url || items[i].thumb_sm_url;
			
			var med = new Image();
			med.src = items[i].pc_url || items[i].image_url;
		}
	},

	init: function(){
		var self = this;
		this._fetch_total();
		// check the ul width and adjust
		var w = 0;
		this.fixWidth();

		return this;
	},


	fixWidth: function(items){
		var w, self = this;
		if (items) {
			w = this.itemsRoot.width();
		}
		else {
			w = 0;
			items = this.itemsRoot.children();	
		}
		items.each(function(i){
			self.loadedImages[i+1] = true;
			w += $(this).fullwidth();
		});
		this.itemsRoot.width(w);

		return this;
	},

	_fetch_total: function(next){
		var self = this, url;
		if (app.cur_slideshow === app.slideshow) {
			url ='json={"HEAD":{"service_type":"'+this.service_type+'","action_type":"search","output_type":"json","page_size":10,"page":1},"BODY":{"query":"'+app.gallery.settings.query+'", "year":"'+app.gallery.settings.year+'", "location":"'+app.gallery.settings.location+'"}}';
		}
		else {
			url ='json={"HEAD":{"service_type":"'+this.service_type+'","action_type":"search","output_type":"json","page_size":10,"page":1},"BODY":{}}';
		}
		this.ajaxcall = $.ajax({
			type: 'get',
			dataType: 'json',
			url: '/SOAPjr',
			data: url,
			success: function(json){
				if (json.HEAD.result) {
					self.totalImages = json.BODY.total_hits
					self.pageTotal = parseInt(json.BODY.total_hits / self.pageSize) + 1;
				}
				else {
					app.display_errors(json.HEAD.errors)
				}
			},
			error: app.ajax_fail
		});
		return this;
	},

	next: function(toEnd){ 
		if (!this.locked && !this.nextDisabled) {
			this.locked = true;
			var self = this, scrollTo;

			var rule1 = toEnd; // forced to go to end of ul
			var rule2 = this.page == this.pageTotal; // we're on the last page
			var rule3 = this.page == this.pageTotal-1 && this.itemsRoot.children().length >= this.totalImages; // we are on the one but last page, but we have all images fetched and rendered already
			if (rule1 || rule2 || rule3) {
				// scroll only to the end of the ul
				scrollTo = self.scrollWidth - parseInt(self.itemsRoot.width(), 10) + 1;
				if (rule2 || rule3) {
					self.atRightEnd = true;
				}
			}
			else {
				this.page++;
				scrollTo = parseInt(self.itemsRoot.css('left'), 10) + 1 - self.scrollWidth;
				self.atRightEnd = false;
			}
			self.itemsRoot.animate({
				left: scrollTo 
			}, self.settings.speed, function(){
				self.checkArrows();
				self.checkImages();
			});
		}
		return this;
	},

	prev: function(toBeginning){
		if (!this.locked && !this.prevDisabled) {
			this.locked = true;
			var self = this, scrollTo;
			this.page = this.page > 1 ? --this.page : 1;
			if (toBeginning) {
				scrollTo = 0;
			}
			else {
				scrollTo = (parseInt(self.itemsRoot.css('left'), 10) + self.scrollWidth) > 0 ? 0 : parseInt(self.itemsRoot.css('left'), 10) + self.scrollWidth
			}
			self.itemsRoot.animate({
				left: scrollTo
			}, self.settings.speed, function(){
				self.atRightEnd = false;
				self.checkArrows();
				self.checkImages();
			});
		}
		return this;

	},

	checkArrows: function(){
		if (parseInt(this.itemsRoot.css('left'), 10) >= 0) {
			this.itemsRoot.css('left', 0);
			this.prevDisabled = true;
		}
		else {
			this.prevDisabled = false;
		}
		if (this.atRightEnd) { 
			this.nextDisabled = true;
		}
		else {
			this.nextDisabled = false;
		}

			// TODO: check if all loaded as well and disable next
		return this;
	},

	checkImages: function(initial){
		var self = this, scrollTo;
 		if (this.stop_checking_images) { self.locked = false; return this;}
		if (parseInt(this.itemsRoot.width(), 10) + parseInt(this.itemsRoot.css('left'), 10) < this.scrollWidth) {
			// we have extra space on the right

			if ((this.itemsRoot.children().length < this.totalImages) && !(this.page > this.pageTotal || this.page < 0)) {
				this.loadImages();
				return this; 
			}
			else { // no more images to load - just adjust the offset
				scrollTo = self.scrollWidth - parseInt(self.itemsRoot.width(), 10) + 1;
				self.atRightEnd = true;
			
				self.itemsRoot.animate({
					left: scrollTo 
				}, self.settings.speed, function(){
					self.locked = false;
					self.checkArrows();
				});
				return this; 
			}
		}
		else if (self.removed.length && !$(this.settings.items+".rebuildLeft", this.itemsRoot).is(":obfuscated")){ // we need to rebuild the removed items
			self.rebuild();
		}
		else {
			self.locked = false;
		}
		return this;
	},

	rebuild: function(){
		if (this.removed.length) {
			var item = this.removed.shift();
			var html = '<li><a href="'+item.link_url+'" class="'+item.link_class+'" title="'+item.link_title+'"><img src="'+item.thumb_url+'" alt="'+item.thumb_alt+'" title="'+item.thumb_title+'" /></a></li>';
			var rootLeft = parseInt(this.itemsRoot.css('padding-left'), 10);
			this.itemsRoot.css('padding-left', rootLeft-item.w).prepend(html);
			this.checkItems();
		}
		return this;
	},

	checkTotal: function(){
		var items = this.itemsRoot.children(), self = this;
		if (items.length > this.settings.MAX) { 
			var diff = items.length - this.settings.MAX;
			var toRemove = items.eq(diff).prevAll();
			toRemove.next().addClass('rebuild');
			toRemove.each(function(){ // remove and store data to later reconstruct
				var elem = $(this),
					img = $('img', elem),
					link = $('a', elem),
					data = {
						w: elem.width(),
						thumb_url: img.attr('src'),
						thumb_alt: img.attr('alt') || '',
						thumb_title: img.attr('title') || '',
						link_title: link.attr('title') || '',
						link_url: link.attr('href'),
						link_class: link.attr('class') || ''
					},
					width = elem.width();

				self.removed.unshift(data);
				var rootLeft = parseInt(this.itemsRoot.css('padding-left'), 10);
				self.itemsRoot.css('padding-left', rootLeft + width);
				elem.remove();
			});
		}
		return this;
	},

	loadImages: function(){
		var self = this, url;
		if (app.cur_slideshow === app.slideshow) {
			url ='json={"HEAD":{"service_type":"'+this.service_type+'","action_type":"search","output_type":"posh","page_size":'+this.pageSize+',"page":'+this.page+'},"BODY":{"query":"'+app.gallery.settings.query+'", "gallery":"'+app.gallery.settings.where+'", "year":"'+app.gallery.settings.year+'", "location":"'+app.gallery.settings.location+'", "template":"'+this.template+'"}}';
		}
		else {
			url = 'json={"HEAD":{"service_type":"'+this.service_type+'","action_type":"search","output_type":"posh","page_size":'+this.pageSize+',"page":'+this.page+'},"BODY":{"template":"'+this.template+'"}}';
		}
		this.ajaxcall = $.ajax({
			type: 'get',
			dataType: 'json',
			url: '/SOAPjr',
			data: url,
			success: function(json){
				if (json.HEAD.result && json.BODY.content) {
					/*var newItems = $(json.BODY.content).appendTo(self.itemsRoot);
					self.fixWidth(newItems);
					self.checkTotal();
					self.checkImages();
					if (self.settings.pass_data) {
						app.cur_slideshow.addItems(json.BODY.data.results);
					} */
					self.preloadImages(json);
				}
				else {
					app.display_errors(json.HEAD.errors)
				}
			},
			error: app.ajax_fail
		});
		return this;

	}

};



(function($) {
$.fn.extend({

		prompt: function(){
			return this.each(function(){
				$(this)
				.focus(function(e){
					if (this.value == this.defaultValue) {
						this.value = '';
					}
				})
				.blur(function(e){
					if (this.value == this.defaultValue || this.value === '') {
						this.value = this.defaultValue;
					}
				});
			});
		},

	fullwidth: function(){
		var el = $(this).eq(0);
		var width = el.width();
		width += parseInt(el.css('padding-left'),10);
		width += parseInt(el.css('padding-right'),10);
		width += parseInt(el.css('margin-left'),10);
		width += parseInt(el.css('margin-right'),10);
		width += isNaN(parseInt(el.css('border-left-width'),10)) ? 0 : parseInt(el.css('border-left-width'),10);
		width += isNaN(parseInt(el.css('border-right-width'),10)) ? 0 : parseInt(el.css('border-right-width'),10);
		return width;
	},

	reverse: [].reverse,
	
	fullheight: function(){
		var el = $(this).eq(0);
		var height = el.height();
		height += parseInt(el.css('padding-top'),10);
		height += parseInt(el.css('padding-bottom'),10);
		height += parseInt(el.css('margin-top'),10);
		height += parseInt(el.css('margin-bottom'),10);
		height += isNaN(parseInt(el.css('border-top-width'),10)) ? 0 : parseInt(el.css('border-left-width'),10);
		height += isNaN(parseInt(el.css('border-bottom-width'),10)) ? 0 : parseInt(el.css('border-right-width'),10);
		return height;
	}
})

/*
 *	obscured jQuery Selector Plug-in v$Revision: 11 $
 *	<https://sourceforge.net/projects/jqueryobscured>
 *	
 *	Copyright (c) 2009 Dave Willkomm
 *	Licensed under the MIT License
 *	<http://www.opensource.org/licenses/mit-license.php>
 */
$.extend($.expr[":"], {
		
		/*
		 *	Returns a boolean indicating that the specified element is visible, but partially or completely hidden by an
		 *	ancestor element.
		 */
		obscured: function(e)
		{
			var	deltaX,
				deltaY,
				element = $(e),
				elementOffset,
				overflowX,
				overflowY,
				p,
				parent,
				parentOffset;
			
			
			if (element.is(":visible"))
			{
				for (p = e.parentNode; p !== document; p = p.parentNode)
				{
					parent = $(p);
					overflowX = parent.css("overflow-x");
					overflowY = parent.css("overflow-y");
					
					if (overflowX !== "visible" || overflowY !== "visible")
					{
						elementOffset = element.offset();
						parentOffset = parent.offset();
						
						
						return (parentOffset.top  > elementOffset.top  || // top obscured
								parentOffset.left > elementOffset.left || // left obscured
								parentOffset.top  + parent.height() < elementOffset.top  + element.height() || // bottom obscured
								parentOffset.left + parent.width()  < elementOffset.left + element.width());   // right obscured
					}
				}
			}
			
			return false;
		}
		
	});
jQuery.extend({
   getScript: function(url, callback) {
      var head = document.getElementsByTagName("head")[0];
      var script = document.createElement("script");
      script.src = url;

      // Handle Script loading
      {
         var done = false;

         // Attach handlers for all browsers
         script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
                  this.readyState == "loaded" || this.readyState == "complete") ) {
               done = true;
               if (callback)
                  callback();

               // Handle memory leak in IE
               script.onload = script.onreadystatechange = null;
            }
         };
      }
      head.appendChild(script);

      // We handle everything using the script element injection
      return undefined;
   }
});

	
})(jQuery);
