var config = new Config;
	
function Config() {

	function checkLocation() {
		checkRewrite();
	}
	
	function xmlForHTMLData(data) {
	
		jQuery(data).find("xmlhtml"). each(function() {
			var parent_node = jQuery("parent", this).text();
			var self_node = jQuery("self", this).text();
			var html = jQuery("content", this).text();
			var js = jQuery("js", this).text();
			
			var existing_content = jQuery(parent_node).find(self_node);
			
			if (existing_content.length > 0) {
				existing_content.replaceWith(html);
			} else {
				jQuery(parent_node).prepend(html);
				existing_content = jQuery(parent_node).find(self_node);
				existing_content.hide();
				existing_content.fadeIn();
			}
			
			if (js) {
				eval(js);	
			}
		});
		
		initToolTips();
		
	}
	
	checkLocation();

	return {
		sceneAjaxURL: '/rpc',
		xmlForHTML: function(data) {
			xmlForHTMLData(data);
		}
	}
}

function initMenu() {
	var menu = new Menu(jQuery("#Menu"));
	var search_ac = new SearchTopAutoComplete(jQuery(".logged-in .autocomplete"));
}

jQuery(function() {
	init();
});

function init() {
	initMenu();
	initRatingContainers();	
	initSidebarTitles();
	initPopulatedInput();
	initIndividual();
	initTabs();
	initToolTips();
}

function initSection(section) {
	
	if (! section || section ==  "frontpage") {
		initScene();
	} 
	
	if (! section || section == "titlepage") {
		initTitlesPage();
	} 
	
	if (! section || section == "titlesearch") {
		initTitleSearch();
		initTitleSearchListView();
		initTitleSearchGenreBrowse();
	} 
	
	if (! section || section == "userprofile") {
		initProfilePage();
	}
	
	if (! section || section == "usersearch") {
		initUserSearchPage();
	}
	
	if (! section || section == "friendsedit") {
		initFriendsEditPage();
	}
	
	if (! section || section == "friendsoverview") {
		initFriendsOverviewPage();
	}
	
	if (! section || section == "finetunerecommendations") {
		initFineTuneRecommendationsPage();
	}
	
	if (! section || section == "helpsection") {
		initHelpSection();
	}
	
	if (! section || section == "addlist") {
		initListsAddPage();
	}	
	
	if (! section || section == "viewlist") {
		initListsViewPage();
	}	
	
	if (! section || section == "listshome") {
		initListsHomePage();
	}
	
}

function initFriendsEditPage() {
	var friends_edit = new FriendsEdit(jQuery("#EditFriends"));
}

function initFineTuneRecommendationsPage() {
	jQuery(".finetune").each(function() {
		new FineTuneRecommendationUser(jQuery(this));
	});
}

function initIndividual() {
	$A(document.getElementsByTagName("script")).findAll( function(s) {
		return (s.src && s.src.match(/sceneami\.js(\?.*)?$/))
    }).each( function(s) {
		var path = s.src.replace(/sceneami\.js(\?.*)?$/,'');
		var includes = s.src.match(/\?.*load=([a-z,]*)/);
		if (! includes) {
			initSection(false);
		} else {
			(includes ? includes[1] : 'frontpage,titlepage,search,userprofile').split(',').each(
			function(include) { 
				initSection(include);
		   });	   
	   }
    });
}

function initFriendsOverviewPage() {
	jQuery("#FriendRequests .request").each(function() {
		new FriendRequest(jQuery(this));
	});
}

function initHelpSection() {

	var contact_page = new ContactPage(jQuery("#ContactPage"));
	var faq_page 	 = new FAQ(jQuery("#FAQ"));

}

/* INIT */

function initListsHomePage() {
	var lists_friends = new SceneContainer(jQuery("#ListsFriends"), "/more_lists_friends", "/lists");		
	var lists_others = new SceneContainer(jQuery("#ListsOutsideFriends"), "/more_lists_others", "/lists");		
	var comments_yours = new SceneContainer(jQuery("#ListsCommentsYours"), "/more_comments_yours", "/lists");		
	var comments_others = new SceneContainer(jQuery("#ListsCommentsOthers"), "/more_comments_others", "/lists");		
	var lists_ideas = new ListsIdeas(jQuery("#ListsIdeas"));
}

function initListsAddPage() {
	var list_add = new ListsAddPage(jQuery(".lists-add"));
	var list_edit = new ListsEditPage(jQuery(".lists-edit"), list_add);
}

function initListsViewPage() {

	var listadd = new MovieAddCommentContainer(jQuery("#ListAddComment"), jQuery("#ListComments"), "/lists");
	var comments = new Array;
	
	jQuery('#ListComments .comment').each(function() {
		comments.push(new MovieComment(jQuery(this), "/lists"));
	});
	
	listadd.setTimer(new CommentEditHandler(comments));

}

function initSidebarTitles() {
	jQuery(".sidebarTitles").each(function() {
		new SidebarTitles(jQuery(this));
	});
}

function checkRewrite() {
	var hash = document.location.hash.replace("#", "");	
	if (hash.length > 0 && hash.indexOf("=") != -1) {
		var query = document.location.search.replace("?", "");
		var combo = hash + "&" + query;
		var res = "";
		combo.split('&').each(
			function(include) { 
				var parts = include.split("=");
				if (res.indexOf("&" + parts[0] + "=") == -1) {
					res += "&" + include;
				}
			}
		);		
		res = location.protocol + "//" + location.host + location.pathname + res.replace(/^&|/, "?").replace(/&$/, '');
		document.location.href = res;			
	}	
}

function initToolTips() {

	$$("*[title]").each(function(element) {
		if (element.title.length > 0) {
			new Tip(element, element.title, { style: 'protoblue', stem: 'topLeft'});
		}
			element.title = '';
		});

}

function initUserSearchPage() {
	var user_search = new UserSearch(jQuery("#UserSearchForm"), jQuery("#UserSearchResult"));
}

function initTabs() {
	jQuery(".tabs > ul").tabs();
}

function initPopulatedInput() {
	jQuery(".populated-input").each(function() {
		new PopulatedInput(jQuery(this));
	});
}

function initRatingContainers() {
	jQuery('.dropdown-selector').each(function() {
		new DropDownContainer(jQuery(this));				
	});
	
	jQuery('.rating').each(function() {
		new RatingContainer(jQuery(this));
	});
}

function initProfilePage() {
	var seen_list   = new MovieSeenList(jQuery("#UserSeen"), "/get_seen_page");
	var wish_list   = new MovieSeenList(jQuery("#WishUserSeen"), "/get_wish_seen_page");
	var common_list = new MovieSeenList(jQuery("#CommonSeen"), "/get_common_seen_page");
	var user_lists  = new MovieSeenList(jQuery("#UserLists"), "/get_lists_page");
	var req_form    = new FriendRequestForm(jQuery("#UserRelation"));
}

function initTitleSearch() {
	new TitleSearch(jQuery('.search-result'));				
}

function initTitleSearchListView() {
	new TitleSearchListView(jQuery('.search-result-listview'));				
}

function initTitleSearchGenreBrowse() {
	new TitleSearchGenreBrowse(jQuery('.browse-popular-by-genre'));
}

function initScene() {
	initSceneComments();
	initSceneCommentsOutside();
	var friends_seen 		= new SceneContainer(jQuery("#FriendsSeen"), "/more_friends_seen", "/scene");
	var most_watched 		= new SceneContainer(jQuery("#MostWatched"), "/more_most_watched", "/scene");	
	var top_rated 			= new SceneContainer(jQuery("#TopRated"), "/more_top_rated", "/scene");		
	var recommendations		= new SceneContainer(jQuery("#Recommendations"), "/more_recommendations", "/scene");
	var lists_ideas 		= new ListsIdeas(jQuery("#ListsIdeas"));
}

function initSceneComments() {
	var scene_comments 		= new SceneContainer(jQuery("#SceneComments"), "/more_scene_comments", "/scene");
}

function initSceneCommentsOutside() {
	var outside_comments 	= new SceneContainer(jQuery("#OutsideSceneComments"), "/more_outside_comments", "/scene");
}

function initTitlesPage() {
	var comments = new Array;
	
	jQuery('#MovieComments .comment').each(function() {
		comments.push(new MovieComment(jQuery(this), "/titles"));
	});
	
	var macc = new MovieAddCommentContainer(jQuery("#MovieAddComment"), jQuery("#MovieComments"), "/titles");	
	macc.setTimer(new CommentEditHandler(comments));
	
	var wishlist = WishListContainer(jQuery("#MovieWishList"));
	var rating = TitlesRatingContainer(jQuery("#MovieRating"), wishlist);
	
	initTitlesPageUserCovers();
	
}

function initTitlesPageUserCovers() {
	var usercovers = UserCoverContainer(jQuery("#MovieCovers"));
}


/* SIDEBAR */

function SidebarTitles(target) {

	var limit = 5;
	var offset = 1;
	var max;
	var listview;
	var coverview;
	
	var domain = "/settings";
	var command = "/save_view_setting";
	
	function attachEvents() {
	
		if (! target.hasClass("treated")) {
			listview = jQuery(target.find(".listview"));
			coverview = jQuery(target.find(".coverview"));
			max = (listview.find("li").length)/limit;
			target.find(".show-listview").click(handleShowListView);
			target.find(".show-coverview").click(handleShowCoverView);
			showGroup(1);
			createLinks();
			if (target.hasClass("current-is-list")) {
				listview.show();
			}
			target.addClass("treated");
		}
	}
	
	function handleShowListView(event) {
		coverview.fadeOut("fast", function(){listview.fadeIn();	target.addClass("current-is-list");target.removeClass("current-is-covers");});
		saveSetting(jQuery(this).attr("rel"), jQuery(this).attr("rev"));
		return false;
	}
	
	function handleShowCoverView(event) {
		listview.fadeOut("fast", function(){coverview.fadeIn();target.addClass("current-is-covers");target.removeClass("current-is-list");});
		saveSetting(jQuery(this).attr("rel"), jQuery(this).attr("rev"));
		return false;
	}
	
	function showGroup(group) {
		var end = group*limit;
		var start = Math.max(0,((group-1)*limit)-1);
		var selector = "li:lt("+end+")" + ((start > 0) ? ":gt("+start+")" : "");
		listview.find("li:not("+selector+")").hide();
		listview.find(selector).show();
	}
	
	function createLinks() {
		listview.append("<div class='scene-item bottom'><a href='#' class='prev'>&lt;</a><a href='#' class='next'>&gt;</a><div class='clearer'>&nbsp;</div></div><div class='clearer'>&nbsp;</div>");
		listview.find(".prev").click(handlePrevClick);
		listview.find(".next").click(handleNextClick);
	}
	
	function handlePrevClick(event) {
		if (offset > 1) {
			offset--;
			showGroup(offset);
		}
		return false;
	}
	
	function saveSetting(page, view) {
		if (page && view) {
			jQuery.get(config.sceneAjaxURL + domain + command, { 'page': page, 'view': view }, null);	
		}
	}
	
	function handleNextClick(event) {
		if (offset < max) {
			offset++;
			showGroup(offset);
		}
		return false;
	}
	attachEvents();
}


/* USER PROFILE PAGE */

function FriendRequestForm(target) {

	var friend_code;
	var request_code;
	var domain = "/profile";
	var command = "/request_friendship";

	function attachEvents() {
	
		var link = jQuery(target.find(".request a"));
		link.click(handleToggleRequestForm);
		friend_code = link.attr("rel");
		request_code = link.attr("rev");
		target.find(".request .cancel").click(handleToggleRequestForm);
		target.find(".request .send").click(handleSendRequest);
	}
	
	function handleToggleRequestForm(event) {
		target.find(".request .form").slideToggle();
		return false;
	}
	
	function handleSendRequest(event) {
		var msg = target.find("textarea").val();
		jQuery.get(config.sceneAjaxURL + domain + command, { 'friend_code': friend_code, 'request_code': request_code, 'message': msg }, handleRequestResponse);	
		return false;
	}
	
	function handleRequestResponse(data) {
		target.slideUp();
		config.xmlForHTML(data);
	}
	
	attachEvents();
}


function MovieSeenList(target, command) {
	var domain = "/profile";
	var select;
	var page;
	var form;
	
	function attachEvents() {
		form = target.find("form");
		select = target.find("select");
		select.change(handlePageChange);		
	}
	
	function handlePageChange(event) {
		page = select.val();
		jQuery.get(config.sceneAjaxURL + domain + command, jQuery(form).serializeArray(), handlePageChangeResponse);	
	}
	
	function handlePageChangeResponse(data) {
		target.html(data);
		attachEvents();	
		target.find('.dropdown-selector').each(function() { new DropDownContainer(jQuery(this)); });
		target.find('.rating').each(function() { new RatingContainer(jQuery(this)); });
		initToolTips();
	}
	attachEvents();
}

/* USER SEARCH */

function UserSearch(target, container) {

	var domain = "/profile";
	var command = "/search_profiles";
	var query;
	
	function attachEvents() {
		target.submit(handleFormSubmit);
	}
	
	function handleFormSubmit(event) {
		query = target.find("input[type='text']").val();
		jQuery.get(config.sceneAjaxURL + domain + command, { 'q': query }, handleSearchResponse);	
		return false;
	}
	
	function handleSearchResponse(data) {
		container.html(data);
		jQuery(document.location).attr("hash", "q=" + query); 
	}
	
	attachEvents();

}


/* TITLES SEARCH */

function TitleSearchGenreBrowse(target) {

	var optionsContainer;

	function initInterface() {
		optionsContainer = target.find(".advanced-options");
		target.find(".advanced-options-link").click(handleToggleAdvancedOptions);
	}
	
	function handleToggleAdvancedOptions() {
		optionsContainer.slideToggle();
		return false;
	}

	initInterface();
}

function TitleSearchListView(target) {

	var domain = "/titles";
	var commandFetchRatingMenu  = "/fetch_titles_ratingmenu";
	var commandFetchRatingMoreMenu  = "/fetch_titles_ratingmenu_more";
	var commandTitleInfo = "/title_info";
	var commandTitleInfoMore = "/title_info_more";
	
	function initInterface() {
		initCoverToolTips('information', commandTitleInfo);
		initCoverToolTips('information_more', commandTitleInfoMore);
		initRatingToolTips('rate_button', commandFetchRatingMenu);
		initRatingToolTips('rate_button_more', commandFetchRatingMoreMenu);
	}
	
	function initCoverToolTips(rel, command) {
	
		$$("*[rel='"+ rel +"']").each(function(element) {
			if (element.rev.length > 0) {
			new Tip(element, "Loading...", 
			{ 	title: element.title, 
				delay: 0,
				showOn: 'mouseover', hideOn: false, hideAfter: 0.3, 
				stem: 'topMiddle', 
				offset: { x: 0, y: 0 }, 
				hook: { target: 'bottomMiddle', tip: 'topMiddle' },
				ajax: { url: config.sceneAjaxURL + domain + command, options: { method: 'get', parameters: {'movie_id': element.rev} } }
			});
			}	
		});
	
	}
	
	function initRatingToolTips(rel, command) {
		$$("*[rel='"+ rel +"']").each(function(element) {
			new Tip(element, "Loading...", 
			{ 	title: element.title, 
				delay: 0,
				showOn: 'mouseover', hideOn: false, hideAfter: 0.3, 
				stem: 'topMiddle', 
				offset: { x: 0, y: 0 }, 
				hook: { target: 'bottomMiddle', tip: 'topMiddle' },
				ajax: { url: config.sceneAjaxURL + domain + command, options: { onComplete: gotRatingMenu, method: 'get', parameters: {'movie_id': element.rev} } }
			});
		});
	}
	
	function gotRatingMenu(event) {
		jQuery(".prototip a").click(handleRatingClicked);
		jQuery('.prototip').each(function() {
			new RatingContainer(jQuery(this));
		});
	}
	
	function handleRatingClicked() {
		jQuery(".prototip").fadeOut();
		var title_id = jQuery(this).attr("rel");
		var rating   = jQuery(this).attr("class");
		if (rating != "wishlist") {
			// need to find the corresponding title url in the dom
			target.find("a[rel=" + title_id + "]").addClass("rerate");
		} 
		
		jQuery(this).parents("div").find(".wishlist").parent("li").fadeOut();

	}

	initInterface();

}

function TitleSearch(target) {

	var sliderClass = ".slider";
	var handleClass = ".handle";
	var ratingClass = ".movie-rating";
	var listedClass = ".movie-list";
	var extendClass = ".extended-movie-list";
	
	var domain = "/titles";
	var commandFetchSubMenu  = "/fetch_titles_submenu";
	var commandFetchSubMenuExtended  = "/fetch_titles_submenu_extended";
	var commandAddWish = "/add_wish";
	var commandAddWishExtended = "/add_wish_extended";
	var commandAddRating = "/add_rating";
	var commandMoreInfo = "/title_info";
	var commandAddRatingExtended = "/add_rating_extended";
	
	function initInterface() {
		
		var ul = target.find("ul");				
		var itemsWidth = ul.innerWidth() - ul.parents("div").outerWidth();
		
		if (itemsWidth < 0) {
			jQuery(sliderClass).hide();
		} else {
			jQuery(sliderClass).show();
		}
				
		target.find(sliderClass).slider({
			minValue: 0,
			maxValue: itemsWidth,
			handle: handleClass,
			stop: function (event, ui) {
				ul.animate({'left' : ui.value * -1}, 500);
			},
			slide: function (event, ui) {
				ul.css('left', ui.value * -1);
			}
		});
	}
	
	function initExtendedInterface() {
		
		var list = target.find(extendClass);
		if (list.length > 0) {
			var max =  document.documentElement.clientHeight - list.offset().top - 90;	
			list.height(max);
		}
	
	}
	
	function initDragables() {
		target.find("li").draggable({helper: 'clone'});		
		target.find(ratingClass).droppable({ 
			accept: "li.movie, li.movie-extended", 
			hoverClass: "active", 
			drop: rateDropHandler
		});
	}
	
	function rateDropHandler(ev, ui) {
		var title = ui.draggable;
		var movie_id = jQuery(title).find("a").attr("rel");
		var rating = jQuery(this).find("span").attr("class");		
		var command = commandAddRating;
		
		if (jQuery(title).hasClass("movie-extended")) {
			command = commandAddRatingExtended;
		} 

		jQuery.get(config.sceneAjaxURL + domain + command, { 'movie_id': movie_id, 'rating': rating }, handleRatingAddedResponse);	
		title.clone().appendTo(jQuery(this)).fadeOut("slow");		
		title.addClass("seen");
		initSeenTitles(true);
	}
	
	function handleRatingAddedResponse(data) {
		config.xmlForHTML(data);
	}
	
	function initSeenTitles(effects) {
		if (effects) {
			target.find(".seen[opacity!=0.2] img").fadeTo("slow", 0.2);
		} else {
			target.find(".seen[opacity!=0.2] img").css("opacity", 0.2);
		}
	}
	
	function initLinks() {
		if (target.find(ratingClass).length > 0) {
			target.find(listedClass + " a").click(handleTitleClick);
		}
	}
	
	function handleTitleClick(event) {		
		return false;
	}
		
	function initToolTips() {
		
		if (target.find(ratingClass).length == 0) return;

		$$(listedClass + ' a').each(function(element) {		
			new Tip(element, "Loading...", 
				{ style: 'protoblue', title: element.title, showOn: 'click', hideOn: 'click',  hideAfter: 0.3, stem: 'topMiddle', 
					offset: { x: -5, y: -25 }, 
					hook: { target: 'bottomMiddle', tip: 'topMiddle' },
					ajax: { url: config.sceneAjaxURL + domain + commandFetchSubMenu, options: { onComplete: attachWishEvents, method: 'get', parameters: {'movie_id': element.rel} } }
				});					
			element.title = '';
		});
		$$(extendClass + ' a.title').each(function(element) {		
			new Tip(element, "Loading...", 
				{ style: 'protoblue', title: element.title, showOn: 'click', hideOn: 'click',  hideAfter: 1, stem: 'topMiddle', 
					hook: { target: 'bottomMiddle', tip: 'topMiddle' },
					ajax: { url: config.sceneAjaxURL + domain + commandFetchSubMenuExtended, options: { onComplete: attachWishEventsExtended, method: 'get', parameters: {'movie_id': element.rel} } }
				});					
			element.title = '';
		});
		$$(extendClass + ' .info').each(function(element) {		
			new Tip(element, "Loading...", 
				{ style: 'protoblue', showOn: 'click', hideOn: 'click',  hideAfter: 0.3, stem: 'topMiddle', 
					title: element.title,
					hook: { target: 'bottomMiddle', tip: 'topMiddle' },
					offset: { x: -1, y: -16 }, 
					ajax: { url: config.sceneAjaxURL + domain + commandMoreInfo, options: { method: 'get', parameters: {'movie_id': element.rel} } }
				});					
			element.title = '';
		});
	
		
		$$(listedClass + ' img').each(function(element) {
			new Tip(element, element.title, { style: 'protoblue', delay: 0, stem: 'topMiddle', hook: { target: 'bottomMiddle', tip: 'topMiddle' } });
			element.title = '';
		});
	}
	
	function attachWishEvents() {
		jQuery(".prototip .wish").click(addWishHandler);
	}
	
	function attachWishEventsExtended() {
		jQuery(".prototip .wish").click(addWishHandlerExtended);
	}
	
	function addWishHandler(event) {
		var link = jQuery(this);
		var movie_id = link.attr("rel");
		jQuery.get(config.sceneAjaxURL + domain + commandAddWish, { 'movie_id': movie_id }, null);
		link.slideUp();		
		return false;
	}
	
	function addWishHandlerExtended(event) {
		var link = jQuery(this);
		var movie_id = link.attr("rel");
		jQuery.get(config.sceneAjaxURL + domain + commandAddWishExtended, { 'movie_id': movie_id }, null);
		link.slideUp();		
		return false;
	}
	
	initSeenTitles(false);
	initInterface();	
	initExtendedInterface();	
	initToolTips();
	initDragables();
	initLinks();
	
}

/* SCENE */

function SceneContainer(target, command, domain) {

	var link_more;
	var page = 2;
	
	function attachEvents() {
		link_more = target.find(".load-more");
		link_more.click(loadMoreHandler);
	}
	
	function loadMoreHandler(e) {
		link_more.addClass("loading");
		jQuery.get(config.sceneAjaxURL + domain + command, { 'p': page }, handleCommentsResponse);		
		return false;
	}
	
	function handleCommentsResponse(data) {
		link_more.removeClass("loading");
		if (data == '') {
			alert('There is nothing more to show :)');
			link_more.hide();
		} else {
			link_more.before(data);
			initRatingContainers();
			initToolTips();
			page++;			
		}
	}
	
	attachEvents();	
}

/* TITLES PAGE  */

function WishListContainer(target) {

	var domain = "/titles";
	var commandAdd = "/add_wish";
	var commandRemove = "/remove_wish";
	var selectedClass = "selected";
	
	function attachEvents() {
		target.find("a").click(toggleWishListHandler);
	}
	
	function toggleWishListHandler(event) {
	
		var movie_id = jQuery(this).attr("rel");
		
		if (target.hasClass(selectedClass)) {
			jQuery.get(config.sceneAjaxURL + domain + commandRemove, { 'movie_id': movie_id }, handleResponse);
		} else {
			jQuery.get(config.sceneAjaxURL + domain + commandAdd, { 'movie_id': movie_id }, handleResponse);
		}
	
		return false;
	}
	
	function handleResponse(event) {
		target.toggleClass(selectedClass);
	}
	
	function hideContainer() {
		target.addClass(selectedClass);
		target.slideUp("fast");
	}
	
	function showContainer() {
		target.removeClass(selectedClass);		
		target.slideDown("fast");
	}
	
	
	attachEvents();
	
	return {
		show: function() { showContainer() },
		hide: function() { hideContainer() }
	}	

}

function CommentEditHandler(comments) {

	var applicableComments = new Array;
	var timer = false;
	
	function indexArray() {
		applicableComments = new Array;		
		for (var i = 0; i < comments.length ; i++) {
			if (comments[i].editLeft) {
				applicableComments.push(comments[i]);
			}
		}
		if (timer == false && applicableComments.length > 0) {
			setInterval (decreaseComments, 1000);
			timer = true;
		}
	}
	
	function attachTimer() {
		indexArray();
	}
	
	function decreaseComments() {
		for (var i = 0; i < applicableComments.length ; i++) {
			if (applicableComments[i].editLeft != null) {
				applicableComments[i].decreaseEdit();
			}
		}
	}
	
	function reindexArray(newComment) {		
		comments.push(newComment);
		indexArray();		
	}
	
	attachTimer();
	
	return {
		reindex: function(newComment) {
			reindexArray(newComment);
		},
		index: function() {
			indexArray();
		}
	}

}

function TitlesRatingContainer(target, wishlist) {

	var currentRating = null;
	var currentInfoText = null;
	var defaultInfoText;
	var movie_id = null;
	
	var domain = "/titles";
	var commandAdd = "/add_rating";
	var commandRemove = "/remove_seen";
	
	function getCurrentRating() {
		var ratingLink = target.find(".selected").find("a");
		if (ratingLink.length > 0) {
			var rating = ratingLink.attr("class");
			currentInfoText = ratingLink.attr("rev");
			currentRating = rating;
		}
	}
	
	function attachEvents() {
		defaultInfoText = target.find(".information").html();
		movie_id = target.find("a").attr("rel");
		target.find("a").click(changeRatingHandler);		
		getCurrentRating();
		setInterface(false);
	}

	function setInterface(effects) {
		if (currentRating != null) {
			target.find("a").each(function() {
				if (jQuery(this).attr("class") != currentRating) {
					if (effects) {
						jQuery(this).fadeTo("slow", 0.2);
					} else {
						jQuery(this).css("opacity", 0.2);
					}
				} else {
					if (effects) {
						jQuery(this).fadeTo("slow", 1);
					} else {
						jQuery(this).css("opacity", 1);
					}
				}
			});
		}		
		if (currentInfoText != null) {
			target.find(".information").html(currentInfoText);
		} 		
	}
	
	function clear() {
		jQuery.get(config.sceneAjaxURL + domain + commandRemove, { 'movie_id': movie_id }, handleRemoveResponse);
	}
	
	function handleRemoveResponse(data) {
		currentInfoText = null;
		currentRating = null;
		target.find("a").css("opacity", 1);		
		target.find(".information").html(defaultInfoText);
		wishlist.show();
	}
	
	function changeRatingHandler(event) {
	
		var ratingLink = jQuery(this);
		var rating = ratingLink.attr("class");
	
		if (rating != currentRating) {
			currentRating = rating;
			currentInfoText = ratingLink.attr("rev");
			jQuery.get(config.sceneAjaxURL + domain + commandAdd, { 'movie_id': movie_id, 'rating': currentRating }, handleRatingResponse);
		} else {
			clear();
		}
		
		return false;
	}
	
	function handleRatingResponse(data) {
		wishlist.hide();
		setInterface(true);
	}
	
	attachEvents();

}

function UserCoverContainer(target) {

	var domain = "/titles";
	var commandUp = "/vote_cover_up";
	var commandDown = "/vote_cover_down";
	var link_core;
	
	function attachEvents() {
		target.find(".covers-upload-link").click(handleToggleUploadForm);
		target.find(".disabled a").css("opacity", "0.2").attr("title", '');
		target.find(".voting:not(.disabled) a").click(handleVoteClick);
	}
	
	function handleToggleUploadForm(event) {
		target.find(".covers-upload").slideToggle("slow");
	}
	
	function handleVoteClick(event) {
		link_core    = this;
		var link 	 = jQuery(this);
		var cover_id = link.attr("rel");
		var id		 = link.attr("rev");
		var link_css = link.attr("class");
		var command  = false;
				
		if (link_css == "thumbs-up") {
			command = commandUp;
		} else if (link_css == "thumbs-down") {
			command = commandDown;
		}
		
		if (command) {
			jQuery.get(config.sceneAjaxURL + domain + command, { cover_id: cover_id, id: id }, handleVoteResponse);	
		}
				
		return false;		
	}
	
	function handleVoteResponse(data) {
		$(link_core).prototip.hide();
		config.xmlForHTML(data);
	}
	
	attachEvents();
}

function MovieComment(target, domain) {

	var commandEdit = "/edit_comment";
	var commandDelete = "/delete_comment";
	var commandSpoiler = "/spoiler_comment";
	var previousComment;
	var previousCommentRaw;
	var commentId;
	var editLeft;
	
	var spoiler = false;
	var editing = false;
	
	var _spoilerContainer;
	var _textContainer;
	
	function attachEvents() {
	
		if (target.hasClass("spoiler")) {
			target.click(seeSpoilerHandler);
		}
		
		_textContainer = target.find(".text");
		target.find(".edit a").click(editCommentHandler);
		
		commentId 	= target.find(".edit a").attr("rel");
		editLeft 	= target.find(".edit a").attr("rev");
		
		if (editLeft) {
			target.find(".edit a").append("<span class='timeleft'>&nbsp;</span>");
			decreaseEditLeft();
		}	
		
		_spoilerContainer = target.find(".spoiler-change");

		if (_spoilerContainer.length) {
			if (! commentId) {
				commentId = _spoilerContainer.find("a").attr("rel");
			}
			spoiler = _spoilerContainer.hasClass("is-spoiler");
			_spoilerContainer.click(toggleSpoilerHandler);
		}
		
		attachSpeciality();
	}
	
	// start custom sites
	
	function attachSpeciality() {
		target.find("a[rel='youtube']").click(handleYouTubeLinkClick);
		
		$$("*[rel='youtube']").each(function(element) {
			if (element.rev.length > 0) {
				html = "<img src='" + element.rev + "' width='130' height='97' />";
				new Tip(element, html, { delay: 0, style: 'protoblue', stem: 'topLeft'});
			}
			element.rev = '';
		});
	}
	
	function handleYouTubeLinkClick(event) {
		jQuery(this).next(".youtube").slideToggle();
		return false;
	}
	
	// end custom sites
	
	function toggleSpoilerHandler(event) {
		jQuery.get(config.sceneAjaxURL + domain + commandSpoiler, { comment_id: commentId, spoiler: (! spoiler) }, handleSpoilerCommentResponse);					
		return false;
	}
	
	function handleSpoilerCommentResponse(data) {
		_spoilerContainer.toggleClass("is-spoiler");
		spoiler = ! spoiler;
	}
	
	function editCommentHandler(event) {
		toggleEdit();
		return false;
	}
	
	function toggleEdit() {
		setEdit(! editing);
	}
	
	function decreaseEditLeft() {
		if (editLeft < 1) {
			removeEditFunctionality();
			editLeft = null;
		} else {
			editLeft--;
			target.find(".edit .timeleft").html(editLeft + " seconds");
		}
	}
	
	function removeEditFunctionality() {
		if (editing) {
			setEdit(false);
		}
		target.find(".edit").remove();
	}
	
	function setEdit(mode) {
		editing = mode;
		if (editing) {
			target.addClass("editing");
			previousComment 	= _textContainer.html();
			previousCommentRaw 	= target.find(".unformatted-text").html();
			_textContainer.html("<textarea>" + previousCommentRaw + "</textarea><input type='submit' value='Edit' class='edit-button' /><input type='submit' value='Delete' class='delete-button' /><div class='clearfix'>&nbsp;</div>");
			_textContainer.find(".edit-button").click(performEditHandler);
			_textContainer.find(".delete-button").click(performDeleteHandler);
		} else {
			target.removeClass("editing");
			_textContainer.find(".edit-button").unbind("click", performEditHandler);
			_textContainer.find(".delete-button").unbind("click", performDeleteHandler);
			_textContainer.html(previousComment);	
			attachSpeciality();
		}		
		return false;
	}
	
	function performDeleteHandler(event) {
		if (confirm("Are you sure you would like to delete this comment?")) {
			jQuery.get(config.sceneAjaxURL + domain + commandDelete, { comment_id: commentId }, handleDeleteCommentResponse);		
		}
		return false;
	}
	
	function performEditHandler(event) {
		var textarea = target.find("textarea").val();
		jQuery.get(config.sceneAjaxURL + domain + commandEdit, { comment_id: commentId, comment: textarea }, handleEditCommentResponse);		
		return false;
	}
	
	function handleDeleteCommentResponse(data) {
		target.slideUp();
		return false;
	}
	
	function handleEditCommentResponse(data) {
		var textarea = target.find("textarea");
		target.find(".unformatted-text").html(textarea.val());
		previousComment = data;
		setEdit(false);
	}
	
	function seeSpoilerHandler(event) {
		target.unbind("click", seeSpoilerHandler);		
		target.removeClass("spoiler");
		return false;
	}
	
	attachEvents();
	
	return {
		editLeft: editLeft,
		decreaseEdit: function() { decreaseEditLeft(); }
	}

}

function MovieAddCommentContainer(target, commentsTarget, domain) {
	
	var command = "/add_comment";
	var form;
	var comment;
	var spoiler;
	var timerObject;
	
	function attachEvents() {		
		target.find("input[type='submit']").click(addCommentHandler);		
		form = target.find("form");
		comment = form.find("textarea");
		spoiler = form.find("input[type='checkbox']");		
	}
	
	function addCommentHandler(event) {
		if (comment.val().length > 0) {
			jQuery.post(config.sceneAjaxURL + domain + command, form.serializeArray(), handleCommentResponse);
		} else {
			showMessage("No comment text?");
		}
	}
	
	function handleCommentResponse(data) {
		clear();
		commentsTarget.prepend(data);
		commentsTarget.find(".comment.new").each(function() {
			var mc = new MovieComment(jQuery(this), domain);
			if (timerObject) {
				timerObject.reindex(mc);
			}
		});
		commentsTarget.find(".comment.new").fadeIn("slow").removeClass("new");
		commentsTarget.find(".missing-message").fadeOut("slow");
		initToolTips();
	}
	
	function showMessage(text) {
		alert(text);
	}
	
	function clear() {
		comment.val('');
		spoiler.attr('checked', false);
	}
	
	function setTimerObject(object) {
		timerObject = object;
	}
	
	attachEvents();
	
	return {
		setTimer: function (object) {
			setTimerObject(object);
		}
	}
}

/* CORE CONTAINERS */

function RatingContainer(target) {

	var domain = "/scene";
	var command = "/recommendation_action";
	var commandMore = "/recommendation_action_more";
	var sending = false;
	
	function attachEvents() {		
		target.find("a").click(clickHandler);
	}
	
	function clickHandler(e) {
		if (! sending) {
			rating = jQuery(this).attr("class");
			id = jQuery(this).attr("rel");
			
			if (jQuery(this).attr("rev") == "extended") {
				jQuery.get(config.sceneAjaxURL + domain + commandMore, { 'id': id, 'action': rating, 'source': location.pathname }, handleRateResponse);
			} else {
				jQuery.get(config.sceneAjaxURL + domain + command, { 'id': id, 'action': rating, 'source': location.pathname }, handleRateResponse);
			}
			
			sending = true;
		}
		return false;
	}
	
	function handleRateResponse(data) {
		sending = false;
		config.xmlForHTML(data);
	}
	
	attachEvents();	
}

function DropDownContainer(target) {
	
	var list;
	var heading;
	var link;
	var list_visible = false;
	var isAjax = false;
	var ajax;
	
	if (target.hasClass("ajax")) {
		initAjaxInterface();
	} else {
		initInterface();
	}
	
	function initAjaxInterface() {
		isAjax = true;		
		heading = target.find("h3");
		ajax = target.find(".ajax");
		link = heading.find("a");
		link.click(headingClickHandlerAjax);
		link.parent("h3").click(headingParentClickHandlerAjax);
	}
	
	function initInterface() {
		list = target.find("ul");
		heading = target.find("h3");	
		list.hide();
		heading.click(headingClickHandeler);
		list.find("a").click(containerLinkClick);
	}
	
	function headingParentClickHandlerAjax(event) {
		jQuery(this).find("a").click();
		return false;
	}
	
	function headingClickHandlerAjax(event) {
		if (! list_visible) {
			var movie_id = jQuery(this).attr("rel");
			var command = jQuery(this).attr("rev");
			heading.addClass("loading");
			jQuery.get(config.sceneAjaxURL + command, { 'movie_id': movie_id }, handleAjaxFetchResponse);
		} else {
			collapse();
		}
		return false;
	}
	
	function handleAjaxFetchResponse(data) {	
		heading.removeClass("loading");
		ajax.html(data);
		list = ajax.find("ul");		
		list.find("a").click(containerLinkClick);
		new RatingContainer(ajax.find(".rating"));
		expand();
	}
	
	function headingClickHandeler(event) {
		if (! list_visible) {
			expand();
		} else {
			collapse();
		}
		return false;
	}
	
	function expand() {
		heading.addClass("expanded");
		list.slideDown();
		list_visible = true;
	}
	
	function collapse() {
		heading.removeClass("expanded");
		list.slideUp();
		list_visible = false;
	}
	
	function containerLinkClick(event) {
		var disable = list.hasClass("disable");
		var command = jQuery(this).attr("class");
		var disable = jQuery(this).attr("rev");
		collapseAndDisable(disable);
		return false;
	}
	
	function collapseAndDisable(disable) {
		collapse();		
		if (disable) {			
			var parents = target.parents(".disable-item");
			if (parents.length > 0) {
				parents.fadeTo("slow", 0.2);
			} else {			
				target.fadeTo("slow", 0.2);
			}			
			if (heading) heading.unbind('click', headingClickHandeler);
			if (link) link.unbind('click', headingClickHandlerAjax);
		}
	}
	
};

function PopulatedInput(target) {

	var defaultText;
	var defaultType;

	function attachEvents() {
		defaultText = target.attr("title");
		defaultType = target.attr("type");
		target.attr("title", "");
		target.bind("focus", focus);
		target.bind("blur", blur);
		blur(false);
	}
	
	function focus(event) {
		if (target.val() == defaultText) {
			target.val('');
			target.removeClass("populated");
		}
	}
	
	function blur(event) {
		if (target.val().length == 0) {
			target.val(defaultText);
			target.addClass("populated");
		}
	}
	
	attachEvents();
}


function Menu(target) {

	function attachEvents() {
		target.find(".expand").click(handleToggleClick);
	}
	
	function closeall() {
		target.find(".expanded").removeClass("expanded").find("ul").hide();
	}
	
	function handleToggleClick(event) {
		var link = jQuery(this);
		var main = link.parent("li");
		var submenu = link.parent().find("ul");
		
		if (main.hasClass("expanded")) {
			main.removeClass("expanded");
			submenu.fadeOut();
		} else {
			closeall();		
			main.addClass("expanded");			
			submenu.fadeIn();
		}
		
		return false;
	}
	
	attachEvents();

}

/* FRIENDS OVERVIEW */

function FriendRequest(target) {

	var domain = "/profile";
	var command_accept = "/accept_friendrequest";
	var command_deny = "/deny_friendrequest";
	
	function attachEvents() {
		jQuery(target).find(".accept").click(handleAcceptRequest);
		jQuery(target).find(".deny").click(handleDenyRequest);
	}
	
	function handleAcceptRequest(event) {
		var request_id = jQuery(this).attr("rel");
		
		if (confirm("Are you sure you would like to ACCEPT this friend request?")) {
			jQuery.get(config.sceneAjaxURL + domain + command_accept, { 'request_id': request_id }, handleRequestResponse);	
		}
		return;
	}

	function handleDenyRequest(event) {
		var request_id = jQuery(this).attr("rel");
		
		if (confirm("Are you sure you would like to DENY this friend request?")) {
			jQuery.get(config.sceneAjaxURL + domain + command_deny, { 'request_id': request_id }, handleRequestResponse);	
		}
		return;
	}
	
	function checkEmpty() {
		
		var ul = jQuery(target).parents("ul");
		var count = jQuery(ul).find("li:visible").length;
		if (count > 1) {
			return false;
		} else {
			jQuery(ul).parent("div").slideUp();
			return true;
		}
	}
	
	function handleRequestResponse(data) {
		if (! checkEmpty()) {
			jQuery(target).slideUp();
		}
		
		config.xmlForHTML(data);
	}

	attachEvents();

}

/* FRIENDS EDIT */

function FriendsEdit(target) {

	function attachEvents() {
		target.find("a.remove").click(confirmDeleteHandler);
	}
	
	function confirmDeleteHandler(event) {
		return confirm("Are you sure you would like to delete this friend?");
	}
	
	attachEvents();
}

/* FINETUNE RECOMMENDATIONS */

function FineTuneRecommendationUser(target) {

	var trust_level_link;
	var trust_edit_container;
	var trust_slider;
	var trust_slider_value;
	var trust_figure;
	var trust_level_remove;
	
	var domain = "/scene";
	var command_set = "/set_trust_level";
	var command_remove = "/remove_trust_level";
	var user_code;
	var value;

	function attachEvents() {
		trust_level_link = jQuery(target.find(".trust-level"));
		trust_edit_container = jQuery(target.find(".trust-edit"));
		trust_slider = jQuery(target.find(".trust-slider"));
		trust_slider_value = jQuery(target.find(".trust-slider-value"));
		trust_level_remove = jQuery(target.find(".trust-level-remove"));
			
		trust_level_link.click(handleTrustLevelEdit);
		trust_level_remove.click(handleTrustLevelRemove);
		
		trust_slider.slider({ slide: handleSliderMove, change: handleSliderChanged });
				
		user_code = trust_level_link.attr("rel");
		trust_edit_container.hide();		
	}
	
	function handleTrustLevelRemove(event) {
		trust_level_remove.addClass("remove-hidden");
		trust_level_link.html("Click here to assign");
		jQuery.get(config.sceneAjaxURL + domain + command_remove, { 'user_code': user_code }, handleSetResponse);	
		return false;
	}
	
	function handleTrustLevelEdit(event) {		
		link_text = trust_level_link.html();
		if (link_text.indexOf("%") != -1){
			trust_slider.slider("moveTo", parseInt(link_text));
		} else {
			trust_slider.slider("moveTo", 0);
			trust_slider_value.html("Drag red slider to set");
		}
		trust_level_link.hide();
		trust_level_remove.hide();
		trust_edit_container.fadeIn();
		return false;
	}
	
	function handleSliderMove(e, ui) {
		trust_slider_value.html(Math.round(ui.value) + "%");	
	}
	
	function handleSliderChanged(e, ui) {
		value = Math.round(ui.value);
		jQuery.get(config.sceneAjaxURL + domain + command_set, { 'user_code': user_code, 'level': value }, handleSetResponse);	
		trust_level_link.html(value + "%");	
		trust_slider_value.html(value + "%");	
		trust_edit_container.hide();
		trust_level_remove.removeClass("remove-hidden");
		trust_level_remove.show();
		trust_level_link.fadeIn();
	}
	
	function handleSetResponse(data) {
	}
	
	attachEvents();


}

// Help pages

function FAQ(target) {

	function attachEvents() {
		target.find("dt").click(handleQuestionClick);
	}
	
	function handleQuestionClick(event) {
	
		var dd = jQuery(this).next("dd");
		if (dd.is(":visible")) {
			dd.slideUp("fast");
		} else {
			dd.fadeIn();
		}
	
	}
	
	attachEvents();

}

function ContactPage(target) {

	var form;

	function attachEvents() {
		form = target.find("form");
		target.find(".contact-form").click(handleToggleFormClick);
	}
	
	function handleToggleFormClick(event) {
		form.slideToggle();
		return false;
	}
	
	attachEvents();

}

function SearchTopAutoComplete(target) {
	
	function attachEvents() {
		var ac = new AutoComplete(target, "topAutoComplete", callbackTypeGoto);
	}
	
	function callbackTypeGoto(e, item) {
		location.href = item.slug;
	}

	attachEvents();

}

function AutoComplete(target, resultCSS, callback) {
	
	var domain = "/suggest";
	var command  = "/titles";
	
	function format(mail) {
		return "<div class='thumb image-left'><img width='20' height='30' src='" + mail.image + "'></div><span>" + mail.title + "</span>";
	}
	
	function html_entity_decode( string ) {
	    var histogram = {}, histogram_r = {}, code = 0;
	    var entity = chr = '';
	    histogram['34'] = 'quot';
	    histogram['38'] = 'amp';
	    histogram['60'] = 'lt';
	    histogram['62'] = 'gt';
	    histogram['160'] = 'nbsp';
	    histogram['161'] = 'iexcl';
	    histogram['162'] = 'cent';
	    histogram['163'] = 'pound';
	    histogram['164'] = 'curren';
	    histogram['165'] = 'yen';
	    histogram['166'] = 'brvbar';
	    histogram['167'] = 'sect';
	    histogram['168'] = 'uml';
	    histogram['169'] = 'copy';
	    histogram['170'] = 'ordf';
	    histogram['171'] = 'laquo';
	    histogram['172'] = 'not';
	    histogram['173'] = 'shy';
	    histogram['174'] = 'reg';
	    histogram['175'] = 'macr';
	    histogram['176'] = 'deg';
	    histogram['177'] = 'plusmn';
	    histogram['178'] = 'sup2';
	    histogram['179'] = 'sup3';
	    histogram['180'] = 'acute';
	    histogram['181'] = 'micro';
	    histogram['182'] = 'para';
	    histogram['183'] = 'middot';
	    histogram['184'] = 'cedil';
	    histogram['185'] = 'sup1';
	    histogram['186'] = 'ordm';
	    histogram['187'] = 'raquo';
	    histogram['188'] = 'frac14';
	    histogram['189'] = 'frac12';
	    histogram['190'] = 'frac34';
	    histogram['191'] = 'iquest';
	    histogram['192'] = 'Agrave';
	    histogram['193'] = 'Aacute';
	    histogram['194'] = 'Acirc';
	    histogram['195'] = 'Atilde';
	    histogram['196'] = 'Auml';
	    histogram['197'] = 'Aring';
	    histogram['198'] = 'AElig';
	    histogram['199'] = 'Ccedil';
	    histogram['200'] = 'Egrave';
	    histogram['201'] = 'Eacute';
	    histogram['202'] = 'Ecirc';
	    histogram['203'] = 'Euml';
	    histogram['204'] = 'Igrave';
	    histogram['205'] = 'Iacute';
	    histogram['206'] = 'Icirc';
	    histogram['207'] = 'Iuml';
	    histogram['208'] = 'ETH';
	    histogram['209'] = 'Ntilde';
	    histogram['210'] = 'Ograve';
	    histogram['211'] = 'Oacute';
	    histogram['212'] = 'Ocirc';
	    histogram['213'] = 'Otilde';
	    histogram['214'] = 'Ouml';
	    histogram['215'] = 'times';
	    histogram['216'] = 'Oslash';
	    histogram['217'] = 'Ugrave';
	    histogram['218'] = 'Uacute';
	    histogram['219'] = 'Ucirc';
	    histogram['220'] = 'Uuml';
	    histogram['221'] = 'Yacute';
	    histogram['222'] = 'THORN';
	    histogram['223'] = 'szlig';
	    histogram['224'] = 'agrave';
	    histogram['225'] = 'aacute';
	    histogram['226'] = 'acirc';
	    histogram['227'] = 'atilde';
	    histogram['228'] = 'auml';
	    histogram['229'] = 'aring';
	    histogram['230'] = 'aelig';
	    histogram['231'] = 'ccedil';
	    histogram['232'] = 'egrave';
	    histogram['233'] = 'eacute';
	    histogram['234'] = 'ecirc';
	    histogram['235'] = 'euml';
	    histogram['236'] = 'igrave';
	    histogram['237'] = 'iacute';
	    histogram['238'] = 'icirc';
	    histogram['239'] = 'iuml';
	    histogram['240'] = 'eth';
	    histogram['241'] = 'ntilde';
	    histogram['242'] = 'ograve';
	    histogram['243'] = 'oacute';
	    histogram['244'] = 'ocirc';
	    histogram['245'] = 'otilde';
	    histogram['246'] = 'ouml';
	    histogram['247'] = 'divide';
	    histogram['248'] = 'oslash';
	    histogram['249'] = 'ugrave';
	    histogram['250'] = 'uacute';
	    histogram['251'] = 'ucirc';
	    histogram['252'] = 'uuml';
	    histogram['253'] = 'yacute';
	    histogram['254'] = 'thorn';
	    histogram['255'] = 'yuml';

	    for (code in histogram) {
	        entity = histogram[code];
	        histogram_r[entity] = code; 
	    }

	    return string.replace(/(\&([a-zA-Z]+)\;)/g, function(full, m1, m2){
	        if (m2 in histogram_r) {
	            return String.fromCharCode(histogram_r[m2]);
	        } else {
	            return m2;
	        }
	    });
	}

	function attachEvents() {
	
		target.autocomplete(config.sceneAjaxURL + domain + command, {
		selectFirst: false,
		resultsClass: resultCSS,
		parse: function(data) {
			return jQuery.map(eval(data), function(row) {
				return {
					data: row,
					result: html_entity_decode(row.title)
				}
			});
		},formatItem: function(item) { return format(item); }
		}).result(callback);

	}

	attachEvents();

}

/* LISTS */

function ListsEditPage(target, list) {

	var domain = "/lists";
	var command = "/load";
	
	function attachEvents() {
		target.find("a").click(handleLoadLinkClick);
	}
	
	function handleLoadLinkClick(event) {
		target.find("a").removeClass("selected");
		jQuery(this).addClass("selected");
		jQuery(this).addClass("loading");
		var id = jQuery(this).attr("rel");
		jQuery.getJSON(config.sceneAjaxURL + domain + command, { id: id }, handleLoadResponse);	
		return false;
	}
	
	function handleLoadResponse(data) {
		list.jsonToList(data);
		target.find(".loading").removeClass("loading");
	}
	
	attachEvents();

}

function ListsAddPage(target) {

	var id;
	var items;		
	var oldpos;
	var title;
	var title_note;
	var commentbox;
	var basedon;
	var defaultStr = "Type the title of your list in here!";
	var html;
	
	var domain = "/lists";
	var commandSave = "/save";
	var commandLoad = "/load";

	
	function attachEvents() {
	
		if(jQuery.browser.msie) {
			jQuery(".footer").fadeOut(); // ...so sick of dealing with msie.
		}
	
		target.find("ul").sortable({handle: '.arrange', stop: handleSortComplete, start: handleSortStart});
	
		title = jQuery(target.find(".list-title"));
	
		title_note = jQuery(target.find(".comment-box.title textarea"));
		commentbox = target.find(".comment-box.title");
	
		target.find("a.comment-title").click(handleToggleShowComment);
		target.find("a.save").click(handleSave);
		target.find("a.draft").click(handleSaveDraft);
		target.find("a.load-entries").click(handleLoadBasedOnEntries);
	
		title.focus(handleTitleFocus);
		html = target.find("li:first").html();
		initInputs();
		
	}
	
	function handleLoadBasedOnEntries(event) {
		var based = jQuery(this).attr("rel");
		jQuery.getJSON(config.sceneAjaxURL + domain + commandLoad, { id: based, basing: true, orgid: id }, handleLoadEntriesResponse);	
		return false;
	}
	
	function handleLoadEntriesResponse(data) {
		loadFromData(data);
	}
	
	function handleTitleFocus(event) {
		title.removeClass("error");
	}
		
	function handleToggleShowComment(event) {
		var textarea = jQuery(commentbox).find("textarea");
		if (commentbox.is(":visible")) {
			if (textarea.val().length > 0) {
				if (confirm("If you close the note area, the description of your list will be removed. Continue?")) {
					textarea.val('');
					commentbox.fadeOut();
				}
			} else {
				commentbox.fadeOut();		
			}
		} else {
			commentbox.fadeIn();
			textarea.focus();
		}
 		return false;
	}
		
	function initInputs() {
		items = new Array;
		target.find("li").each(function(item) {
			var item = new ListsAddPageRow(jQuery(this));
			item.getdelete().click(handleDeleteRow);
			items.push(item);
		});
		target.find(".add").click(handleAddRow);
	}
	
	function handleDeleteRow(event) {
		if (items.length > 3) {
			var li = jQuery(this).parent("li");
			var index = li.parent().children().index(li);
			removeItemAt(index);
			li.fadeOut(200, function(event){
				jQuery(this).remove()
				relabelNumbers();
			});
		} else {
			alert("Your list needs at least 3 items!");
		}

		$(this).prototip.hide();
		return false;
	}
	
	function addRow(num, removeothers, fade) {
		
		if (removeothers) {
			target.find("li").remove();
			items = new Array();
		}
		
		for (i=0;i<num;i++) {
			target.find("ul").append("<li class='added' style='display: none'>" + html + "</li>");
		}
		
		target.find("li.added").each(function(item) {
			if (fade) {
				jQuery(this).fadeIn();
			} else {
				jQuery(this).show();
			}
			jQuery(this).removeClass('added');
			var item = new ListsAddPageRow(jQuery(this));
			item.getdelete().click(handleDeleteRow);
			item.clear();
			items.push(item);
		});
		
		relabelNumbers();
		initToolTips();
	}
	
	function handleAddRow(event) {
		if (items.length < 50) {	
			addRow(1, false, true);
		} else {
			alert("Your list can have a maximum of 50 items");
		}
		return false;
	}
	
	function handleSortStart(e, ui) {
		oldpos = jQuery(ui.item).parent().children().index(ui.item);
	}
	
	function handleSortComplete(e, ui) {
		var newpos = jQuery(ui.item).parent().children().index(ui.item);
		shiftArrayLeft(oldpos, newpos);
		relabelNumbers();		
	}

	function removeItemAt(index) {
		items.splice(index, 1);
	}

	function shiftArrayLeft(start, end) {
		var tmp = items.splice(start,1);
		items.splice(end, 0, tmp[0]);
	}
	
	function relabelNumbers() {
		for (var i=0;i<items.length;i++) {
			items[i].setorder(i+1);
		}	
	}
	
	function checkMissing() {
	
		var error = false;
	
		if (title.val().length == 0 || title.val() == defaultStr) {
			error = true;
			title.addClass("error");
		}
	
		for (var i=0;i<items.length;i++) {
			if (! items[i].valid()) {
				items[i].setError();
				error = true;
			}
		}
		
		if (error) {
			alert("ERROR:\nThere are field that are missing a value (now shown with a pink border), please correct these or remove the rows if you do not wish to include them.");
		}
	
		return error;
	
	}
	
	function handleSaveDraft(event) {
		if (! checkMissing()) {
			basedon = jQuery(this).attr("rel");
			jQuery(this).addClass("saving");
			params = encode(true);
			jQuery.post(config.sceneAjaxURL + domain + commandSave, params, handleSaveResponse);	
		}
		return false;
	}
	
	function handleSave(event) {
		if (! checkMissing()) {
			jQuery(this).addClass("saving");
			basedon = jQuery(this).attr("rel");
			params = encode(false);
			jQuery.post(config.sceneAjaxURL + domain + commandSave, params, handleSaveResponse);	
		}
		return false;
	}
	
	function encode(draft) {
		var params = new Object();
		params['listsize'] = items.length;
		params['title'] = title.val();
		if (id) {
			params['id'] = id;
		}
		params['note'] = title_note.val();
		if (draft) {
			params['draft'] = true;
		}
		if (basedon) {
			params['basedon'] = basedon;
		}
		for (var i=0;i<items.length;i++) {
			params['items['+i+']'] = items[i].value();
			params['notes['+i+']'] = items[i].note();
		}
		params['commentable'] = target.find("input[name='comments']:checked").val();
		
		return params;
	}
	
	function handleSaveResponse(data) {
		jQuery(".saving").removeClass("saving");
		
		if (! isNaN(data)) { 
			setID(data);
			alert ("Your list has been saved. If you save again, you will overwrite the same list (not create a new list).");
		} else {
			alert ("I'm sorry, but I think something went wrong saving your list. Please try again!");
		}
		return false;
	}
	
	function setTitle(string) {
		title.val(string);
	}
	
	function setNote(string) {
		title_note.val(string);
	}
	
	function setID(num) {
		if (num) {
			id = num;
			var link = target.find(".url a");
			var stem = link.attr("rel");
			link.attr("href", stem+num);
			link.html(stem+num);
			target.find(".url").show();
		} else {
			id = "";
			target.find(".url").hide();
		}
	}
	
	function loadFromData(data) {
		setTitle(data.title);
		setID(data.id);
		if (data.note) {
			setNote(data.note);
			commentbox.show();
		} else {
			setNote('');
			commentbox.hide();
		}
		
		addRow(data.items.length, true, false);
		
		for (i=0;i<data.items.length;i++) {
			items[i].jsonToList(data.items[i]);
		}
		
		target.find("input[value='"+data.commentable+"']").attr("checked", "checked");
		target.slideDown();
	}
	
	attachEvents();
	
	return {
		jsonToList: function (data) { loadFromData(data); }
	}
	
}

function ListsAddPageRow(target) {

	var input;
	var data;
	var order;
	var textarea;
	var commentbox;
	
	function attachEvents() {
		input = target.find("input");
		textarea = jQuery(target.find("textarea"));
		commentbox = target.find(".comment-box");
	
		new AutoComplete(input, "list-add-search", resultAutoComplete);

		target.mouseover(function() {jQuery(this).addClass("hover")});
		target.mouseout(function() {jQuery(this).removeClass("hover")});
		target.find(".edit").click(handleExitEditMode);
		target.find(".comment").click(handleToggleShowComment);
		
		jQuery(input).focus(handleInputFocus);
	}
	
	function handleInputFocus() {
		jQuery(this).removeClass("error");
	}
	
	function resultAutoComplete(e, result) {
		data = result;
		input.fadeOut(200, enterReadyMode);
	}
	
	function setOrderIndicator(number) {
		order = number;
		strnumber = "" + number;
		if (number<10) strnumber = "0" + strnumber;
		target.find(".number").html(strnumber);
	}
	
	function enterReadyMode(event) {
		target.addClass("editable");
		var html = "<div class='completed' style='display: none'><img class='thumb image-left' width='20' height='30' src='" + data.image + "'/><h3 class='titled'>" + data.title + "</h3></div>";
		input.after(html);
		target.find(".completed").fadeIn(200);
		target.next().find("input").focus();
	}
	
	function handleExitEditMode(event) {
		target.removeClass("editable");
		target.find(".completed").fadeOut(200, function(event) { 
			input.fadeIn();
			jQuery(this).remove();
			data = null;
		});
		return false;
	}
	
	function handleToggleShowComment(event) {
		if (commentbox.is(":visible")) {
			if (textarea.val().length > 0) {
				if (confirm("If you close the note area, your note will be deleted. Continue?")) {
					textarea.val('');
					commentbox.fadeOut();
				}
			} else {
				commentbox.fadeOut();		
			}
		} else {
			commentbox.fadeIn();
			textarea.focus();
		}
 		return false;
	}
	
	function clearAll() {
		target.find(".completed").remove();
		commentbox.hide();
		input.show();
		input.val('');
	}
	
	function getNote() {
		return jQuery(textarea).val();
	}
	
	function getValue() {
		if (data) {
			return "ID=" + data.id;
		}
		return jQuery(input).val();
	}
	
	function setTitle(string) {
		jQuery(input).val(string);
	}

	function setNote(string) {
		jQuery(textarea).val(string);
	}
		
	function loadFromData(obj) {
		if (obj.type == "TITLE") {
			data = [];
			data.image 	= obj.title_db.cover;
			data.title 	= obj.title_db.title;
			data.id 	= obj.title_id;
			input.hide();
			setTitle(obj.title_db.title);
			enterReadyMode();
		} else {
			setTitle(obj.title);
			handleExitEditMode();
		}
		
		if (obj.note) {
			commentbox.show();
			setNote(obj.note);
		}
	}
	
	function checkIsValid() {
		return (getValue().length > 0);
	}
	
	function setIsError() {
		jQuery(input).addClass("error");
	}
	
	attachEvents();
	
	return {
		getdata : function() { return data; },
		getinput : function() { return input; },
		getdelete: function() { return target.find(".delete"); },
		setorder: function(i) { setOrderIndicator(i); },
		clear: function() { clearAll(); },
		value: function() { return getValue(); },
		note: function() { return getNote(); },
		jsonToList: function(data) { loadFromData(data); },
		valid: function() { return checkIsValid(); },
		setError: function() { setIsError(); }
	}
}

function ListsIdeas(target) {

	var container;
	
	function attachEvents() {
		target.find(".list-large-ideas").click(handleToggleContainer);
		container = target.find(".list-large-actual-ideas");
	}
	
	function handleToggleContainer() {
		if (container.is(":visible")) {
			container.slideUp();
		} else {
			container.slideDown();
		}
		return false;
	}

	attachEvents();


}
