PaginatorModule={};

//To use dom manipulated paging wrap each page in an element with the class page
//To use custom forward/back buttons add the class page_forward and page_backward to them.
//To use custom positioned control bars add the class control_bar to the element that should contain
//control bar information
Paginator = function(element, options) {
	this.element = YAHOO.util.Dom.get(element);
	//we need an element to do anything
	if (!this.element) {
		return;
	}
	
	this.onPageChange = new YAHOO.util.CustomEvent("onPageChange");
	
	var color = this.deducePaginatorIconColor();
	
	this.img_up = "<img class='color_icon' src='" + Site.coloredImgURL(color) + "/paginator/images/arrow_up.gif'/>";
	this.img_down = "<img class='color_icon' src='" + Site.coloredImgURL(color) + "/paginator/images/arrow_down.gif'/>";
	this.img_left = "<img class='color_icon' src='" + Site.coloredImgURL(color) + "/paginator/images/arrow_left.gif'/>";
	this.img_right = "<img class='color_icon' src='" + Site.coloredImgURL(color) + "/paginator/images/arrow_right.gif'/>";
	this.img_selected_page = "<img class='color_icon' src='" + Site.coloredImgURL(color) + "/core/images/circle_on.gif'/>";
	this.img_unselected_page = "<img class='color_icon' src='" + Site.coloredImgURL(color) + "/core/images/circle_off.gif'/>";

	this.horizontal_paging_buttons_innerhtml = "\
		<a href='javascript:void(0);' class='page_backward'>"+this.img_left+"</a>\
		<a href='javascript:void(0);' class='page_forward'>"+this.img_right+"</a>\
	";
	this.vertical_paging_buttons_innerhtml = "\
		<a href='javascript:void(0);' class='page_forward'>"+this.img_down+"</a>\
		<a href='javascript:void(0);' class='page_backward'>"+this.img_up+"</a>\
	";

	//if the element passed in contains an element with class pages that is the root pages element
	//otherwise element passed in is the pages element
	this.pages = YAHOO.util.Dom.getElementsByClassName("pages", null, this.element);
	if (this.pages.length == 0) {
		this.pages = this.element;
	} else {
		this.pages = this.pages[0];
	}
	
	//apply options to the object to override defaults we have set
	for (var key in options) {
		this[key] = options[key];
	}
	
	this.initializeOrientation();

	//default page size
	if (!this[this.primaryDimension]) {
		this[this.primaryDimension] = this.pages["offset" + this.capitalizedPrimaryDimension];
	}
	
	this.initializeDomPaging(); //if there are elements with class page they will be used to do dom based paging

	this.initializeAjaxPaging(); //if we have options available to load missing pages, setup everything necessary to load them
	
	//If we have a page list then we have already generated where page breaks should occur and
	//we just need to use DOM manipulation to pull pages into place
	if (this.pageList) {
		this.hiddenPages = document.createElement("div");
		this.hiddenPages.style.display = "none";
		document.body.appendChild(this.hiddenPages);
		this.hideExtraPages();
		for(var i = 0; i < this.pageList.length; i++){
			if (this.pageList[i].loaded) {
				this.pageList[i].page.style[this.primaryDimension] = this[this.primaryDimension] + "px";
			}
		}
		// HACK: dirty dirty IE6 hack
		// This will basically disable the animation for sliding between pages.
		// IE6 had a problem rendering the page properly after an animation, thus, hack.
		if (YAHOO.env.ua.ie > 0 && YAHOO.env.ua.ie < 7) {
			this.pages.style[this.primaryDimension] = this[this.primaryDimension] + "px";
		} else {
			this.pages.style[this.primaryDimension] = this[this.primaryDimension]*3 + "px";
		}
		
	} else { //if we don't have a page list then we assume we just have one dom element that we scroll within a frame for paging
		this.initializeSlidePaging();
	}


	//wrap it in a container so we can scroll it and wrap the wrapper in another div so we have a nice root node for everything
	this.pagesRoot = document.createElement("div");
	this.pagesContainer = document.createElement("div");
	this.pagesRoot.appendChild(this.pagesContainer);
	this.pagesContainer.style[this.primaryDimension] = this[this.primaryDimension] + "px";
	this.pagesContainer.style[this.secondaryDimension] = "auto";
	this.pagesContainer.style.overflow = "hidden"; //we handle scrolling through javascript magic so scroll bars would be bad
	this.pages.parentNode.replaceChild(this.pagesRoot, this.pages);
	this.pagesContainer.appendChild(this.pages);
	YAHOO.util.Dom.addClass(this.pagesRoot, "paginator");
	this.pagesRoot.setAttribute('minion_name', this.pagesRoot.getAttribute('minion_name') + " paginator");
	this.pagesRoot.id = "paginator_"+Paginator.nextID++;
	Paginator.paginators[this.pagesRoot.id] = this;
	
	//figure out which is our actual root
	if (YAHOO.util.Dom.isAncestor(this.pagesRoot, this.element)) {
		this.root = this.pagesRoot;
	} else {
		this.root = this.element;
	}
	
	//add paging buttons, page indicators, etc.
	this.addControlBar(this.currentPage);
	this.initializeCustomColors();	
};

Paginator.paginators = {};
Paginator.nextID = 0;

Paginator.CONTROL_BAR_INNERHTML = "";

Paginator.prototype = {
	//properties can be overriden by including them in the options object
	duration: 0.5, //animation duration
	pageTag: null, //type of tag that pages are (if using page hinting)
	orientation: "horizontal", //horizontal or vertical
	primaryDimension: "width", //don't override this
	pageIndicatorStyle: "dots", //dots or numbers
	currentPage: 0, //set this to change the starting page
	ajaxLoadURL: null, //set this to a url to use ajax requests to pull in future pages
	numPages: null, //this value is required with ajaxLoadURL, don't use it otherwise
	queueAnimation: 0, //Number of animations currently in the queue, shouldn't be set manually
	prefetchPages: 0, //Number of pages beyond the currently viewed one that should be loaded when viewing the current one
	pageGrouping: 1, //Number of pages that should be fetched at a time
	ajaxGetParams: [], //Other params to be affixed to the ajaxLoadURL, they should be complete strings excluding ? or & characters, passed in as an array
	
	// If the given page isn't loaded yet get it using the load method for that object
	getPageAt: function(index) {
		for (var i=0; i<this.prefetchPages+1; i++) {
			if (this.pageList[this.currentPage+i] && !this.pageList[this.currentPage+i].loaded) {
				this.pageList[this.currentPage+i].load();
				//assume that if we find one page that we need to load we should stop
				//because loading it should deal with loading enough pages to keep us moving
				break;
			}
		}
		return this.pageList[index].page;
	},
	
	
	hideExtraPages: function() {
		if (this.pageList) {
			for (var i = 0; i < this.pageList.length; i++) {
				if (i != this.currentPage) {
					if (this.pageList[i].loaded) {
						this.hiddenPages.appendChild(this.getPageAt(i));
					}
				}
			}
			if (this.pagesContainer) {
				if (this.orientation == "horizontal") {
					this.pagesContainer.scrollLeft = 0;
				} else {
					this.pagesContainer.scrollTop = 0;
				}
			}
		}
	},
	initializeOrientation: function() {
		//setup dimensions (width or height) these are used to access attributes by key
		//(eg. someElement[this.primaryDimension] to access it's width or height)
		if (this.orientation == "horizontal") {
			this.primaryDimension = "width";
			this.secondaryDimension = "height";
			this.capitalizedPrimaryDimension = "Width";
			this.capitalizedSecondaryDimension = "Height";
		} else {
			this.primaryDimension = "height";
			this.secondaryDimension = "width";
			this.capitalizedPrimaryDimension = "Height";
			this.capitalizedSecondaryDimension = "Width";
		}
	},
	initializeDomPaging: function() {
		var that = this;
		YAHOO.util.Dom.getElementsByClassName("page", this.pageTag, this.pages, function(page) {
			page.style[that.primaryDimension] = that[that.primaryDimension] + "px";

			if (!that.pageList) {
				that.pageList = [];
			}
			that.pageList.push({
				page: page,
				loaded: true,
				load: function(){ alert("Bad!"); }
			});
		});
	},
	initializeAjaxPaging: function() {
		if (this.ajaxLoadURL && this.numPages > 0){
			if (!this.pageList) {
				this.pageList = [];
			}
			var strings = [];
			for (var i = 0; i < (this.numPages); i++){
				if (i != this.currentPage){
					var that = this;
					var div = document.createElement("div");
					div.style[that.primaryDimension]=that[that.primaryDimension] + "px";
					var newPage = {
						index: i,
						load: function(){
							if (that.pageGrouping == 1) {
								new AJAXDiv([this], that.ajaxLoadURL, that.generateGetParams(this.index));
								return div;
							} else {
								var pagesToFetch = [];
								for (var i=0; i<that.pageGrouping; i++) {
									if (that.numPages > this.index+i) {
										pagesToFetch.push(that.pageList[this.index+i]);
										that.pageList[this.index+i].loaded = true;
										that.pageList[this.index+i].load = null;
									}
								}
								new AJAXDiv(pagesToFetch, that.ajaxLoadURL, ["page_list=" + escape(pagesToFetch.join(','))]);
								return this.page;
							}
						},
						loaded: false,
						page: div,
						toString: function() {return this.index.toString();}
					};
					if (i < this.currentPage) {
						this.pageList.unshift(newPage);
					} else {
						this.pageList.push(newPage);
					}
				}
			}
		} 
	},
	generateGetParams: function(pageNum)
	{
		var temp_arr = [];
		for(var i=0; i < this.ajaxGetParams.length; i++)
		{
			temp_arr.push(this.ajaxGetParams[i]);
		}
		temp_arr.push("page="+pageNum);
		
		return temp_arr;
	},
	reinitializeSlidePaging: function() {
		this.initializeSlidePaging();
		this.correctSlideForCurrentPage();
		this.updateControlBar();
	},
	correctSlideForCurrentPage: function() {
		if (this.orientation == "horizontal") {
			this.pagesContainer.scrollLeft = this.currentPage * this.width;
		} else {
			this.pagesContainer.scrollTop = this.currentPage * this.height;
		}
	},
	initializeSlidePaging: function() {
		//figure out how many pages worth of width we need to add to bring ourselves to be the right height
		if (this.orientation == "horizontal") {
			this.totalLength = this.width;
			this.pages.style.width = this.width + "px";
			var previousHeight = this.pages.offsetHeight;
			var repetition = false;
			while (this.pages.offsetHeight > this.height) {
				this.totalLength *= 2;
				this.pages.style.width = this.totalLength + "px";
				//avoid infinite loops
				if (previousHeight == this.pages.offsetHeight) {
					if (repetition) {
						break;
					}
					repetition = true;
				} else {
					repetition = false;
				}
				previousHeight = this.pages.offsetHeight;
			}
			while (this.height >= this.pages.offsetHeight && this.totalLength >= this.width) {
				this.totalLength -= this.width;
				this.pages.style.width = this.totalLength + "px";
			}
			this.totalLength += this.width;
			this.pages.style.width = this.totalLength + "px";
		} else { //vertical length calculation
			var originalPosition = this.pages.style.position;
			this.pages.style.position = "absolute";
			this.totalLength = this.pages.offsetHeight;
			this.pages.style.position = originalPosition;
		}
	},
	initializeCustomColors: function() {
		// elements = YAHOO.util.Dom.getElementsByClassName("custom_color_icon", null, this.root);
		// init_custom_color_icons(elements);
	},
	registerPageButtons: function(){
		//register hooks to any button
		var that = this;
		YAHOO.util.Dom.getElementsByClassName("page_forward", null, this.root, function(element) {
			YAHOO.util.Event.on(element, "click", function(event) {
				YAHOO.util.Event.preventDefault(event);
				this.pageForward();
			}, that, true);
		});
		YAHOO.util.Dom.getElementsByClassName("page_backward", null,  this.root, function(element) {
			YAHOO.util.Event.on(element, "click", function(event) {
				YAHOO.util.Event.preventDefault(event);
				this.pageBackward();
			}, that, true);
		});
	},
	//Adds a control bar, if you have any subelements of the root element that have class control_bar
	//they will be used, otherwise a new element will be created
	addControlBar: function(currentPage) {
		var controlBars = YAHOO.util.Dom.getElementsByClassName("control_bar", null, this.root);
		var controlBar = null;
		if (controlBars.length == 0) {
			//legacy implementation of how to specify control bars, takes top, top and bottom, or defaults to just bottom
			if (this.controls == "top" || this.controls == "top and bottom"){
				controlBar = document.createElement("div");
				YAHOO.util.Dom.addClass(controlBar, "control_bar");
				controlBar.innerHTML = Paginator.CONTROL_BAR_INNERHTML;
				controlBars.push(controlBar);
				this.pagesContainer.parentNode.insertBefore(controlBar, this.pagesContainer);
			}
			if (this.controls != "top") {
				controlBar = document.createElement("div");
				YAHOO.util.Dom.addClass(controlBar, "control_bar");
				controlBar.innerHTML = Paginator.CONTROL_BAR_INNERHTML;
				this.insertAfter(controlBar, this.pagesContainer);
				controlBars.push(controlBar);
			}
		}
		for (var i=0; i<controlBars.length; i++) {
			controlBar = controlBars[i];
			this.addPagingButtons(controlBar);
			this.addPageIndicator(controlBar, currentPage);

		}
		this.registerPageButtons();
	},
	addPageIndicator: function(controlBar, index) {
		var pageIndicator = document.createElement("div");
		YAHOO.util.Dom.addClass(pageIndicator, "page_list");
		controlBar.appendChild(pageIndicator);
		
		switch (this.pageIndicatorStyle) {
			case "numbers":
				this.addNumbersPageIndicator(pageIndicator, index);
				break;
			case "dots":
				this.addDotsPageIndicator(pageIndicator, index);
				break;
			default:
		}
	},
	//The default page indicator, uses dots to indicate number of pages and current page
	addDotsPageIndicator: function(pageIndicator, index) {
		for (var i=0; i<this.numberOfPages(); i++) {
			if (i == index){
				pageIndicator.appendChild(this.createNode(this.img_selected_page));
			} else {
				pageIndicator.appendChild(this.createNode(this.img_unselected_page));
			}
		}
	},
	//Voodoo that adds numbers as a page indicator, see Thomas if you need to understand it
	addNumbersPageIndicator: function(pageIndicator, index) {
		var list = {};
		list[1] = true;
		list[2] = true;
		list[index] = true;
		list[index + 1] = true;
		list[index + 2] = true;
		var end = this.numberOfPages();
		list[end - 1] = true;
		list[end] = true;
		var last_i = 0;
		for (var i in list) {
			i = parseInt(i, 10);
			if (i > 0 && i <= end){
				if (i != (last_i + 1)) {
					pageIndicator.appendChild(this.createNode("..."));
				}
				last_i = i;
					
				if (i == (index + 1)){
					pageIndicator.appendChild(this.createNode("<span class='selected'>" + (i) + " </span>"));
				} else {
					pageIndicator.appendChild(this.createNode("<a href='#'>" + (i) + " </a>"));
				}
			}
		}
	},
	//Adds paging buttons to the control bar, if you pass pagingButtons through options it will be used rather than creating a new one
	addPagingButtons: function(controlBar) {
		//add buttons if they aren't already on the page and we have multiple pages
		if (this.numberOfPages() > 1 && 
				!YAHOO.util.Dom.getElementsByClassName("page_backward", null, this.element).length > 0 && 
				!YAHOO.util.Dom.getElementsByClassName("page_forward", null, this.element).length > 0) {
			var pagingButtons = document.createElement("div");
			YAHOO.util.Dom.addClass(pagingButtons, "paging_buttons");
			if (this.orientation == "horizontal") {
				pagingButtons.innerHTML = this.horizontal_paging_buttons_innerhtml;
			} else {
				pagingButtons.innerHTML = this.vertical_paging_buttons_innerhtml;
			}
			controlBar.insertBefore(pagingButtons, controlBar.firstChild);
			
		}

	},
	showStrikeZones: function() {
		if (this.numberOfPages() > 1) {
			this.addStrikeZoneLeft();
			this.addStrikeZoneRight();
		}
	},
	hideStrikeZones: function() {
		if (this.strikeZoneLeft && this.strikeZoneLeft.parentNode) {
			this.strikeZoneLeft.parentNode.removeChild(this.strikeZoneLeft);
		}
		if (this.strikeZoneRight && this.strikeZoneRight.parentNode) {
			this.strikeZoneRight.parentNode.removeChild(this.strikeZoneRight);
		}
	},
	addStrikeZoneLeft: function() {
		var strike = this.strikeZoneLeft;
		if (!strike) {
			strike = this.createStrikeZone();
		}
		strike.firstChild.style.left = "-14px";
		YAHOO.util.Dom.addClass(strike.firstChild, "strike_zone_left");
		this.pagesContainer.parentNode.insertBefore(strike, this.pagesContainer);
		YAHOO.util.Event.on(strike.firstChild, "mouseover", this.pageBackward, this, true);
		YAHOO.util.Dom.addClass(strike.firstChild, "left");
		this.strikeZoneLeft = strike;
	},
	addStrikeZoneRight: function() {
		var strike = this.strikeZoneRight;
		if (!strike) {
			strike = this.createStrikeZone();
		}
		strike.firstChild.style.left = this.width-4+"px";
		YAHOO.util.Dom.addClass(strike.firstChild, "strike_zone_right");
		this.pagesContainer.parentNode.insertBefore(strike, this.pagesContainer);
		YAHOO.util.Event.on(strike.firstChild, "mouseover", this.pageForward, this, true);
		YAHOO.util.Dom.addClass(strike.firstChild, "right");
		this.strikeZoneRight = strike;
	},
	createStrikeZone: function() {
		var strike = document.createElement("div");
		strike.style.position = "absolute";
		var strike2 = document.createElement("div");
		strike2.style.height = this.height + "px";
		strike2.style.width = "20px";
		strike2.style.position = "relative";
		strike2.style.zIndex = "1000";
		var dd = new YAHOO.util.DDTarget(strike2);
		strike.appendChild(strike2);
		return strike;
	},
	addNextPage: function() {
		if (this.pageList) {
			var current = this.getPageAt(this.currentPage);
			var next = this.getPageAt(this.nextPage());
			this.insertAfter(next, current);
		}
	},
	nextPage: function() {
		return (this.currentPage+1)%this.numberOfPages();
	},
	addPreviousPage: function() {
		if (this.pageList) {
			this.getPageAt(this.currentPage).parentNode.insertBefore(this.getPageAt(this.previousPage()), this.getPageAt(this.currentPage));
			if (this.orientation == "horizontal") {
				this.pagesContainer.scrollLeft = this.width;
			} else {
				this.pagesContainer.scrollTop = this.height;
			}
		}
	},
	previousPage: function() {
		return (this.numberOfPages()+this.currentPage-1)%this.numberOfPages();
	},
	pageForward: function(event, callback) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		if (this.currentPage == this.numberOfPages()-1) {
			return; //don't wrap
		}
		this.normalPageForward(callback);
	},
	normalPageForward: function(event, callback) {
		var oldCurrentPage = this.currentPage;
		//if we're already moving instantly finish it so we don't screw up positioning
		//XXX: ACTUALLY if we're already moving just return and make them wait because firefox 3 is fucking up.
		//This needs a better solution but this prevents major breakage until we get one
		if (this.currentAnimation) {
			if (!callback) {
				this.queueAnimation++;
			}
			return;
			// this.currentAnimation.stop(true);
		}
		if (this.pageList) {
			this.addNextPage();
		}
		if (this.orientation == "horizontal") {
			this.currentAnimation = new YAHOO.util.Scroll(this.pagesContainer, { scroll: { by: [this.width, 0] } }, this.duration);
		} else {
			this.currentAnimation = new YAHOO.util.Scroll(this.pagesContainer, { scroll: { by: [0, this.height] } }, this.duration);
		}
		this.currentAnimation.onComplete.subscribe(this.finishAnimation, this, true);
		if (this.beforePageCallback) {
			this.beforePageCallback();
		}
		if (callback) {
			this.currentAnimation.onComplete.subscribe(callback);
		}
		if (this.afterPageCallback) {
			this.currentAnimation.onComplete.subscribe(this.afterPageCallback, this, true);
		}
				
		this.currentAnimation.animate();
		this.currentPage = this.nextPage();
		this.updateControlBar();
		
		this.onPageChange.fire({page: this.currentPage, previousPage: oldCurrentPage});
	},
	pageBackward: function(event, callback) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		if (this.currentPage == 0) {
			return; //don't wrap
		}
		this.normalPageBackward(callback);
	},
	normalPageBackward: function(callback) {
		var oldCurrentPage = this.currentPage;
		//if we're already moving instantly finish it so we don't screw up positioning
		//XXX: ACTUALLY if we're already moving just return and make them wait because firefox 3 is fucking up.
		//This needs a better solution but this prevents major breakage until we get one
		if (this.currentAnimation) {
			if (!callback) {
				this.queueAnimation--;
			}
			return;
			// this.currentAnimation.stop(true);
		}

		if (this.pageList) {
			this.addPreviousPage();
		}
		if (this.orientation == "horizontal") {
			this.currentAnimation = new YAHOO.util.Scroll(this.pagesContainer, { scroll: { by: [-this.width, 0] } }, this.duration);
		} else {
			this.currentAnimation = new YAHOO.util.Scroll(this.pagesContainer, { scroll: { by: [0, -this.height] } }, this.duration);
		}
		this.currentAnimation.onComplete.subscribe(this.finishAnimation, this, true);
		if (this.beforePageCallback) {
			this.beforePageCallback();
		}
		if (callback) {
			this.currentAnimation.onComplete.subscribe(callback);
		}
		if (this.afterPageCallback) {
			this.currentAnimation.onComplete.subscribe(this.afterPageCallback, this, true);
		}
		this.currentAnimation.animate();
		this.currentPage = this.previousPage();
		this.updateControlBar();
		
		this.onPageChange.fire({page: this.currentPage, previousPage: oldCurrentPage});
	},
	
	// Update the little dots at the bottom of the page that tell us what page we're on.
	updateControlBar: function(page) {
		if (!page) {
			page = this.currentPage;
		}
		var that = this;
		YAHOO.util.Dom.getElementsByClassName("control_bar", "div", this.root, function(element) {
			YAHOO.util.Dom.getElementsByClassName("page_list", "div", element, function(child){
				child.parentNode.removeChild(child);
			});
			that.addPageIndicator(element, page);
		});	
		this.initializeCustomColors();
	},
	finishAnimation: function() {
		this.hideExtraPages();
		this.currentAnimation = null;
		if (this.queueAnimation > 0) {
			this.queueAnimation--;
			this.pageForward();
		} else if (this.queueAnimation < 0) {
			this.queueAnimation++;
			this.pageBackward();
		}
		this.initializeCustomColors();
	},
	currentAnimation: null,
	numberOfPages: function() {
		if (this.pageList) {
			return this.pageList.length;
		} else {
			return this.totalLength/this[this.primaryDimension];
		}
	},
	//Returns the DOM node for a given page, used primarily by things outside of paginator that need to modify offscreen pages
	//Returns null if pages aren't broken up into their own dom elements.
	getPage: function(pageNumber) {
		if (this.pageList) {
			return this.pageList[pageNumber];
		} else {
			return null;
		}
	},
	//this behavior should be extracted somewhere
	//does the same as node.insertBefore except inserts after
	insertAfter: function(newChild, oldChild) {
		if (oldChild.nextSibling) {
			oldChild.parentNode.insertBefore(newChild, oldChild.nextSibling);
		} else {
			oldChild.parentNode.appendChild(newChild);
		}
	},
	createNode: function(inner) {
		var temp = document.createElement("temp");
		temp.innerHTML = inner;
		return temp.firstChild;
	},
	deducePaginatorIconColor: function()
	{
		// Build the fake hierarchy of elements down to the paginator icon
		var paginatorElement = document.createElement("div");
		paginatorElement.className = "paginator";
		var controlBarElement = document.createElement("div");
		controlBarElement.className = "control_bar";
		var pagingButtonsElement = document.createElement("div");
		pagingButtonsElement.className = "paging_buttons";
		var aElement = document.createElement("a");
		var imgElement = document.createElement("img");
		imgElement.className = "color_icon";

		aElement.appendChild(imgElement);
		pagingButtonsElement.appendChild(aElement);
		controlBarElement.appendChild(pagingButtonsElement);
		paginatorElement.appendChild(controlBarElement);
		
		// Append the fake hierarchy to the main element
		this.element.appendChild(paginatorElement);
		
		// Get the color of the fake image element
		var color = YAHOO.util.Dom.getStyle(imgElement, "color");
		
		// Remove the fake hierarchy
		this.element.removeChild(paginatorElement);
		
		// Return the color
		return color;	
	}
};

AJAXDiv = function(pages, url, args){
	this.contentURL = url;
	this.pages = pages;
	this.args = args;
	this.elements = [];
	for (var i=0; i<this.pages.length;i++) {
		this.elements.push(this.pages[i].page);
	}
	
	//TODO: More robust and general purpose spinner code
	if (Nexopia && Nexopia.JSONData) {
		this.spinner = document.createElement("div");
		this.spinner.innerHTML = "<img class='script' id='spinner' src='" + Site.staticFilesURL + "/nexoskel/images/spinner.gif" + "'/>";
		this.elements[0].appendChild(this.spinner);
	}
	this.load();
	
};

AJAXDiv.prototype = {
	load: function() {
		YAHOO.util.Connect.asyncRequest('GET', this.contentURL + "?" + this.args.join("&"), {
			success: function(o) {
				if (this.spinner) {
					this.elements[0].removeChild(this.spinner);
				}
				var temp = document.createElement("temp");
				temp.innerHTML = o.responseText;
				var children = [];
				//we're going to remove nodes so we need to copy the array first
				for (var i = 0; i < temp.childNodes.length; i++) {
					children.push(temp.childNodes[i]);
				}
				
				// children will probably have nodes that we don't care about.
				// Only append those with nodeType 1 to the elements array.
				for (i = 0, j = 0; j < this.elements.length; i++) {
					if (children[i].nodeType != 1) { //Node.ELEMENT_NODE (ie6 doesn't have this constant)
						continue;
					}
					this.elements[j].appendChild(children[i]);
					this.pages[j].loaded = true;
					j++; //do this here rather than in the loop declaration so that continues don't increment
				}
				Overlord.summonMinions(this.elements);
			},
			failure: function(o) {
			},
			scope: this
		});
	}
};

Overlord.assign({
	minion: "paginator",
	unload: function(element) {
		delete Paginator.paginators[element.id];
	}
});
TruncatorModule={};

Truncator = function(element, options) {
	if (options) {
		YAHOO.lang.augmentObject(this, options, true);
	}
	
	this.element = YAHOO.util.Dom.get(element);

	this.shortenedText = this.element.innerHTML;
	this.originalText = this.element.innerHTML;
	this.words = this.originalText.split(/\s/);
	
	if (!this.width) {
		this.width = this.element.offsetWidth;
	}
	if (!this.height) {
		this.height = this.element.offsetHeight;
	}
	
	this.truncate();
};

Truncator.prototype = {
	tooltip: true, //add a tooltip with the original text content
	expandable: false, //the content can be expanded by clicking on it
	collapsible: false, //the expanded content can be collapsed by clicking on it
	suffix: "...", //what should be added to the end of truncated text
	expandedSuffix: "", //if there should be a suffix on the expanded text this is it
	fixed_length: -1, // if we want truncator to be fast and immediately cut to a given size use this option.
	
	toggleExpanded: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		if (this.collapsed) {
			this.expand();
		} else if (this.collapsible) {
			this.collapse();
		}
	},
	expand: function() {
		this.element.innerHTML = this.originalText + this.expandedSuffix;
		this.collapsed = false;
	},
	collapse: function() {
		this.element.innerHTML = this.shortenedText;
		this.collapsed = true;
	},
	//private - don't overwrite this stuff in options
	truncate: function() {
		var originalVisibility = this.element.style.visibility;
		var originalPosition = this.element.style.position;
		var originalDisplay = this.element.style.display;
		var originalWidth = this.element.style.width;
		var originalHeight = this.element.style.height;
		var originalOverflow = this.element.style.overflow;

		YAHOO.util.Dom.setStyle(this.element, 'visibility', 'hidden');
		YAHOO.util.Dom.setStyle(this.element, 'position', 'absolute');
		YAHOO.util.Dom.setStyle(this.element, 'display', 'block');
		YAHOO.util.Dom.setStyle(this.element, 'width', this.width + "px");
		YAHOO.util.Dom.setStyle(this.element, 'height', this.height + "px");
		YAHOO.util.Dom.setStyle(this.element, 'overflow', 'auto');

		// if we're not dealing with a fixed length we'll do this dynamically.
		if (this.fixed_length == -1) {
			while (this.shortenedText.length > this.suffix.length && 
					(this.element.clientWidth < this.element.scrollWidth || this.element.clientHeight < this.element.scrollHeight)) {
				this.shorten();
			}
		} else {
			this.quick_shorten();
		}

		YAHOO.util.Dom.setStyle(this.element, 'visibility', originalVisibility);
		YAHOO.util.Dom.setStyle(this.element, 'position', originalPosition);
		YAHOO.util.Dom.setStyle(this.element, 'display', originalDisplay);
		YAHOO.util.Dom.setStyle(this.element, 'width', originalWidth);
		YAHOO.util.Dom.setStyle(this.element, 'height', originalHeight);
		YAHOO.util.Dom.setStyle(this.element, 'overflow', originalOverflow);
		if (this.shortened) {
			if (this.tooltip) {
				this.addTooltip();
			}
			if (this.expandable) {
				this.makeExpandable();
			}
		}
	},

	quick_shorten: function() {
		if (this.shortenedText.length > this.fixed_length) {
			this.shortened = true;
			this.shortenedText = this.shortenedText.substr(0,this.fixed_length);

			this.shortenedText = this.shortenedText.replace(/[\s\,\.\?\:]+$/,"");
			this.shortenedText += this.suffix;
			this.element.innerHTML = this.shortenedText;
		}
	},

	shorten: function() {
		this.shortened = true;
		if (this.words.length > 1) {
			this.shortenedText = this.shortenedText.substr(0, this.shortenedText.lastIndexOf(this.words.pop().replace(/[\s\,\.\?\:]+$/,"")));
		} else {
			if (this.shortenedText.lastIndexOf(this.suffix) > 0) {
				this.shortenedText = this.shortenedText.substr(0,this.shortenedText.lastIndexOf(this.suffix)-1);
			} else {
				this.shortenedText = this.shortenedText.substr(0,this.shortenedText.length-1);
			}
		}
		this.shortenedText = this.shortenedText.replace(/[\s\,\.\?\:]+$/,"");
		this.shortenedText += this.suffix;
		this.element.innerHTML = this.shortenedText;
	},
	addTooltip: function() {
		new YAHOO.widget.Tooltip(document.createElement("div"), {
			text: this.originalText,
			context: this.element,
			width: this.width + "px"
		});
	},
	makeExpandable: function() {
		YAHOO.util.Event.on(this.element, 'click', this.toggleExpanded, this, true);
	},
	shortened: false,
	collapsed: true
};
FlashDetectModule={};

// http://www.featureblend.com/license.txt
YAHOO.util.FlashDetect=new function(){var self=this;self.installed=false;self.raw="";self.major=-1;self.minor=-1;self.revision=-1;self.revisionStr="";var activeXDetectRules=[{"name":"ShockwaveFlash.ShockwaveFlash.7","version":function(obj){return getActiveXVersion(obj);}},{"name":"ShockwaveFlash.ShockwaveFlash.6","version":function(obj){var version="6,0,21";try{obj.AllowScriptAccess="always";version=getActiveXVersion(obj);}catch(err){}
return version;}},{"name":"ShockwaveFlash.ShockwaveFlash","version":function(obj){return getActiveXVersion(obj);}}];var getActiveXVersion=function(activeXObj){var version=-1;try{version=activeXObj.GetVariable("$version");}catch(err){}
return version;};var getActiveXObject=function(name){var obj=-1;try{obj=new ActiveXObject(name);}catch(err){}
return obj;};var parseActiveXVersion=function(str){var versionArray=str.split(",");return{"raw":str,"major":parseInt(versionArray[0].split(" ")[1],10),"minor":parseInt(versionArray[1],10),"revision":parseInt(versionArray[2],10),"revisionStr":versionArray[2]};};var parseStandardVersion=function(str){var descParts=str.split(/ +/);var majorMinor=descParts[2].split(/\./);var revisionStr=descParts[3];return{"raw":str,"major":parseInt(majorMinor[0],10),"minor":parseInt(majorMinor[1],10),"revisionStr":revisionStr,"revision":parseRevisionStrToInt(revisionStr)};};var parseRevisionStrToInt=function(str){return parseInt(str.replace(/[a-zA-Z]/g,""),10)||self.revision;};self.majorAtLeast=function(version){return self.major>=version;};self.FlashDetect=function(){if(navigator.plugins&&navigator.plugins.length>0){var type='application/x-shockwave-flash';var mimeTypes=navigator.mimeTypes;if(mimeTypes&&mimeTypes[type]&&mimeTypes[type].enabledPlugin&&mimeTypes[type].enabledPlugin.description){var version=mimeTypes[type].enabledPlugin.description;var versionObj=parseStandardVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revisionStr=versionObj.revisionStr;self.revision=versionObj.revision;self.installed=true;}}else if(navigator.appVersion.indexOf("Mac")==-1&&window.execScript){var version=-1;for(var i=0;i<activeXDetectRules.length&&version==-1;i++){var obj=getActiveXObject(activeXDetectRules[i].name);if(typeof obj=="object"){self.installed=true;version=activeXDetectRules[i].version(obj);if(version!=-1){var versionObj=parseActiveXVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revision=versionObj.revision;self.revisionStr=versionObj.revisionStr;}}}}}();};YAHOO.util.FlashDetect.release="1.0.3";
GalleryModule={};

Overlord.assign({
	minion: "gallery_abuse_section",
	load: function(element) {
	
		YAHOO.util.Event.on("submit_abuse_log", "click", function(event){
			if (event) {
				YAHOO.util.Event.preventDefault(event);
			}
	
			var form = YAHOO.util.Dom.get("abuse_log_form");
			YAHOO.util.Connect.setForm(form);
			YAHOO.util.Connect.asyncRequest('POST', form.gallery_abuse_url.value, new ResponseHandler({
				success: function(o) {
					YAHOO.util.Dom.get("abuse_log_entry").value = "";
					YAHOO.util.Dom.get("abuse_log_subject").value = "";
				},
				failure: function(o) {
				}
			}));
		});
	}	
});
GallerySelect = {
	classicUploader : false,
	init: function() {
		if (!this.initialized) {
			this.initialized = true;
			YAHOO.util.Event.on("selected_gallery", "click", function(e) {GallerySelect.updateDisplay(e);});
			YAHOO.util.Event.on("create_gallery", "click", function(e) {
				YAHOO.util.Event.preventDefault(e);
				GallerySelect.updateDisplay(e);
				if (this.innerHTML == "CREATE GALLERY") {
					this.innerHTML = "CANCEL";
				} else {
					this.innerHTML = "CREATE GALLERY";
				}
			});
			YAHOO.util.Event.on("cancel_link", "click", function(e) {GallerySelect.cancelCreate(e);});
			galleryCreateSubmit = YAHOO.util.Dom.get("gallery_create_submit");
			galleryOverlay = YAHOO.util.Dom.get("gallery_overlay");
			if (galleryCreateSubmit && galleryOverlay && YAHOO.util.Dom.isAncestor(galleryOverlay, galleryCreateSubmit)) {
				YAHOO.util.Event.on("gallery_create_submit", 'click', function(e) {
					YAHOO.util.Event.preventDefault(e);
					GallerySelect.submitNewGallery(this);
				});
			}
			this.updateDisplay();
		}
		if(!YAHOO.util.Event.getListeners("selected_gallery", "click"))
		{
			YAHOO.util.Event.on("selected_gallery", "click", function(e) {GallerySelect.updateDisplay(e);});
		}
	},
	reinit: function() {
		if (GalleryManagement && GalleryManagement.initialized) {
			GalleryManagement.updateOptions();
		}
		this.init();
	},
	updateDisplay: function(e) {
		var clicked = false;
		if (e) {
			var clicked = YAHOO.util.Event.getTarget(e).innerHTML;
		}
		var selectedGallery = document.getElementById("selected_gallery");
		if ((selectedGallery && selectedGallery.value == 0) || clicked == "CREATE GALLERY") {
			this.showOverlay(e);
		} else {
			this.hideOverlay(e);
		}
	},
	showOverlay: function(e) {
		var overlay = document.getElementById("gallery_overlay");
		YAHOO.util.Dom.setStyle(overlay, "display", "block");
		if(this.classicUploader) { 
			YAHOO.util.Event.addListener(document.getElementById('file_upload'), "click", ProfilePictureUploader.disabled);
		} else {
			YAHOO.util.Dom.setStyle('uploader_overlay', "display", "none");
		}
	},
	cancelCreate: function(e) {
		YAHOO.util.Event.preventDefault(e);
		this.hideOverlay(e);
		var selectedGallery = document.getElementById("selected_gallery");
		
		// if there's a gallery selector box reset it to the default
		if (selectedGallery) {
			selectedGallery.options[0].selected=true;
		}

	}, 
	hideOverlay: function(e) {
		document.getElementById("gallery_overlay").style.display = "none";
		if(this.classicUploader) { 
			YAHOO.util.Event.removeListener(document.getElementById('file_upload'), "click", ProfilePictureUploader.disabled);
		} else {
			YAHOO.util.Dom.setStyle('uploader_overlay', "display", "block");
		}
	},
	submitNewGallery: function(e) {
		if (document.getElementById("gallery_create_submit").value == "Creating...") {
			return false; //we're already submitting don't do anything else.
		}
		var overlay = document.getElementById("gallery_overlay");
		var form = YAHOO.util.Dom.getAncestorByTagName(document.getElementById("gallery_create_submit"), "form");
		document.getElementById("gallery_create_submit").value = "Creating...";
		YAHOO.util.Connect.setForm(form);
		this.callback.argument = e;
		YAHOO.util.Connect.asyncRequest('POST', Nexopia.areaBaseURI() + '/gallery/ajax_create', new ResponseHandler(this.callback), "refresh=create_album_popup");
		return false;
	},
	callback: {
		success: function(o) {
			var overlay_create = document.getElementById("gallery_create_submit");
			if (overlay_create) {
				overlay_create.value = "Create Gallery";
			}
			var main_create = document.getElementById("create_gallery");
			if (main_create) {
				main_create.innerHTML = "CREATE GALLERY";
			}
			GallerySelect.updateDisplay();
			GallerySelect.reinit();
			GalleryManagement.move_to();
		},
		failure: function(o) {
			document.getElementById("gallery_overlay").style.display = "none";
			document.getElementById("gallery_create_submit").value = "Create Gallery";
			var newGalleryOption = document.getElementById("new_gallery");
			newGalleryOption.parentNode.removeChild(newGalleryOption);
			var div = document.createElement("div");
			div.innerHTML = "Unable to create gallery dynamically, use the <a class=\"body\" href=\"/my/gallery/create\">gallery creation page</a> to create a new gallery.";
			document.getElementById("selected_gallery").parentNode.appendChild(div);
		},
		timeout: 5000,
		newNode: function(node) {
			if (node.id) {
				var match = node.id.match(/^gallery_folder_(\d+)$/);
				if (match) {
					var albumRow = YAHOO.util.Dom.get("album_row");
					if (albumRow) {
						var li = document.createElement("li");
						li.id = match[1];
						albumRow.appendChild(li);
						li.appendChild(node);
						var paginatorEl = YAHOO.util.Dom.getAncestorByClassName(albumRow, 'paginator');
						if (paginatorEl) {
							var paginator = Paginator.paginators[paginatorEl.id];
							paginator.reinitializeSlidePaging();
						}
					}
				}
			}
		},
		argument: []
	}
};

Overlord.assign({
	minion: "gallery_creation",
	load: GallerySelect.init,
	scope: GallerySelect	
});
//require select.js

var ProfilePictureUploader = {
	flashUploader: null,
	init: function() {
		this.uploadQueue = [];
		if (this.hasSuitableFlashVersion()) {
			YAHOO.widget.Uploader.SWFURL = Site.staticFilesURL + "/gallery/flash/uploader.swf";
			this.flashUploader = new YAHOO.widget.Uploader("uploader_overlay", Site.staticFilesURL + "/gallery/images/choose_picture_button.gif");

			var overlay = document.getElementById('uploader_overlay');
			var button = document.getElementById('choose_picture');
						
			YAHOO.util.Dom.setStyle(overlay, 'top', button.offsetTop + "px");
			YAHOO.util.Dom.setStyle(overlay, 'left', button.offsetLeft + "px");
			
			YAHOO.util.Dom.setStyle(overlay, 'width', YAHOO.util.Dom.getStyle(button, 'width'));
			YAHOO.util.Dom.setStyle(overlay, 'height', YAHOO.util.Dom.getStyle(button, 'height'));
			
			this.flashUploader.addListener('contentReady', this.configUploader, this, true);
			this.flashUploader.addListener('fileSelect', this.startUpload, this, true);
			this.flashUploader.addListener('uploadCompleteData', this.uploadComplete, this, true);
			
		} else {
			this.activateClassicUploader();
		}
	},
	configUploader: function() {
		this.flashUploader.setFileFilters(["*.jpeg;*.jpg;*.png;*.gif;*.bmp"], "Picture Files");
	},
	//minimum version is 9.0.45
	hasSuitableFlashVersion: function() {
		if (YAHOO.util.FlashDetect.major > 9) {
			return true;
		} else if (YAHOO.util.FlashDetect.major == 9) {
			if (YAHOO.util.FlashDetect.minor > 0 || YAHOO.util.FlashDetect.revision >= 45) {
				return true;
			}
		}
		return false;
	},
	activateClassicUploader: function() {
		// Do this to prevent the user from switiching back to the flash uploader and creating errors
		document.getElementById('alternate_instructions').innerHTML = "";
		YAHOO.util.Dom.setStyle('uploader_overlay', 'display', "none");
		YAHOO.util.Dom.setStyle('choose_picture', 'display', "none");
		YAHOO.util.Dom.setStyle('file_upload', 'display', "inline");
		YAHOO.util.Dom.setStyle('classic_file_upload', 'display', "block");
		if(GallerySelect) {
			GallerySelect.classicUploader = true;
		}
	},
	startUpload: function(event) {
		this.showSpinner();
		this.flashUploader.uploadAll(document.getElementById("swf_upload_path").value, 'POST', {
			type: "Userpics",
			description: "",
			session: YAHOO.util.Dom.get('session').value,
			selected_gallery: YAHOO.util.Dom.get('selected_gallery').value
		});
	},
	uploadComplete: function(event) {

		var success = false;
		r = new ResponseHandler({});
		var serverData = event.data;
		if (serverData.indexOf("Success") == 0) {
			serverData = serverData.slice(0,8);
			success = true;
		}

		r.handleResponse({responseText: serverData});
		NexopiaPanel.current.close();
		
		if (success) {
			EditPicturePanel.init('first', 'profile_picture');
			YAHOO.util.Connect.asyncRequest('POST', Nexopia.areaBaseURI() + '/pictures/refresh', new ResponseHandler({}));
		}
		
	},
	showSpinner: function() {
		YAHOO.util.Dom.setStyle('uploader_overlay', 'width', "1px"); 
		YAHOO.util.Dom.setStyle('uploader_overlay', 'height', "1px"); 
		
		YAHOO.util.Dom.setStyle('add_profile_pic_form', 'visibility', 'hidden');
		YAHOO.util.Dom.setStyle('add_profile_pic', 'background-image', 'url('+Site.staticFilesURL + '/nexoskel/images/spinner.gif)');
		YAHOO.util.Dom.setStyle('add_profile_pic', 'background-position', 'center center');
		YAHOO.util.Dom.setStyle('add_profile_pic', 'background-repeat', 'no-repeat');
	},
	disabled: function(e) {
		// Block the event, e.g. because we're in the middle of creating an album.  Display a message?
		YAHOO.util.Event.preventDefault(e);
	}
};

Overlord.assign({
	minion: "add_profile_pic", 
	load: ProfilePictureUploader.init,
	scope: ProfilePictureUploader
});

// Toggle the "advanced" section of the profile pic uploader to be open or closed.
Overlord.assign({
	minion: "add_profile_pic:advanced_link",
	click: function() {
		var advanced_content = YAHOO.util.Dom.get("advanced_content");
		var display_state = YAHOO.util.Dom.getStyle(advanced_content, "display");
		var up_arrow = YAHOO.util.Dom.get("up_arrow");
		var down_arrow = YAHOO.util.Dom.get("down_arrow");
		
		// If we're not currently showing the advanced box show it.
		if (display_state.toLowerCase() == "none") {
			YAHOO.util.Dom.setStyle(advanced_content, "display", "block");
			YAHOO.util.Dom.setStyle(up_arrow, "display", "inline");
			YAHOO.util.Dom.setStyle(down_arrow, "display", "none");
		} else {
			YAHOO.util.Dom.setStyle(advanced_content, "display", "none");			
			YAHOO.util.Dom.setStyle(up_arrow, "display", "none");
			YAHOO.util.Dom.setStyle(down_arrow, "display", "inline");
		}
	}
	
});

Overlord.assign({
	minion: "add_profile_pic:cancel_link",
	click: function(){
		NexopiaPanel.current.close();
	}
});

Overlord.assign({
	minion: "add_profile_pic:classic_interface",
	click: function(event){
		YAHOO.util.Event.preventDefault(event);
		ProfilePictureUploader.activateClassicUploader();
	}
});
GalleryManagement = {
	initialized: false,
	init: function() {
		if (!this.initialized) {
			this.initialized = true;
		}
		var galleryid = document.getElementById("galleryid");
		if (galleryid) {
			this.galleryid = galleryid.value;
		}
		
		// find all elements under the element with id 'action_bar' 
		// that have both an element name that has "function" in it 
		// and have an id that matches a function name somewhere in GalleryManagement
		var actions = YAHOO.util.Dom.getElementsBy(function(element) {
			return (/^function/.test(element.name) && GalleryManagement[element.id]);
		}, "", document.getElementById("action_bar"));
		
		// For each element that has an action associated with it add an 'onclick' listener to it.
		for (var i=0;i<actions.length;i++) {
			YAHOO.util.Event.addListener(actions[i], "click", function(event) {
				YAHOO.util.Event.preventDefault(event);
				GalleryManagement[this.id]();
			});
		}
		YAHOO.util.Event.on("selected_gallery", "change", this.move_to, this, true);
		this.updateOptions();
		this.initialized = true;
	},
	reinit: function() {
		if (this.initialized) { //don't reinitialize if we were never initialized to begin with
			this.galleries = {};
			this.init();
			if (GallerySelect) {
				GallerySelect.init();
			}
		}
	},
	album_cover: function() {
		var id = this.getSelected()[0];
		this.startSpinner();
		YAHOO.util.Connect.setForm("gallery_form");
		YAHOO.util.Connect.asyncRequest('POST', Nexopia.JSONData['areaBaseUri'] + '/gallery/album_cover', new ResponseHandler({
			success: function(o) {
				this.unselectAll();
				GalleryManagement.stopSpinner();
			},
			scope: this
		}), "galleryid=" + this.galleryid + "&id="+id);
	},
	make_profile_pic: function() {
		var id = this.getSelected()[0];
		this.startSpinner();
		YAHOO.util.Connect.setForm("gallery_form");
		YAHOO.util.Connect.asyncRequest('POST', Nexopia.JSONData['areaBaseUri'] + '/gallery/make_profile_pic', new ResponseHandler({
			success: function(o) {
				this.unselectAll();
				GalleryManagement.stopSpinner();
			},
			failure: function(o) {
				this.unselectAll();
				GalleryManagement.stopSpinner();
			},
			scope: this
		}), "id="+id);
		
	},
	remove: function() {
		if (confirm("Are you sure you want to delete the selected photo(s)?\nThis action cannot be undone.")) {
			var ids = this.getSelected().join(',');
			this.startSpinner();
			YAHOO.util.Connect.setForm("gallery_form");
			YAHOO.util.Connect.asyncRequest('POST', Nexopia.JSONData['areaBaseUri'] + '/gallery/delete_group', new ResponseHandler({
				success: function(o, argument) {
					var selected = this.getSelected();
					for (var i=0;i<selected.length; i++) {
						this.images[selected[i]].remove();
					}
					this.unselectAll();
					GalleryManagement.stopSpinner();
				},
				scope: this
			}), "ids=" + ids);
		}
	},
	deleteGallery: function(deleteLink) {
		if (confirm("Are you sure you want to delete this album?\nThis will permanently delete all photos within the album.")) {
			this.startSpinner();
			YAHOO.util.Connect.asyncRequest('POST', deleteLink.href, new ResponseHandler({
				success: function(o) {
					var id = GalleryManagement.parseID(this.id);
					var galleryid = document.getElementById("galleryid");
					if (galleryid) {
						galleryid = galleryid.value;
					} else {
						galleryid = 0;
					}
					if (galleryid == id) {
						var galleryBody = document.getElementById("gallery_information");
						galleryBody.parentNode.removeChild(galleryBody);
					}
					var gallery = document.getElementById("gallery_"+id);
					GalleryManagement.stopSpinner();
					gallery.parentNode.removeChild(gallery);
				},
				failure: function(o) {
				},
				scope: deleteLink
			}), "form_key[]=" + SecureForm.getFormKey());
		}
	},
	edit_description: function(descriptionElement) {
		var id = this.parseID(descriptionElement.id);
		this.images[id].edit();
	},
	save_description: function(descriptionElement) {
		var id = this.parseID(descriptionElement.id);
		this.images[id].save();
	},
	move_to: function() {
		var idArray = this.getSelected();
		var ids = idArray.join(',');
		var targetGallery = document.getElementById("selected_gallery").value;
		var currentGallery = document.getElementById("galleryid").value;
		if (targetGallery != currentGallery && targetGallery > 0) {
			this.startSpinner();
			YAHOO.util.Connect.setForm("gallery_form");
			YAHOO.util.Connect.asyncRequest('POST', Nexopia.JSONData['areaBaseUri'] + '/gallery/change_gallery', new ResponseHandler({
				success: function(o) {
					var selected = o.argument;
					for (var i=0;i<selected.length; i++) {
						this.images[selected[i]].remove();
					}
					this.unselectAll();
					this.updateOptions();
					var selectElement = document.getElementById("selected_gallery");
					var currentGallery = document.getElementById("galleryid").value;
					for (var i=0; i<selectElement.options.length; i++) {
						if (selectElement.options[i].value == currentGallery) {
							selectElement.options[i].selected = "selected";
							break;
						}
					}
					GalleryManagement.stopSpinner();
				},
				failure: function(o) {
					GalleryManagement.stopSpinner();
				},
				scope: this,
				argument: idArray
			}),	"ids=" + ids + "&targetgallery=" + targetGallery + "&galleryid=" + document.getElementById("galleryid").value);
		}
	},
	delete_pic: function(deleteLink, id) {
		//if the delete link is an element we pull the data from it, otherwise we assume the proper link and id were passed in
		if (deleteLink.href) {
			id = this.parseID(deleteLink.id);
			deleteLink = deleteLink.href;
		}
		if (confirm("Delete picture?")) {
			this.startSpinner();
			YAHOO.util.Connect.setForm("gallery_form");
			YAHOO.util.Connect.asyncRequest('POST', deleteLink, new ResponseHandler({
				success: function(o) {
					this.remove();
					this.unselectAll();
					GalleryManagement.stopSpinner();
				},
				failure: function(o) {
				},
				scope: this.images[id]
			}), "void=void");
			return true;
		}
		return false;
	},
	select: function(checkBoxElement) {
		this.updateOptions();
	},
	parseID: function(id_string) {
		return id_string.match(/\[(\w+)\]/)[1];
	},
	images: {},
	galleries: {},
	updateOptions: function() {
		var count = this.countSelected();
		var album_cover = document.getElementById("album_cover");
		var profile_pic = document.getElementById("profile_pic");
		var remove = document.getElementById("remove");
		var move_to = document.getElementById("move_to");
		var move_to_select = document.getElementById("selected_gallery");
		//TODO: make the profile pic count based upon the number of currently available profile pic slots.
		
		if (count == 1) {
			if (album_cover) album_cover.disabled = "";
		} else {
			if (album_cover) album_cover.disabled = "disabled";
		}
		if (count >= 1) {
			if (remove) remove.disabled = "";
			if (move_to_select) move_to_select.disabled = "";
		} else {
			if (remove) remove.disabled = "disabled";
			if (move_to_select) move_to_select.disabled = "disabled";
		}
	},
	countSelected: function() {
		var count = 0;
		for (var imageid in this.images) {
			if (this.images[imageid].isSelected()) {
				count++;
			}
		}
		return count;
	},
	selectAll: function(event) {
		for (var imageid in this.images) {
			this.images[imageid].select();
		}
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		this.updateOptions();
	},
	unselectAll: function(event) {
		for (var imageid in this.images) {
			this.images[imageid].unselect();
		}
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		this.updateOptions();
	},
	getSelected: function() {
		var selected = new Array();
		for (var imageid in this.images) {
			if (this.images[imageid].isSelected()) {
				selected.push(imageid);
			}
		}
		return selected;
	},
	startSpinner: function() {
		if (EditGallery) {
			EditGallery.startSpinner();
		}
	},
	stopSpinner: function() {
		if (EditGallery) {
			EditGallery.stopSpinner();
		}
	},
	columns: 6
};

//Setup all of the GalleryImage objects on the page, delete them when they are removed
Overlord.assign({
	minion: "gallery:pic_checkbox",
	load: function(element) {
		var image = new GalleryImage(element);
		if (image && image.node) {
			element.galleryImageID = image.id;
			GalleryManagement.images[image.id] = image;
		}
	},
	unload: function(element) {
		delete GalleryManagement.images[element.galleryImageID];
	},
	order: -1 // need to run 'load' before paginator splits the pages otherwise it doesn't happen for images on pages after the first.

});

Overlord.assign({
	minion: "gallery_management",
	load: GalleryManagement.init,
	scope: GalleryManagement	
});

Overlord.assign({
	minion: "gallery_management:select_all",
	click: GalleryManagement.selectAll,
	scope: GalleryManagement
});
Overlord.assign({
	minion: "gallery_management:select_none",
	click: GalleryManagement.unselectAll,
	scope: GalleryManagement
});

//require gallery_management.js
GalleryManagement.AlbumInfo = {
	summaryElement: null, //.details .summary
	editElement: null, //.details .edit
	spinnerElement: null, //.details .edit .spinner
	edit: function() {
		this.editClone = this.editElement.cloneNode(true);
		this.editElement.style.display = "block";
		this.summaryElement.style.display = "none";
	},
	cancel: function() {
		this.summaryElement.style.display = "block";
		this.editElement.parentNode.replaceChild(this.editClone, this.editElement);
		this.editElement = this.editClone;
		Overlord.summonMinions(this.editElement);
	},
	//finish saving, show spinner, etc...
	save: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		this.spinnerElement.style.display = "inline";
		var form = this.editElement.getElementsByTagName("form")[0];
		var new_title = form.elements[0].value.replace(/^(\s|&nbsp;|&#160;)*|(\s|&nbsp;|&#160;)*$/,"");
		var description = document.getElementById('gallery_description');
		if (description.innerHTML == "Enter description here...") {
			description.innerHTML = "";
		}
		if(new_title == "") {
			alert("Galleries cannot have empty titles.");
			this.spinnerElement.style.display = "none";
		} else {
			YAHOO.util.Connect.setForm(form);
			YAHOO.util.Connect.asyncRequest("POST", Nexopia.areaBaseURI() +"/gallery/update/"+Nexopia.json(this.editElement).id, new ResponseHandler({}), "refresh=album_info");
		}
	}
};

Overlord.assign({
	minion: "album_info:show_edit_album",
	click: GalleryManagement.AlbumInfo.edit,
	scope: GalleryManagement.AlbumInfo
});

Overlord.assign({
	minion: "album_info:cancel_edit",
	click: GalleryManagement.AlbumInfo.cancel,
	scope: GalleryManagement.AlbumInfo
});

Overlord.assign({
	minion: "album_info:edit",
	load: function(element) {
		GalleryManagement.AlbumInfo.editElement = element;
	}
});

Overlord.assign({
	minion: "album_info:spinner",
	load: function(element) {
		GalleryManagement.AlbumInfo.spinnerElement = element;
	}
});

Overlord.assign({
	minion: "album_info:summary",
	load: function(element) {
		GalleryManagement.AlbumInfo.summaryElement = element;
	}
});

Overlord.assign({
	minion: "album_info:save",
	click: GalleryManagement.AlbumInfo.save,
	scope: GalleryManagement.AlbumInfo
});

Overlord.assign({
	minion: "album_info:description_edit",
	load: function(element) {
		if (element.innerHTML == "") {
			element.innerHTML = "Enter description here...";
		}
	},
	click: function(event, element) {
		if (element.innerHTML == "Enter description here...") {
			element.innerHTML = "";
		}
	}
});

Overlord.assign({
	minion: "album_info:description",
	load: function(element) {
		new Truncator(element);
	}
});

CreateAlbum = {
	
	validateGalleryName: function() {
		valid = false;
		var gallery_name = YAHOO.util.Dom.get("gallery_name");
		if (gallery_name.value == "")
		{
			alert("Please enter a gallery name.");
		} else {
			valid = true;
		}
		return valid;
	}
	
};

Overlord.assign({
	minion: "album_create:continue",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);

		if ( CreateAlbum.validateGalleryName() ) {
		
			// Set a spinner while we're creating the gallery
			var spinner = YAHOO.util.Dom.get("spinner");
			YAHOO.util.Dom.setStyle(element, "display", "none");
			YAHOO.util.Dom.setStyle(spinner, "display", "inline");
			
			// Ajax submit the form
			var create_gallery_form = YAHOO.util.Dom.get("create_album_form");
			create_gallery_form.submit();
		}
		
	}
	
});
EditGallery  = {
	init: function () {
		this.galleryName = YAHOO.util.Dom.get("gallery_name");
		this.galleryNameInput = YAHOO.util.Dom.get("gallery_name_input");
		this.galleryDescription = YAHOO.util.Dom.get("gallery_description");
		this.galleryDescriptionInput = YAHOO.util.Dom.get("gallery_description_input");
		this.galleryPermissions = YAHOO.util.Dom.get("current_gallery_permission");
		this.galleryPermissionsSelect = YAHOO.util.Dom.get("gallery_permission_select");
		this.form = YAHOO.util.Dom.get("edit_gallery_form");
		this.root = YAHOO.util.Dom.get("edit_gallery");
		YAHOO.util.Event.on(this.galleryName, "click", this.editName, this, true);
		YAHOO.util.Event.on(this.galleryNameInput, "blur", this.scheduleSave, this, true);
		YAHOO.util.Event.on(this.galleryNameInput, "keypress", this.checkKeys, this, true);
		YAHOO.util.Event.on(this.galleryDescription, "click", this.editDescription, this, true);
		YAHOO.util.Event.on(this.galleryDescriptionInput, "blur", this.scheduleSave, this, true);
		YAHOO.util.Event.on(this.galleryDescriptionInput, "keypress", this.checkKeys, this, true);
		YAHOO.util.Event.on(this.galleryPermissions, "click", this.editPermissions, this, true);
		YAHOO.util.Event.on(this.galleryPermissionsSelect, "change", this.scheduleSave, this, true);
		YAHOO.util.Event.on(this.galleryPermissionsSelect, "blur", this.scheduleSave, this, true);
		YAHOO.util.Event.on(this.galleryPermissionsSelect, "keypress", this.checkKeys, this, true);
		YAHOO.util.Event.on(document.getElementsByTagName("body")[0], "click", this.considerSaving, this, true);
	},
	saveOnClick: false,
	reinit: function() {
		this.init();
	},
	editName: function() {
		this.cancelSave();
		this.galleryName.tabIndex=2;
		this.galleryName.style.display = "none";
		this.galleryNameInput.parentNode.style.display = "block";
		this.galleryNameInput.focus();
		this.galleryNameInput.select();
	},
	editDescription: function() {
		this.cancelSave();
		this.galleryDescription.style.display = "none";
		this.galleryDescriptionInput.parentNode.style.display = "block";
		this.galleryDescriptionInput.focus();
		this.galleryDescriptionInput.select();
	},
	editPermissions: function() {
		this.galleryPermissions.style.display = "none";
		this.galleryPermissionsSelect.style.display = "block";
		this.galleryPermissionsSelect.focus();
	},
	checkKeys: function(event) {
		switch (YAHOO.util.Event.getCharCode(event)) {
			case 13: //enter
				this.save();
				YAHOO.util.Event.preventDefault(event);
				break;
			case 27: //escape
				this.cancel();
				YAHOO.util.Event.preventDefault(event);
				break;
		}
	},
	scheduleSave: function() {
		this.saveOnClick = true;
	},
	considerSaving: function() {
		if (this.saveOnClick) {
			this.save();
		}
	},
	cancel: function() {
		this.galleryName.style.display = "block";
		this.galleryNameInput.parentNode.style.display = "none";
		this.galleryNameInput.blur();
		this.galleryDescription.style.display = "block";
		this.galleryDescriptionInput.parentNode.style.display = "none";
		this.galleryDescriptionInput.blur();
		this.galleryPermissions.style.display = "block";
		this.galleryPermissionsSelect.style.display = "none";
		this.galleryPermissionsSelect.blur();
		this.cancelSave();
	},
	cancelSave: function() {
		this.saveOnClick = false;
	},
	save: function() {
		YAHOO.util.Connect.setForm(this.form);
		this.startSpinner();
		YAHOO.util.Connect.asyncRequest('POST', this.form.attributes.action.value, new ResponseHandler({
			success: function(o) {
				if (GalleryManagement) {
					GalleryManagement.reinit();
				}
				this.stopSpinner();
			},
			failure: function(o) {
				
			},
			scope: this
		}), "ajax=true");
		this.cancelSave();
	},
	startSpinner: function() {
		var spinner = YAHOO.util.Dom.get("edit_gallery_spinner");
		if (spinner) {
			spinner.style.display = "block";
		}
	},
	stopSpinner: function() {
		var spinner = YAHOO.util.Dom.get("edit_gallery_spinner");
		if (spinner) {
			spinner.style.display = "none";
		}
	}
};

Overlord.assign({
	minion: "edit_gallery",
	load: EditGallery.init,
	scope: EditGallery
});
EditPicturePanel = {
	form_key: null,
	description: null,
	smallSpinner: null,
	spinnerBody: "<div id='edit_picture_panel' class='spinner'><img src='"+Site.staticFilesURL+"/nexoskel/images/large_spinner.gif'/></div>",
	baseURI: Nexopia.areaBaseURI(), 
	init: function(galleryPicID, functionPanel, config) {
		if(config) {
			YAHOO.lang.augmentObject(this, config, true);
		}
		this.galleryPicID = galleryPicID;
		this.functionPanel = functionPanel;
		this.overlay = new YAHOO.widget.Panel("picture_edit_overlay", {
			fixedcenter: false,
			visible: true,
			modal:true,
			close:false,
			draggable:false,
			underlay: "none"
		});
		this.overlay.setBody(this.spinnerBody);
		this.overlay.render(document.body);
		
		// For some reason, the minified version of container doesn't seem to be able to set the zIndex properly,
		// so we are doing that again after the panel has been initialized.
		this.overlay.cfg.setProperty("zIndex", 500);

		// Fix for a problem in Firefox 2 where the panel won't show.
		if(YAHOO.env.ua.gecko < 1.9)
		{
			YAHOO.util.Dom.setStyle(this.overlay.innerElement, 'position', 'relative');
		}
				
		this.overlay.center();
		YAHOO.util.Connect.asyncRequest('GET', this.baseURI + '/gallery/pic/' + this.galleryPicID + '/edit?function_panel='+this.functionPanel, new ResponseHandler({
			success: function(o) {
				this.overlay.element = this.overlay.element.firstChild; //XXX: This should not be necessary but the original element reports an offsetWidth/Height of 0 in FF3
				if (this.galleryPicID == "first") {
					this.galleryPicID = Nexopia.json(document.getElementById('edit_picture_panel'));
					var thumbnail = YAHOO.util.Dom.get('profile_picture_thumbnail');
					if (thumbnail) {
						var userID = Nexopia.json(thumbnail);
						thumbnail.src = Site.imageURL + "/gallerylandscapethumb/" + (Math.round(Math.random()*9000)+1000) + "/" + userID + "/" + this.galleryPicID + '.jpg';
					}
				}
				this.overlay.center();
			},
			failure: function(o) {
				this.overlay.destroy();
			},
			scope: this
		}));
	},
	initImageCrop: function(img) {
		var imgCrop = Nexopia.json(img);
		var cropperConfig = null;
		if (imgCrop) {
			cropperConfig = {
				ratio: true,
				initWidth: Math.round(imgCrop.w*img.width),
				initHeight: Math.round(imgCrop.h*img.height),
				initialXY: [Math.round(imgCrop.x*img.width), Math.round(imgCrop.y*img.height)],
				status: false
			};
		} else {
			var imgRatio = img.width/img.height;
			if (imgRatio < 1.2) {
				cropperConfig = {
					ratio: true,
					initWidth: img.width,
					initHeight: img.width/1.2,
					initialXY: [0, (img.height-(img.width/1.2))/2],
					status: false
				};
			} else {
				cropperConfig = {
					ratio: true,
					initHeight: img.height,
					initWidth: img.height*1.2,
					initialXY: [(img.width-(img.height*1.2))/2, 0],
					status: false
				};
			}
		}
		this.cropper = new YAHOO.widget.ImageCropper(img, cropperConfig);
	},
	saveImageCrop: function() {
		rawCoords = this.cropper.getCropCoords();
		var width = parseInt(this.cropper.getEl().width, 10);
		var height = parseInt(this.cropper.getEl().height, 10);

		var w = rawCoords.width/width;
		var x = rawCoords.left/width;
		var h = rawCoords.width/1.2/height; //we don't really believe the image cropper preserved 
											//the proper ratio so we'll just take height based on width.
											//If it actually did get it right they should be the same anyhow.
		var y = rawCoords.top/height;
		y = Math.min(y, 1-h); //make sure our fudging hasn't put the total height more than 1

		this.overlay.setBody(this.spinnerBody);
		this.overlay.center();
		YAHOO.util.Connect.asyncRequest('POST', this.baseURI + "/gallery/pic/"+this.galleryPicID+"/crop", new ResponseHandler({
			success: function() {
				var that = this;
				YAHOO.util.Dom.getElementsBy(function(element) {
					var elementsrc;
					var qindex = element.src.lastIndexOf("?reload=");
					if(qindex == -1) {
						elementsrc = element.src;
					} else {
						elementsrc = element.src.substring(0,qindex);
					}
					return (elementsrc.lastIndexOf(that.galleryPicID) == elementsrc.length - (that.galleryPicID.toString().length + 4));
				}, 'img', null, function(element) {
					element.src = element.src + "?reload=" + Math.random();
				});
				this.overlay.destroy();
			},
			failure: function() {
				this.overlay.destroy();
			},
			scope: this
		}), "form_key[]="+this.form_key+"&x="+x+"&y="+y+"&w="+w+"&h="+h);
	},
	makeSignPic: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		this.showSpinner();
		YAHOO.util.Connect.asyncRequest('POST', this.baseURI + "/gallery/pic/"+this.galleryPicID+"/sign", new ResponseHandler({
			success: function() {
				this.stopSpinner();
			},
			failure: function() {
				this.stopSpinner();
			},
			scope: this
		}), "form_key[]="+this.form_key);
	},
	makeAlbumCover: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		this.showSpinner();
		YAHOO.util.Connect.asyncRequest('POST', this.baseURI + "/gallery/pic/"+this.galleryPicID+"/album_cover", new ResponseHandler({
			success: function() {
				this.stopSpinner();
			},
			failure: function() {
				this.stopSpinner();
			},
			scope: this
		}), "form_key[]="+this.form_key+"&refresh=album_info");
	},
	makeProfilePicture: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		this.showSpinner();
		YAHOO.util.Connect.asyncRequest('POST', this.baseURI + "/gallery/pic/"+this.galleryPicID+"/profile_picture", new ResponseHandler({
			success: function() {
				this.stopSpinner();
			},
			failure: function() {
				this.stopSpinner();
			},
			scope: this
		}), "form_key[]="+this.form_key);
	},
	deletePicture: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		if (!confirm("Are you sure you want to delete the selected photo?\nThis action cannot be undone.")) {
			return;
		}
		this.overlay.setBody(this.spinnerBody);
		this.overlay.center();
		YAHOO.util.Connect.asyncRequest('POST', this.baseURI + "/gallery/pic/"+this.galleryPicID+"/delete?source=film_view", new ResponseHandler({
			success: function() {
				this.overlay.destroy();
			},
			failure: function() {
				this.overlay.destroy();
			},
			scope: this
		}), "form_key[]="+this.form_key+"&refresh=gallery");
	},
	saveDescription: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		YAHOO.util.Connect.asyncRequest('POST', this.baseURI + "/gallery/pic/"+this.galleryPicID+"/description", new ResponseHandler({
			success: function() {
				this.stopSpinner();
			},
			failure: function() {
				this.stopSpinner();
			},
			scope: this
		}), "form_key[]="+this.form_key+"&description="+Nexopia.Utilities.escapeURI(this.description.value));
	},
	showSpinner: function() {
		if (this.smallSpinner) {
			YAHOO.util.Dom.setStyle(this.smallSpinner, 'display', 'inline');
		}
	},
	stopSpinner: function() {
		if (this.smallSpinner) {
			YAHOO.util.Dom.setStyle(this.smallSpinner, 'display', 'none');
		}
	}
};

//If you click done, close the panel.
Overlord.assign({
	minion: "edit_picture:done",
	click: EditPicturePanel.saveImageCrop,
	scope: EditPicturePanel
});

//Setup the click handler for the sign pic link
Overlord.assign({
	minion: "edit_picture:signpic",
	click: EditPicturePanel.makeSignPic,
	scope: EditPicturePanel
});

Overlord.assign({
	minion: "edit_picture:album_cover",
	click: EditPicturePanel.makeAlbumCover,
	scope: EditPicturePanel
});

Overlord.assign({
	minion: "edit_picture:profile_picture",
	click: EditPicturePanel.makeProfilePicture,
	scope: EditPicturePanel
});

Overlord.assign({
	minion: "edit_picture:delete",
	click: EditPicturePanel.deletePicture,
	scope: EditPicturePanel
});


//Once the image has loaded, center the overlay and load the image cropper
Overlord.assign({
	minion: "edit_picture:image",
	load: function(element) {
		Nexopia.Utilities.withImage(element, {
			load: function(img) {
				EditPicturePanel.overlay.center();
				EditPicturePanel.initImageCrop(img);
			}
		});
	}
});

Overlord.assign({
	minion: "edit_picture:form_key",
	load: function(el) {
		EditPicturePanel.form_key = el.value;
	}
});

Overlord.assign({
	minion: "edit_picture:spinner",
	load: function(el) {
		EditPicturePanel.smallSpinner = el;
	}
});


Overlord.assign({
	minion: "edit_picture:description",
	load: function(element) {
		EditPicturePanel.description = element;
		if (element.innerHTML == "") {
			element.innerHTML = "Enter description here...";
		}
	},
	click: function(event, element) {
		if (element.innerHTML == "Enter description here...") {
			element.innerHTML = "";
		}
	},
	blur: EditPicturePanel.saveDescription,
	scope: EditPicturePanel
});

EditPicturePanel.EditLink = function(linkElement) {
	this.linkElement = linkElement;
	this.pictureID = Nexopia.json(linkElement)[0];
	this.functionPanel = Nexopia.json(linkElement)[1];
};

EditPicturePanel.EditLink.prototype = {
	edit: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		EditPicturePanel.init(this.pictureID, this.functionPanel);
	}
};

Overlord.assign({
	minion: "edit_picture:edit_link",
	load: function(element) {
		var edit_link = new EditPicturePanel.EditLink(element);
		YAHOO.util.Event.on(element, 'click', edit_link.edit, null, edit_link);
	}
});

UserGallery = {
	init: function() {
		this.tabs = new YAHOO.widget.TabView('user_gallery');
		YAHOO.util.Event.on('film_view_link', 'click', function(event) {this.blur();});
		YAHOO.util.Event.on('thumb_view_link', 'click', function(event) {this.blur();});
	},
	//returns [userid, id] based on an image path
	parsePath: function(path) {
		var match = path.match(/\/gallery\w*\/\d+\/(\d+)-*[^\/]*\/(\d+)-*[^\/]*\./);
		
		return [match[1],match[2]];
	}
};

Overlord.assign({
	minion: "user_gallery",
	load: UserGallery.init,
	scope: UserGallery
});
//require user_gallery.js
UserGallery.FilmView = {
	COMMENT_CACHE_TIME: 300000, //time in milliseconds to client-side cache comments blocks for
	COMMENT_DELAY: 250,
	init_film_view: function(element) {
		//use the paginator to setup paging for the gallery filmstrip, doesn't do
		//dom paging, just slides one long element in a window element
		this.filmStripPaginator = new Paginator("gallery_film_strip", {
			width: 702,
			height: 80
		});
		this.fullLink = YAHOO.util.Dom.get("full_view");
		this.shareLink = YAHOO.util.Dom.get("share_link");
		this.imageDescription = YAHOO.util.Dom.get("image_description");
		this.reportAbuseLink = YAHOO.util.Dom.get("report_abuse");
		
		var currentPicsElement = document.getElementById("current_profile_pics");
		if (currentPicsElement && currentPicsElement.value != "")
		{
			this.currentProfilePics = document.getElementById("current_profile_pics").value.split(",");
		}
		else
		{
			this.currentProfilePics = [];
		}
		this.makeProfilePictureLink();
	},
	//change the main picture to the next thumbnail picture, wraps at the end
	next: function(event) {
		YAHOO.util.Event.preventDefault(event);
		YAHOO.util.Event.getTarget(event).blur();
		for (var i=0; i<this.thumbs.length; i++) {
			if (this.thumbs[i].id == this.currentPicture.pictureID) {
				this.thumbs[(i+1)%this.thumbs.length].makeCurrent();
				break;
			}
		}
		this.preloadImages(0,5);
	},
	//change the main picture to the previous thumbnail picture, wraps at the beginning
	previous: function(event) {
		YAHOO.util.Event.preventDefault(event);
		YAHOO.util.Event.getTarget(event).blur();
		for (var i=0; i<this.thumbs.length; i++) {
			if (this.thumbs[i].id == this.currentPicture.pictureID) {
				if (i-1 < 0) {
					this.thumbs[this.thumbs.length-1].makeCurrent();
				} else {
					this.thumbs[i-1].makeCurrent();
				}
				break;
			}
		}
		this.preloadImages(5,0);
	},
	//preload the specified number of images before and after the current image
	preloadImages: function(backward, forward) {
		for (var i=0; i<this.thumbs.length; i++) {
			if (this.thumbs[i].id == this.currentPicture.pictureID) {
				var currentThumb = i;
			}
		}
		for (i=1; i<=forward; i++) {
			var index = (currentThumb+i)%this.thumbs.length;
			this.getImage(this.thumbs[index]);
		}
		for (i=1; i<=backward; i++) {
			index = currentThumb - i;
			if (index < 0) {
				index = this.thumbs.length + index;
			}
			this.getImage(this.thumbs[index]);
		}
	},
	getImage: function(thumb) {
		if (!thumb.picture) {
			thumb.picture = new Image();
			thumb.picture.src = thumb.normal_link;
			thumb.picture.id = "current_picture";
		}
		return thumb.picture;
	},
	//list of Thumb objects in the order they appear on the page
	thumbs: [],
	//wrapper for adding to the thumbs array
	registerThumb: function(thumb) {
		this.thumbs.push(thumb);
	},
	//remove by thumb id from the thumbs array
	unregisterThumb: function(thumbID) {
		for (var i=0; i<this.thumbs.length; i++) {
			if (this.thumbs[i].id == thumbID) {
				this.thumbs.splice(i,1); //delete the element from the array
			}
		}
	},
	getThumb: function(thumbID) {
		for (var i = 0; i < this.thumbs.length; i++) {
			if (this.thumbs[i].id == thumbID) {
				return this.thumbs[i];
			}
		}
	},
	//wrapper for set current used by normal view
	setCurrentById: function(thumbID) {
		var thumb = this.getThumb(thumbID);
		this.setCurrent(thumb);
		UserGallery.tabs.set("activeIndex", 0, false);
	},
	//set the main image based on a Thumb object
	setCurrent: function(thumb) {
		this.getImage(thumb);
		this.currentPicture.setPicture(thumb.picture);
		YAHOO.util.Dom.getElementsByClassName("current", "img", "gallery_film_strip", function(element) {
			YAHOO.util.Dom.removeClass(element, "current");
		});
		YAHOO.util.Dom.addClass(thumb.img, "current");
		YAHOO.util.Dom.get("current_index").innerHTML = thumb.getIndex();
		this.updateFullPath(thumb);
		this.updateSharePath(thumb);
		this.updateReportAbusePath(thumb);
		this.imageDescription.innerHTML = thumb.description;
		this.loadComments(thumb);
		
		this.makeProfilePictureLink();
	},
	makeProfilePictureLink: function() {
		if(this.currentPicIsProfilePic())
		{
			YAHOO.util.Dom.setStyle("make_profile_picture", "display", "none");
		}
		else
		{
			YAHOO.util.Dom.setStyle("make_profile_picture", "display", "inline");
		}
	},
	updateFullPath: function(thumb) {
		this.fullLink.href = thumb.full_link;
	},
	updateSharePath: function(thumb) {
		// Remove all previous listeners
		YAHOO.util.Event.removeListener(this.shareLink, 'click');		
		
		// Update the link
		this.shareLink.id = "share_link";
		this.shareLink.href = thumb.share_link;
		this.shareLink.attributes["path"].value = thumb.share_link;
		
		// Build a new share panel
		var panel = new AsyncPanel( { path: this.shareLink.attributes["path"].value } );
		NexopiaPanel.linkMap[this.shareLink.id] = panel;
		
		// Set it to open upon clicking the share link
		YAHOO.util.Event.on(this.shareLink, 'click', panel.open, panel, true);
	},
	updateReportAbusePath: function(thumb) {
		this.reportAbuseLink.href = Site.wwwURL + "/reportabuse.php?type=22&uid="+thumb.userid+"&id=" + thumb.id;
	},
	//update the current comments section
	loadComments: function(thumb) {
		var container = YAHOO.util.Dom.get("gallery_comments_block");
		//comments container only exists on logged in page views
		if (container) {
			if (thumb.container && thumb.container.loaded && thumb.container.loaded + this.COMMENT_CACHE_TIME > (new Date()).getTime()) {
				container.parentNode.replaceChild(thumb.container, container);
				return; //abort load we already had it cached
			} else {
				var spinner = container.cloneNode(false);
				spinner.innerHTML = "<img class='script' id='spinner' src='" + Site.staticFilesURL + "/nexoskel/images/spinner.gif" + "'/>";
				container.parentNode.replaceChild(spinner, container);
			}
			//timeout so that we don't actually make a request for a comments if people aren't going to stay and read them
			setTimeout(function(){
				if (UserGallery.FilmView.currentPicture.pictureID == thumb.id) { //only if we're still on the picture
					YAHOO.util.Connect.asyncRequest('GET', Nexopia.JSONData['commentLink'] + "/" + thumb.id, new ResponseHandler({
						success: function(o) {
						},
						failure: function(o) {
						},
						scope: this
					}), "ajax=true");
				}
			}, this.COMMENT_DELAY);
		}
	},
	makeProfilePic: function() {
		YAHOO.util.Dom.setStyle("make_profile_picture", "display", "none");
		
		var id = this.currentPicture.pictureID;
		var formKey = document.getElementById('manage_gallery_form_key').value;
		YAHOO.util.Connect.asyncRequest('POST', Site.selfURL + '/gallery/make_profile_pic', new ResponseHandler({
			success: function(o) {
				this.currentProfilePics[this.currentProfilePics.length] = id; 
			},
			failure: function(o) {
			},
			scope: this
		}), "id="+id+"&form_key[]="+formKey);
		
	},
	editPic: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		var baseUri = Nexopia.json(element);
		EditPicturePanel.init(this.currentPicture.pictureID, 'gallery', {baseURI: baseUri});
	},
	currentPicIsProfilePic: function()
	{
		for(var i = 0; i < this.currentProfilePics.length; i++)
		{
			if(parseInt(this.currentProfilePics[i], 10) == parseInt(this.currentPicture.pictureID, 10))
			{
				return true;
			}
		}
		
		return false;
	}
};

Overlord.assign({
	minion: "user_gallery_film_view",
	load: UserGallery.FilmView.init_film_view,
	scope: UserGallery.FilmView,
	init: 'load'
});

Overlord.assign({
	minion: "gallery_film_strip",
	mouseover: function(event, element) {
		Nexopia.DelayedImage.loadImages(element);
	},
	order: 1 //This should occur after the rest of the page has initialized, it depends on thumbnail objects having already been created
});

Overlord.assign({
	minion: "gallery_comments:view",
	load: function(element) {
		var thumb = UserGallery.FilmView.getThumb(UserGallery.FilmView.currentPicture.pictureID);
		thumb.container = element;
		element.loaded = (new Date()).getTime();
	},
	order: 1, //This should occur after the rest of the page has initialized, it depends on thumbnail objects having already been created
	init: 'load'
});

Overlord.assign({
	minion: "film_view:make_profile_picture",
	load: function(element) {
		YAHOO.util.Event.on(element, 'click', UserGallery.FilmView.makeProfilePic, null, UserGallery.FilmView);
	},
	order: 1 //This should occur after the rest of the page has initialized, it depends on thumbnail objects having already been created
});

Overlord.assign({
	minion: "film_view:edit_picture",
	click: UserGallery.FilmView.editPic,
	scope: UserGallery.FilmView,
	order: 1 //This should occur after the rest of the page has initialized, it depends on thumbnail objects having already been created
});

if(YAHOO.gallery == undefined){
	YAHOO.namespace("gallery");
}

YAHOO.gallery.CommentsView =
{
	init: function()
	{
		YAHOO.gallery.CommentsView.current_page = Nexopia.JSONData['gallery_comments_current_page'];		
		YAHOO.util.Event.addListener("select_all_comments", "click", YAHOO.gallery.CommentsView.select_all_click);		
	},
	
	init_paging: function(element)
	{	
		YAHOO.gallery.CommentsView.current_page = Nexopia.JSONData['gallery_comments_current_page'];
		
		YAHOO.util.Event.addListener(element, "click", YAHOO.gallery.CommentsView.get_page);
	},
	
	get_page: function(e)
	{
		if (e) {
			YAHOO.util.Event.preventDefault(e);
		}
		
		// In some cases the target of the event is the paging arrow instead of the link
		// on the image.  So if we get the image tag we just go to the parent which
		// should be the link we're looking for.
		var target = YAHOO.util.Event.getTarget(e);
		if(target.tagName.toLowerCase() == "img")
		{
			target = target.parentNode;
		}

		var ajax_path = Nexopia.JSONData['gallery_comments_page_path'];		
		var page_path = "http://"+ target.host + ajax_path + target.search;
		
		var error_row = document.getElementById("comments_user_message_row");
		if(error_row)
		{
			error_row.parentNode.removeChild(error_row);
		}
		
		YAHOO.util.Connect.asyncRequest("GET", page_path, new ResponseHandler({
			success: function(o) {
			},
			failure: function(o) {
			},
			scope: this
		}), "");
	},
	
	init_editor: function() {
		YAHOO.util.Event.on("comment_post_submit", "click", YAHOO.gallery.CommentsView.submit_post);
		YAHOO.util.Event.addListener("comment_text", "focus", YAHOO.gallery.CommentsView.clear_input);
		
		var text_area = document.getElementById("comment_text");
		text_area.value = "Post a comment...";
		
		// Disable the submit button on load so the user can't post the initial text.
		var post_button = YAHOO.util.Dom.get("comment_post_submit");
		if (post_button)
		{
			post_button.disabled = true;
		}
	},
	
	admin_get_params: function()
	{
		var temp_arr = [];
		if(Nexopia.JSONData['get_params'] && Nexopia.JSONData['get_params'] != "")
		{
			temp_arr.push(Nexopia.JSONData['get_params']);
		}
		
		return temp_arr;
	},
	
	select_all_click: function(e)
	{
		var input_list = YAHOO.util.Dom.getElementsByClassName("comment_delete_input", "input", "delete_comments_form", function(obj){});
		
		for(var i=0; i < input_list.length; i++)
		{
			input_list[i].checked = e.target.checked;
		}
	},
	
	clear_delete_inputs: function(type, args)
	{
		var select_all_input = document.getElementById("select_all_comments");
		select_all_input.checked = false;
		
		var root_page = document.getElementById("delete_comments_form");
		var input_list = YAHOO.util.Dom.getElementsByClassName("comment_delete_input", "input", root_page, function(obj){});
		
		for(var i=0; i < input_list.length; i++)
		{
			input_list[i].checked = false;
		}
	},
	
	submit_post: function(e) {

		if (e) {
			YAHOO.util.Event.preventDefault(e);
		}
		
		var comments_form = document.getElementById("comment_write_form");
		
		var post_button = document.getElementById("comment_post_submit");
		var spinner = document.getElementById("post_comment_spinner");
		if(post_button && spinner)
		{
			YAHOO.util.Dom.setStyle(post_button, "display", "none");
			post_button.disabled = true;
			YAHOO.util.Dom.setStyle(spinner, "display", "block");
		}
		
		YAHOO.util.Connect.setForm(comments_form);
		YAHOO.util.Connect.asyncRequest(comments_form.method, comments_form.action + "/dynamic", new ResponseHandler({
			success: function(o) {
				YAHOO.gallery.CommentsView.enable_editor();
				// YAHOO.gallery.CommentsView.post_update_comments_view(o);
			},
			failure: function(o) {
			},
			scope: this
		}), "");
	},
	
	post_update_comments_view: function(connection_obj)
	{
		var result_obj = YAHOO.lang.JSON.parse(connection_obj.responseText);
		
		// We only want to insert the comment if we got a successful return and
		// we're on the first page.
		if( result_obj.success && (YAHOO.gallery.CommentsView.current_page == 0) )
		{
			// Since we mad a successful post we want to clear the error message at the top
			// of the comments section if it exists.
			var error_row = document.getElementById("comments_user_message_row");
			if(error_row)
			{
				error_row.parentNode.removeChild(error_row);
			}
			
			var top_comment_id = YAHOO.gallery.CommentsView.min_comment_id();
			var bottom_comment_id = YAHOO.gallery.CommentsView.max_comment_id();
			var visible_comments_count = YAHOO.gallery.CommentsView.num_comments_displayed();
			
			var top_comment = document.getElementById("user_gallery_comment_" + top_comment_id);
			var bottom_comment = document.getElementById("user_gallery_comment_" + bottom_comment_id);
			
			var new_element = document.createElement("div");
			new_element.innerHTML = result_obj.comment_content;
			
			// if we have a comment on the page already, then we want to add the new comment below the
			// existing one.
			if(bottom_comment)
			{
				bottom_comment.parentNode.appendChild(new_element.firstChild);
			}
			// Otherwise we just insert the new comment.
			else
			{
				var root = document.getElementById("gallery_comments_individual_page_wrapper");
				if(root)
				{
					root.appendChild(new_element.firstChild);
				}
			}
			
			// Attach any JS actions that should be attached to a comment object.
			var new_comment = document.getElementById("user_gallery_comment_" + result_obj.comment_id);
			if(new_comment)
			{
				Overlord.summonMinions(new_comment);
			}
			
			// Scroll the top comment off if we end up with more than 5 on the page.
			if( top_comment && (visible_comments_count >= 5) )
			{
				YAHOO.util.Event.purgeElement(top_comment, true);
				bottom_comment.parentNode.removeChild(top_comment);
			}
		}
		
		// If the post wasn't successful post the error message.
		// If the post was successful, but we're not on the first page, then
		// Post a message saying we were successful.
		if( !result_obj.success || (YAHOO.gallery.CommentsView.current_page > 0) )
		{
			YAHOO.gallery.CommentsView.display_user_error(result_obj);
		}
		
		// Re-enable the editor so we can post another innane comment.
		YAHOO.gallery.CommentsView.enable_editor();
	},
	
	quick_delete: function(e)
	{
		if (e) {
			YAHOO.util.Event.preventDefault(e);
		}
		
		if(!confirm("Delete comment?"))
		{
			return;
		}
		
		var target = YAHOO.util.Event.getTarget(e);
		if(target.tagName.toLowerCase() == "img")
		{
			target = target.parentNode;
		}
		
		var bottom_comment_id = YAHOO.gallery.CommentsView.min_comment_id();		
		
		var separator = "";
		if(!(target.host.charAt(target.host.length-1) == "/") && !(target.pathname.charAt(0) == "/"))
		{
			separator = "/";
		}
		
		var delete_path = Site.wwwURL+separator+target.pathname+"/dynamic"+target.search+"&last_id="+bottom_comment_id;

		YAHOO.util.Connect.asyncRequest("GET", delete_path, new ResponseHandler({
			success: function(o) {
				YAHOO.gallery.CommentsView.delete_update_comments_view(o);
			},
			scope: this
		}), "");
	},
	
	delete_update_comments_view: function(connection_obj)
	{
		var result_obj = YAHOO.lang.JSON.parse(connection_obj.responseText);
		
		if(result_obj.success)
		{
			var error_row = document.getElementById("comments_user_message_row");
			if(error_row)
			{
				error_row.parentNode.removeChild(error_row);
			}
			
			var bottom_comment_id = YAHOO.gallery.CommentsView.min_comment_id();
			
			var del_comment_obj = document.getElementById("user_gallery_comment_" + result_obj.removed_comment_id);
			YAHOO.util.Event.purgeElement(del_comment_obj, true);
			del_comment_obj.parentNode.removeChild(del_comment_obj);
			
			//Check to see if there is no content
			if(result_obj.comment_content == null || result_obj.comment_content == "")
			{
				return;
			}
			
			if(result_obj.removed_comment_id == bottom_comment_id)
			{
				bottom_comment_id = YAHOO.gallery.CommentsView.min_comment_id();
			}

			var new_element = document.createElement("div");
			new_element.innerHTML = result_obj.comment_content;

			var bottom_comment = document.getElementById("user_gallery_comment_" + bottom_comment_id);
			bottom_comment.parentNode.appendChild(new_element.firstChild);
			
			var new_comment = document.getElementById("user_gallery_comment_" + result_obj.comment_id);
			if(new_comment)
			{
				Overlord.summonMinions(new_comment);
			}
		}
		else
		{
			YAHOO.gallery.CommentsView.display_user_error(result_obj);
		}
	},
	
	display_user_error: function(result_obj)
	{
		var error_node = document.getElementById("gallery_comments_post_error");
		var success_node = document.getElementById("gallery_comments_post_success");
		if(error_node && !result_obj.success)
		{
			error_node.innerText = result_obj.error;
			return;
		}
		else if((error_node && result_obj.success) || (success_node && !result_obj.success))
		{
			var message_row = document.getElementById("comments_user_message_row");
			if(message_row)
			{
				message_row.parentNode.removeChild(message_row);
			}
		}
		else if(success_node && result_obj.success)
		{
			return;
		}
		
		var new_row = document.createElement("tr");
		new_row.id = "comments_user_message_row";
		
		var left_col = document.createElement("td");
		var right_col = document.createElement("td");

		var new_element = document.createElement("div");
		
		if(result_obj.success)
		{
			var text = document.createTextNode("Comment post successful. Refresh the page to view your comment.");
			new_element.appendChild(text);
			
			new_element.id = "comments_post_success";
		}
		else
		{
			var text = document.createTextNode(result_obj.error);
			new_element.appendChild(text);
		
			new_element.id = "gallery_comments_post_error";
		}
		
		new_row.appendChild(left_col);
		new_row.appendChild(right_col);
		right_col.appendChild(new_element);
	
		var comments_row = document.getElementById("comments_editor_row");
	
		comments_row.parentNode.insertBefore(new_row, comments_row);
	},
	
	enable_editor: function() {
		var spinner = document.getElementById("post_comment_spinner");
		var post_button = document.getElementById("comment_post_submit");
		var text_area = document.getElementById("comment_text");
		
		text_area.value = "Post a comment...";
		YAHOO.util.Event.addListener(text_area, "focus", YAHOO.gallery.CommentsView.clear_input, this);
		YAHOO.util.Dom.setStyle(post_button, "display", "block");
		
		if(post_button && spinner)
		{
			YAHOO.util.Dom.setStyle(post_button, "display", "block");
			post_button.disabled = true;
			YAHOO.util.Dom.setStyle(spinner, "display", "none");
		}
	},
	
	clear_input: function(e) {
		if (e) {
			YAHOO.util.Event.preventDefault(e);
		}
		
		// clear the listener off so it doesn't go again if they click out, then back into the editor.
		YAHOO.util.Event.removeListener("comment_text", "focus", YAHOO.gallery.CommentsView.clear_input);
		
		// clear the text in the editor
		YAHOO.util.Dom.get("comment_text").value = "";
		
		// enable the post button so they can post their comment.
		YAHOO.util.Dom.get("comment_post_submit").disabled = false;
	},
	
	min_comment_id: function()
	{
		var root = document.getElementById("gallery_comments_block");
		
		var comments_list = YAHOO.util.Dom.getElementsByClassName("comment_view_container", "div", "gallery_comments_page_wrapper", function(obj){});
		var min_id;
		var temp, temp_id;
		
		for(var i=0; i < comments_list.length; i++)
		{
			temp = comments_list[i].id.split("_");
			temp_id = parseInt(temp[3], 10);
			if(min_id == null)
			{
				min_id = temp_id;
			}
			min_id = Math.min(temp_id, min_id);	
		}
		
		return min_id;
	},
	
	max_comment_id: function()
	{
		var root = document.getElementById("gallery_comments_block");
		
		var comments_list = YAHOO.util.Dom.getElementsByClassName("comment_view_container", "div", "gallery_comments_page_wrapper", function(obj){});
		var max_id = 0;
		var temp, temp_id;
		
		for(var i=0; i < comments_list.length; i++)
		{
			temp = comments_list[i].id.split("_");
			temp_id = parseInt(temp[3], 10);
			if(max_id == null)
			{
				max_id = temp_id;
			}
			max_id = Math.max(temp_id, max_id);
		}
		
		return max_id;
	},
	
	num_comments_displayed: function()
	{
		var root = document.getElementById("gallery_comments_block");
		var comments_list = YAHOO.util.Dom.getElementsByClassName("comment_view_container", "div", "gallery_comments_page_wrapper", function(obj){});
		
		return comments_list.length;
	}
};

Overlord.assign({
	minion: "gallery_comments:view",
	load: function(element){
		YAHOO.gallery.CommentsView.init();
	},
	order: 1,
	init: 'load'
});

Overlord.assign({
	minion: "gallery_comments:quick_delete",
	load: function(element){
		YAHOO.util.Event.addListener(element, "click", YAHOO.gallery.CommentsView.quick_delete);
	}
});

Overlord.assign({
	minion: "gallery_comments:write",
	load: function(element){
		YAHOO.gallery.CommentsView.init_editor();
	}
});

Overlord.assign({
	minion: "gallery_comments:paging_control",
	load: function(element){
		YAHOO.gallery.CommentsView.init_paging(element);
	}
});

Overlord.assign({
	minion: "gallery_comments:select_all",
	click: function(event){
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		YAHOO.util.Dom.getElementsByClassName('comment_delete_input', 'input', null, function(checkbox) {checkbox.checked = true;});	
	},
	scope: YAHOO.gallery.CommentsView
});

Overlord.assign({
	minion: "gallery_comments:select_none",
	click: function(event){
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		YAHOO.util.Dom.getElementsByClassName('comment_delete_input', 'input', null, function(checkbox) {checkbox.checked = false;});	
	},
	scope: YAHOO.gallery.CommentsView
});


function GalleryFolder(gallery_div) {
	this.dragdrop = new YAHOO.util.DDTarget(gallery_div);
	this.id = GalleryManagement.parseID(gallery_div.id);
	//Truncate the title text if it's too long
	new Truncator(document.getElementById("gallery_title["+this.id+"]"), {width:89,height:20});
	
	//Register the delete link for this gallery to do an ajax delete call through GalleryManagement
	YAHOO.util.Dom.getElementsByClassName("gallery_delete", "a", gallery_div, function(element) {
		YAHOO.util.Event.on(element, "click", function(e) {
			YAHOO.util.Event.preventDefault(e);
			GalleryManagement.deleteGallery(element);
		});
	});
}

GalleryFolder.prototype = {
	takePicture: function(picID) {
		YAHOO.util.Dom.setStyle(picID, "visibility", "");
		if (this.id != GalleryManagement.galleryid) {
			GalleryManagement.startSpinner();
			YAHOO.util.Connect.setForm("gallery_form");
			YAHOO.util.Connect.asyncRequest('POST', Nexopia.JSONData['areaBaseUri'] + '/gallery/change_gallery', new ResponseHandler({
				success: function(o) {
					GalleryManagement.images[this.argument].remove();
					GalleryManagement.stopSpinner();
				},
				failure: function(o) {
					GalleryManagement.stopSpinner();
				},
				argument: picID
			}), "ids=" + picID + "&targetgallery=" + this.id);
		}
	}
};

Overlord.assign({
	minion: "folder_photoframe",
	load: function(element) {
		var folder = new GalleryFolder(element);
		element.galleryFolderID = folder.id;
		GalleryManagement.galleries[folder.id] = folder;
	}, 
	unload: function(element) {
		delete GalleryManagement.galleries[element.galleryFolderID];
	}, 
	order: -1	
});
function GalleryImage(checkBoxElement) {
	this.checkBox = checkBoxElement;
	function checkBoxOnClick(){GalleryManagement.select(this);}
	YAHOO.util.Event.addListener(this.checkBox, "click", checkBoxOnClick); 
	
	this.id = GalleryManagement.parseID(checkBoxElement.id);
	
	this.node = document.getElementById(this.id);
	if (!this.node) {
		return false;
	}

	//some checkboxes might be checked by default by the browser, show them
	if (this.checkBox.checked) {
		this.select();
	}
	this.deleteLink = document.getElementById("delete_link["+this.id+"]");
	
	YAHOO.util.Event.addListener(this.deleteLink, "click", function(event) {
		YAHOO.util.Event.preventDefault(event);
		GalleryManagement.delete_pic(this);
	}); 

	this.node = document.getElementById(this.id);
	YAHOO.util.Event.on("draggable_image["+this.id+"]", "click", YAHOO.util.Event.preventDefault);
	this.dragdrop = new ImageDrag(this.node);
	this.calculatePosition();
}

GalleryImage.prototype = {
	getUserData: function(func) {
	    var callbacks = {
	        success : function (o) {
	            var messages = [];
	            try {
	                messages = YAHOO.lang.JSON.parse(o.responseText);
	            }
	            catch (x) {
	                alert("JSON Parse failed!");
	                return;
	            }
	            o.argument.call(this, messages);
	        },
	
	        failure : function (o) {
	            if (!YAHOO.util.Connect.isCallInProgress(o)) {
	                alert("Async call failed!");
	            }
	        },
	        argument: func,
	        timeout : 3000,
	        scope: this
	    };
	
	    // Make the call to the server for JSON data
	    YAHOO.util.Connect.asyncRequest('GET', Nexopia.JSONData['areaBaseUri'] + "/gallery/jsonuser/", callbacks);
	},
	showEditPanel: function(e) {
		YAHOO.util.Event.preventDefault(e);
		var editPanel = new YAHOO.widget.Panel('edit_photo_panel', { 
			fixedcenter: true,
			constraintoviewport: true,  
			underlay:"shadow",  
			modal:true,
			close:false,  
			visible:false,  
			draggable:false
		});
		
		editPanel.render(document.body);
		
		var uri = Nexopia.JSONData['areaBaseUri'] +"/gallery/pic/" + this.id + "/edit";
		var id = this.id;
		GalleryManagement.startSpinner();
		YAHOO.util.Connect.asyncRequest('GET', uri, new ResponseHandler({
			success: function() {
				GalleryManagement.EditPhotoPanel.panel = editPanel;
				Nexopia.Utilities.withImage('edit_img', {
					load: function(img) {
						editPanel.show();
						if (YAHOO.env.ua.ie) {
							//XXX: I hate using a magic number here but everything else I do seems to make ie angry.
							editPanel.element.firstChild.style.width = Math.max(img.width, 400) + "px";
						}
						editPanel.center();
						GalleryManagement.stopSpinner();
					}
				});
			},
			failure: function() {
				GalleryManagement.stopSpinner();
			}
		}));
	},
	isSelected: function() {
		return this.checkBox.checked;
	},
	select: function() {
		this.checkBox.checked = "checked";
	},
	unselect: function() {
		this.checkBox.checked = "";
	},
	remove: function() {
		this.node.parentNode.removeChild(this.node);
		if (GalleryManagement.images) {
			delete GalleryManagement.images[this.id];
		}
	},
	move: function() {
		this.debug = true;
		var originalPosition = this.position;
		this.calculatePosition();
		if (this.position != originalPosition) {
			GalleryManagement.startSpinner();
			YAHOO.util.Connect.setForm("gallery_form");
			YAHOO.util.Connect.asyncRequest('POST', Nexopia.JSONData['areaBaseUri'] + '/gallery/'+document.getElementById("galleryid").value + '/move_pic', {
				success: function(o, argument) {
					GalleryManagement.stopSpinner();
				},
				failure: function(o) {
					alert("failure");
				},
				scope: this
			}, "id=" + this.id + "&position=" + this.position + "&form_key[]=" + SecureForm.getFormKey());
		}
	},
	calculatePosition: function() {
		var list = this.node.parentNode;
		var found = false;
		for (var i=0; i<list.childNodes.length; i++) {
			if (list.childNodes[i].id == this.node.id) {
				this.position = i+1;
				found = true;
			} else {
				var gimage = GalleryManagement.images[list.childNodes[i].id];
				if(gimage) {
					gimage.position = i+1;
				}
			}
		}
		if(found) {
			return this.position;
		}
		throw "Unable to calculate the position of image " + this.node.id;
	}
};
GalleryProfileBlockManager = {
	init: function() {
	}
};

Overlord.assign({
	minion: "profile",
	load: function(element) {
		GalleryProfileBlockManager.init();
	},
	order: -1	
});

Overlord.assign({
	minion: "gallery_pics_frame",
	load: function(element) {
		new Paginator(element, {height:105, width: 492});
	},
	order: -1	
});

Overlord.assign({
	minion: "gallery_pics_frame",
	mouseover: function(event, element) {
		Nexopia.DelayedImage.loadImages(element);
	},
	order: 1	
});

// This file contains drag 'n' drop code for images in the gallery section of the gallery management page.
// Code for profile pictures is in profile_picture.js

ImageDrag = function(id, sGroup, config) {
	ImageDrag.superclass.constructor.call(this, id, sGroup, config);
	var el = this.getDragEl();
	YAHOO.util.Dom.setStyle(el, "opacity", 0.67);
	this.setHandleElId("draggable_image["+this.id+"]");
	new YAHOO.widget.Tooltip(document.createElement("div"), {
		context: document.getElementById("draggable_image["+this.id+"]"), 
		text:"Move",
		showDelay: 1000
	});
	this.goingUp = false;
	this.lastX = 0;
};

YAHOO.extend(ImageDrag, YAHOO.util.DDProxy, {
	startDrag: function(x, y) {
		for (var key in Paginator.paginators) {
			Paginator.paginators[key].showStrikeZones();
		}
		// make the proxy look like the source element
		var dragEl = this.getDragEl();
		var clickEl = this.getEl();
		YAHOO.util.Dom.setStyle(clickEl, "visibility", "hidden");
		this.originalNextSibling = clickEl.nextSibling;
		this.originalParentNode = clickEl.parentNode;
		dragEl.innerHTML = clickEl.innerHTML;
		YAHOO.util.Dom.setStyle(dragEl, "color", YAHOO.util.Dom.getStyle(clickEl, "color"));
		YAHOO.util.Dom.setStyle(dragEl, "backgroundColor", YAHOO.util.Dom.getStyle(clickEl, "backgroundColor"));
		YAHOO.util.Dom.setStyle(dragEl, "border", "");
		GalleryManagement.dragInProgress = true;
	},
	endDrag: function(e) {
		for (var key in Paginator.paginators) {
			Paginator.paginators[key].hideStrikeZones();
		}
		if (this.undoDrag) {
			if (this.originalNextSibling) {
				this.originalParentNode.insertBefore(this.getEl(), this.originalNextSibling);
			} else {
				this.originalParentNode.appendChild(this.getEl());
			}
		}
		if (!this.skipReorder) {
			YAHOO.util.Dom.setStyle(this.id, "visibility", "");
			GalleryManagement.images[this.id].move();
		} else {
			this.skipReorder = false;
		}
		GalleryManagement.dragInProgress = false;
	},
	onDrag: function(e) {
		// Keep track of the direction of the drag for use during onDragOver
		var x = YAHOO.util.Event.getPageX(e);

		if (x < this.lastX) {
			this.goingUp = true;
		} else if (x > this.lastX) {
			this.goingUp = false;
		}

		this.lastX = x;
	},
	onDragDrop: function(e, id) {
		var el = YAHOO.util.Dom.get(id);
		document.getElementById(id).parentNode.parentNode.style.border = "";
	},
	onDragOver: function(e, id) {
		var destEl =YAHOO.util.Dom.get(id);

		// We are only concerned with list items, we ignore the dragover
		// notifications for the list.
		if (destEl.tagName == "LI") {
			var srcEl = this.getEl();
			var p = destEl.parentNode;
			if (this.goingUp) {
				p.insertBefore(srcEl, destEl); // insert above
			} else {
				p.insertBefore(srcEl, destEl.nextSibling); // insert below
			}
		}
	},
	onDragEnter: function(e, id) {
		var el = YAHOO.util.Dom.get(id);
		if (id.indexOf("gallery") == 0) {
			var frame = document.getElementById(id).parentNode.parentNode;
			frame.style.border = "2px solid gray";
		} else if (el.className == "profile_pic_frame"){
			el.style.border = "2px solid gray";
		} else {
			var paginatorEl = YAHOO.util.Dom.getAncestorByClassName(el, 'paginator');
			if (paginatorEl) {
				var paginator = Paginator.paginators[paginatorEl.id];
				if (YAHOO.util.Dom.hasClass(el, "left")) {
					paginator.pageBackward();
				} else if (YAHOO.util.Dom.hasClass(el, "right")){
					paginator.pageForward();
				}
			}
		}
	},
	onDragOut: function(e, id) {
		var el = YAHOO.util.Dom.get(id);
		if (id.indexOf("gallery") == 0) {
			document.getElementById(id).parentNode.parentNode.style.border = "";
		} else if (el.className == "profile_pic_frame"){
			el.style.border = "";
		}
	}
});
//require user_gallery.js
UserGallery.NormalView = {
	thumbs: [],
	loadImages: function() {
		for (var i=0;i<this.thumbs.length;i++) {
			this.thumbs[i].loadImage();
		}
	}
};

UserGallery.NormalView.Thumb = function(element) {
	this.element = YAHOO.util.Dom.get(element);
	this.url = this.element.attributes.url.value;
	var ids = UserGallery.parsePath(this.url);
	this.userid = ids[0];
	this.id = ids[1];
	
	//on click for the link surrounding the thumbnail
	YAHOO.util.Event.on(this.element.parentNode, 'click', this.makeCurrent, this, true);
};

UserGallery.NormalView.Thumb.prototype = {
	loadImage: function() {
		if (!this.loaded) {
			this.element.src = this.url;
		}
		this.loaded = true;
	},
	makeCurrent: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		UserGallery.FilmView.setCurrentById(this.id);
	}
};
Overlord.assign({
	minion: "normal_view_thumb",
	load: function(element) {
		UserGallery.NormalView.thumbs.push(new UserGallery.NormalView.Thumb(element));
	}	
});

Overlord.assign({
	minion: "thumb_view_link",
	mouseover: UserGallery.NormalView.loadImages,
	focus: UserGallery.NormalView.loadImages,
	scope: UserGallery.NormalView
});
//require film_view.js
Overlord.assign({
	minion:"film_view:current_picture",
	load: function(element) {
		UserGallery.FilmView.currentPicture = new UserGallery.FilmView.Picture(element);
	},
	order: -2,
	init: 'load'
});

/* !here */
UserGallery.FilmView.Picture = function(pictureElement) {
	this.picture = YAHOO.util.Dom.get(pictureElement);
	//the picture id will be the server side id of the image
	this.pictureID = UserGallery.parsePath(this.picture.src)[1];
	
	// Resize the 'photo_full_view' to be the width it needs to be.
	YAHOO.util.Dom.setStyle('photo_full_view', 'width', YAHOO.util.Dom.get("current_picture").width+'px');

	this.leftPanel = document.getElementById('left_arrow_panel');
	if(this.leftPanel) {
		YAHOO.util.Event.on(this.leftPanel, 'click', UserGallery.FilmView.previous, UserGallery.FilmView, true);
		this.leftArrow = document.getElementById('left_arrow_img');
		this.leftArrow.originalSource = this.leftArrow.src;
		this.leftArrow.hoverSource = this.leftArrow.getAttribute('hover_src');
		YAHOO.util.Event.on(this.leftPanel, 'mouseover', this.highlightLeft, this, true);
		YAHOO.util.Event.on(this.leftPanel, 'mouseout', this.unhighlightLeft, this, true);
	}
	this.rightPanel = document.getElementById('right_arrow_panel');
	if(this.rightPanel) {
		YAHOO.util.Event.on(this.rightPanel, "click", UserGallery.FilmView.next, UserGallery.FilmView, true);
		this.rightArrow = document.getElementById('right_arrow_img');
		this.rightArrow.originalSource = this.rightArrow.src;
		this.rightArrow.hoverSource = this.rightArrow.getAttribute('hover_src');
		YAHOO.util.Event.on(this.rightPanel, 'mouseover', this.highlightRight, this, true);
		YAHOO.util.Event.on(this.rightPanel, 'mouseout', this.unhighlightRight, this, true);
	}

	this.initArrows();
	YAHOO.util.Dom.get("current_picture").loaded = true;
};

UserGallery.FilmView.Picture.prototype = {
	//change the picture being displayed, takes a dom node
	setPicture: function(imgTag) {
		this.picture.parentNode.replaceChild(imgTag, this.picture);
		this.picture = imgTag;
		this.pictureID = UserGallery.parsePath(imgTag.src)[1];
		// Resize the 'photo_full_view' to be the width it needs to be.
		YAHOO.util.Dom.setStyle('photo_full_view', 'width', imgTag.width+'px');
		this.initArrows();
		
		YAHOO.util.Event.on(imgTag, 'load', function(e, imgTag)
		{
			YAHOO.util.Dom.setStyle('photo_full_view', 'width', imgTag.width+'px');
		}, imgTag);

		Nexopia.Utilities.withImage('current_picture', {
			load: function(img) {
				this.initArrows();
			},
			scope: UserGallery.FilmView.currentPicture
		});
	}, 
	
	initArrows: function() {
		//I don't know what these numbers correspond to, they are chosen because they seem to work okay.
		//Everything except IE <= 7 seems to behave one way, and surprise surprise ie 6 & 7 behave differently
		//so we have 2 possible fudge factors. My apologies for the hackiness.
		if (YAHOO.env.ua.ie && YAHOO.env.ua.ie < 8) {
			var left_shift = -520;
			var right_shift = -160;
		} else {
			var left_shift = -360;
			var right_shift = 0;
		}
		
		if(this.leftPanel) {
			YAHOO.util.Dom.setStyle('left_arrow_panel', 'height', YAHOO.util.Dom.get("current_picture").height+'px');
			YAHOO.util.Dom.setStyle('left_arrow_panel', 'left', ((YAHOO.util.Dom.get("current_picture").width/2)+left_shift)+'px');
			YAHOO.util.Dom.setStyle(this.leftArrow, 'top', YAHOO.util.Dom.get("current_picture").height/2+'px');
		}
		if(this.rightPanel) {
			YAHOO.util.Dom.setStyle('right_arrow_panel', 'height', YAHOO.util.Dom.get("current_picture").height+'px');
			YAHOO.util.Dom.setStyle('right_arrow_panel', 'left', (YAHOO.util.Dom.get("current_picture").width/2+right_shift)+'px');
			YAHOO.util.Dom.setStyle(this.rightArrow, 'top', YAHOO.util.Dom.get("current_picture").height/2+'px');
		}
	},

	highlightRight: function() {
		YAHOO.util.Dom.addClass(this.rightPanel, 'hover');
		this.rightArrow.src = this.rightArrow.hoverSource;
	},
	highlightLeft: function() {
		YAHOO.util.Dom.addClass(this.leftPanel, 'hover');
		this.leftArrow.src = this.leftArrow.hoverSource;
	},
	unhighlightRight: function() {
		YAHOO.util.Dom.removeClass(this.rightPanel, 'hover');
		this.rightArrow.src = this.rightArrow.originalSource;
	},
	unhighlightLeft: function() {
		YAHOO.util.Dom.removeClass(this.leftPanel, 'hover');
		this.leftArrow.src = this.leftArrow.originalSource;
	}
};

Overlord.assign({
	minion: "recent_galleries:description",
	load: function(element) {
		new Truncator(element, {height: 40, width: 138});
	}	
});
Overlord.assign({
	minion: "recent_galleries:name",
	load: function(element) {
		new Truncator(element, {height: 25, width: 138});
	}	
});

function Template(name) {
	this.templateID = Template.creationCount;
	Template.creationCount++;
	this.rootElement = document.getElementById("template_"+name).cloneNode(true);
	this.recurseElement(this.rootElement);
};

Template.creationCount = 0;

Template.prototype = {
	recurseElement: function(node) {
		if (node.id) {
			node.id = node.id + this.templateID;
		}
		var children = node.childNodes;
		for (var i=0; i<children.length; i++) {
			var child = children.item(i);
			var id = child.id;
			if (id) {
				var match = id.match(/^template_(.+)$/);
				if (match) {
					this[match[1]] = child;
				}
			}
			this.recurseElement(child);
		}
	}
};
//require film_view.js
//initialization of individual thumb objects is taken care of by the script manager
Overlord.assign({
	minion: "gallery_film_strip:thumb",
	load: function(element) {
		new UserGallery.FilmView.Thumb(element);
	},
	unload: function(element) {
		UserGallery.FilmView.unregisterThumb(element.thumbID);
	}
});

Overlord.assign({
	minion: "gallery_film_strip",
	load: function(element) {
		UserGallery.FilmView.preloadImages(1,1);
	},
	order: 1,
	init: 'load'
});

UserGallery.FilmView.Thumb = function(element) {
	this.element = YAHOO.util.Dom.get(element);
	YAHOO.lang.augmentObject(this, Nexopia.json(element));
	this.img = this.element.firstChild.firstChild; //two tags down to get the img tag, this is fragile but fast
	this.calculateIDs(); //pulls the userid and id from the img element and stores them
	this.element.thumbID = this.id; //shortcut to the id primarily used for unregistering thumbs
	UserGallery.FilmView.registerThumb(this);
	//if you click on an image, make it the current main image
	YAHOO.util.Event.on(element, 'click', this.makeCurrent, this, true);
};

UserGallery.FilmView.Thumb.prototype = {
	//call out to UserGallery.FilmView to make this thumb the current main image
	makeCurrent: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		UserGallery.FilmView.setCurrent(this);
	},
	//parses the src attribute from this.img and stores this.userid and this.id
	calculateIDs: function() {
		var src = null;
		if (this.img.src) {
			src = this.img.src;
		} else {
			src = this.img.attributes.url.value;
		}
		var ids = UserGallery.parsePath(src);
		this.userid = ids[0];
		this.id = ids[1];
	},
	getIndex: function() {
		var index = 0;
		var node = this.element;
		while (node.previousSibling != null) {
			if (node.className == "thumb") {
				index++;
			}
			node = node.previousSibling;
		}
		return index;
	}
};
var Uploader = {
	flashUploader: null,
	flashDoneLoading: false,
	filesQueue: [],
	init: function() {
		this.uploadQueue = [];
		if (this.hasSuitableFlashVersion()) {
			YAHOO.widget.Uploader.SWFURL = Site.staticFilesURL + "/gallery/flash/uploader.swf";
			this.flashUploader = new YAHOO.widget.Uploader("uploader_overlay");

			var overlay = document.getElementById('uploader_overlay');
			var button = overlay.nextSibling.firstChild.firstChild;
			var uiLayer = YAHOO.util.Dom.getRegion(button); 
			YAHOO.util.Dom.setStyle(button.firstChild, 'visibility', 'visible');
			YAHOO.util.Dom.setStyle(overlay, 'width', (uiLayer.right-uiLayer.left+2) + "px"); 
			YAHOO.util.Dom.setStyle(overlay, 'height', (uiLayer.bottom-uiLayer.top+2) + "px"); 
			
			this.flashUploader.addListener('contentReady', this.configUploader, this, true);
			this.flashUploader.addListener('fileSelect', this.filesQueued, this, true);
			this.flashUploader.addListener('uploadCompleteData', this.uploadFileSuccess, this, true);
			this.flashUploader.addListener('uploadProgress', this.uploadProgress, this, true);
			this.flashUploader.addListener('uploadStart', function(event) {
				YAHOO.util.Dom.setStyle(overlay, 'width', "1px"); 
				YAHOO.util.Dom.setStyle(overlay, 'height', "1px");
				YAHOO.util.Dom.setStyle(button.parentNode, 'display', "none");
				document.getElementById("alternate_instructions_script").innerHTML = "&nbsp;";
			});
		} else {
			this.activateClassicUploader();
		}
	},
	configUploader: function() {
		this.flashUploader.setSimUploadLimit(1);
		this.flashUploader.setAllowMultipleFiles(true);
		this.flashUploader.setFileFilters(["*.jpeg;*.jpg;*.png;*.gif;*.bmp"], "Picture Files");
	},
	//minimum version is 9.0.45
	hasSuitableFlashVersion: function() {
		if (YAHOO.util.FlashDetect.major > 9) {
			return true;
		} else if (YAHOO.util.FlashDetect.major == 9) {
			if (YAHOO.util.FlashDetect.minor > 0 || YAHOO.util.FlashDetect.revision >= 45) {
				return true;
			}
		}
		return false;
	},

	activateClassicUploader: function() {
		var noscript = YAHOO.util.Dom.getElementsByClassName("noscript");
		var script = YAHOO.util.Dom.getElementsByClassName("script");

		for (var i = 0; i < noscript.length; i++) {
			YAHOO.util.Dom.addClass(noscript[i], 'script');
			YAHOO.util.Dom.removeClass(noscript[i], 'noscript');
		}

		for (i = 0; i < script.length; i++) {
			YAHOO.util.Dom.addClass(script[i], 'noscript');
			YAHOO.util.Dom.removeClass(script[i], 'script');
		}
		YAHOO.util.Dom.get('upload_queue').style.display = "block";
		var overlay = document.getElementById('uploader_overlay');
		YAHOO.util.Dom.setStyle(overlay, 'display', "none");
		YAHOO.util.Dom.setStyle(overlay.nextSibling.firstChild, 'display', "none");
	},
	files: {},
	totalFiles: 0,
	uploadedFiles: 0,
	filesQueued: function(event) {
		//We need to do this extra processing of keys in order to preserve upload order
		keys = []
		for (var k in event.fileList) {
			keys.push(k);
		}
		keys.sort();
		for (var i=0; i<keys.length; i++) {
			this.fileQueued(event.fileList[keys[i]]);
		}
		
		var overlay = document.getElementById('uploader_overlay');
		YAHOO.util.Dom.setStyle(overlay, 'width', "1px"); 
		YAHOO.util.Dom.setStyle(overlay, 'height', "1px");
		YAHOO.util.Dom.setStyle(overlay.nextSibling, 'display', "none");
		YAHOO.util.Dom.setStyle('terms_warning', 'display', "none");
		
		this.uploadNext();
	},
	fileQueued: function(file) {
		var queue = document.getElementById("gallery_queue");
		var template = new Template("file");
		template.cancel.onclick = function() {Uploader.cancel(this);};
		template.description.innerHTML = file.name;
		template.cancel.id = file.id;
		this.files[file.id] = template;
		this.filesQueue.push(file.id);
		this.totalFiles++;
		queue.appendChild(template.rootElement);
	},
	uploadProgress: function(event) {
		var fileTemplate = this.files[event.id];
		fileTemplate.complete.style.width = (event.bytesLoaded/event.bytesTotal)*100 + "%";
	},
	uploadFileSuccess: function(event) {
		this.uploadedFiles++;
		var success = false;
		r = new ResponseHandler({});
		var serverData = event.data;
		if (serverData.indexOf("Success") == 0) {
			serverData = serverData.slice(0,8);
			success = true;
		}

		r.handleResponse({responseText: serverData});

		if (success) {
			var fileTemplate = this.files[event.id];
			fileTemplate.complete.style.width = "100%";
			fileTemplate.cancel.src = Site.staticFilesURL + "/Gallery/images/check_on.gif";
		} else {
			this.uploadError(event);
		}
		if (this.uploadedFiles == this.totalFiles) {
			this.allUploadsComplete();
		} else {
			this.uploadNext();
		}
	},
	uploadNext: function() {
		var file = this.filesQueue.shift();
		this.flashUploader.upload(file, document.getElementById("gallery_upload_link").href, 'POST', {
			type: "Gallery",
			description: "",
			session: YAHOO.util.Dom.get('session').value,
			selected_gallery: YAHOO.util.Dom.get('selected_gallery').value
		});
	},
	allUploadsComplete: function() {
		YAHOO.util.Dom.setStyle('view_album_links', 'display', 'block');
	},
	uploadError: function(event) {
		YAHOO.util.Dom.setStyle(this.files[event.id].rootElement, 'background-color', '#880000');
	},
	cancel: function(cancelElement) {
		var fileID = cancelElement.id;
		var fileTemplate = this.files[fileID];
		fileTemplate.rootElement.parentNode.removeChild(fileTemplate.rootElement);
		this.flashUploader.removeFile(fileID);
	},
	verifyUploadReady: function() {
		return true;
	},
	verifyFilesSelected: function(event) {
		var fileInput = document.getElementById("Filedata_noflash");
		if(!fileInput.value) {
			YAHOO.util.Event.preventDefault(event);
			alert("No files selected.");
		}
	},
	inProgress: false
};

Overlord.assign({
	minion: "gallery_upload",
	load: Uploader.init,
	scope: Uploader	
});

Overlord.assign({
	minion: "gallery_upload:classic_link",
	click: Uploader.activateClassicUploader,
	scope: Uploader
});

Overlord.assign({
	minion: "gallery_upload:classic_upload",
	click: Uploader.verifyFilesSelected,
	scope: Uploader
});
Overlord.assign({
	minion: "ugo:delete_link",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		if( confirm("Are you sure you want to delete this album?\nThis will permanently delete all photos within the album.") ) {
			YAHOO.util.Connect.asyncRequest('POST', element.href, new ResponseHandler({}));	
		}
	}
	
});

Overlord.assign({
	minion: "ugo:description",
	load: function(element) {
		new Truncator(element);
	}
});

UserpicsModule={};

ClassicFilmStrip = {
	init: function() {
		this.element = document.getElementById('classic_film_strip');
		if (!this.element) {
			return;
		}
		this.pictures = Nexopia.json(this.element);
		this.currentPicture = 1;
		this.currentPictureElement = YAHOO.util.Dom.getElementsByClassName('current_profile_picture', 'span', this.element)[0];
		this.profilePicture = YAHOO.util.Dom.getElementsByClassName('profile_picture', 'img', this.element)[0];
		this.profilePictureDescription = YAHOO.util.Dom.getElementsByClassName('profile_picture_description', 'div', this.element)[0];
		this.truncateDescription();
		this.leftPanel = YAHOO.util.Dom.getElementsByClassName('left_panel', 'div', this.element)[0];
		if (this.leftPanel) {
			this.leftArrow = this.leftPanel.firstChild.firstChild;
			this.leftArrow.originalSource = this.leftArrow.src;
			this.leftArrow.hoverSource = this.leftArrow.getAttribute('hover_src');
			YAHOO.util.Event.on(this.leftPanel, 'click', this.previousPicture, this, true);
			YAHOO.util.Event.on(this.leftPanel, 'mouseover', this.highlightLeft, this, true);
			YAHOO.util.Event.on(this.leftPanel, 'mouseout', this.unhighlightLeft, this, true);
		}
		this.rightPanel = YAHOO.util.Dom.getElementsByClassName('right_panel', 'div', this.element)[0];
		if (this.rightPanel) {
			this.rightArrow = this.rightPanel.firstChild.firstChild;
			this.rightArrow.originalSource = this.rightArrow.src;
			this.rightArrow.hoverSource = this.rightArrow.getAttribute('hover_src');
			YAHOO.util.Event.on(this.rightPanel, 'click', this.nextPicture, this, true);
			YAHOO.util.Event.on(this.rightPanel, 'mouseover', this.highlightRight, this, true);
			YAHOO.util.Event.on(this.rightPanel, 'mouseout', this.unhighlightRight, this, true);
		}
	},
	truncateDescription: function() {
		//we use a fixed length to make this as fast as possible
		if (this.profilePictureDescription.offsetHeight > 20) {
			var originalText = this.profilePictureDescription.innerHTML;
			var shortenedText = originalText.substr(0,40);
			shortenedText = shortenedText.replace(/[\s\,\.\?\:]+$/,"");
			shortenedText += "...";
			this.profilePictureDescription.innerHTML = shortenedText;
		}
	},
	nextPicture: function() {
		this.setCurrentPicture(this.currentPicture+1);
	},
	previousPicture: function() {
		this.setCurrentPicture(this.currentPicture-1);
	},
	highlightRight: function() {
		YAHOO.util.Dom.addClass(this.rightPanel, 'hover');
		this.rightArrow.src = this.rightArrow.hoverSource;
	},
	highlightLeft: function() {
		YAHOO.util.Dom.addClass(this.leftPanel, 'hover');
		this.leftArrow.src = this.leftArrow.hoverSource;
	},
	unhighlightRight: function() {
		YAHOO.util.Dom.removeClass(this.rightPanel, 'hover');
		this.rightArrow.src = this.rightArrow.originalSource;
	},
	unhighlightLeft: function() {
		YAHOO.util.Dom.removeClass(this.leftPanel, 'hover');
		this.leftArrow.src = this.leftArrow.originalSource;
	},
	//handles wrapping of this.currentPicture and updates the display
	setCurrentPicture: function(picture) {
		this.currentPicture = picture;
		if (this.currentPicture > this.pictures.length) {
			this.currentPicture = 1;
		} else if (this.currentPicture < 1) {
			this.currentPicture = this.pictures.length;
		}
		this.currentPictureElement.innerHTML = this.currentPicture;
		this.profilePicture.src = this.pictures[this.currentPicture-1][1];
		this.profilePictureDescription.innerHTML = Nexopia.Utilities.escapeHTML(this.pictures[this.currentPicture-1][0]);
		this.truncateDescription();
		
		var commentsLink = YAHOO.util.Dom.get("film_strip_go_to_gallery");
		if(this.profilePicture.comments_count != "")
		{
			if(this.pictures[this.currentPicture-1][2] != undefined && this.pictures[this.currentPicture-1][3] != undefined)
			{
				commentsLink.innerHTML = "Comments (" + this.pictures[this.currentPicture-1][3] + ")";
				commentsLink.href = this.pictures[this.currentPicture-1][2];
			}
			else
			{
				commentsLink.innerHTML = "";
				commentsLink.href = "";
			}
		}		
	}
};

Overlord.assign({
	minion: "userpics:classic_film_strip",
	load: ClassicFilmStrip.init,
	scope: ClassicFilmStrip
});
EditProfilePictures = {};

Overlord.assign({
	minion: "epp:add_picture",
	click: function() {
		var spinnerBody = "<div id='edit_picture_panel' class='spinner'><img src='"+Site.staticFilesURL+"/nexoskel/images/large_spinner.gif'/></div>";
		EditProfilePictures.addPictureOverlay = new YAHOO.widget.Panel("picture_edit_EditProfilePictures.addPictureOverlay", {
			fixedcenter: false,
			visible: true,
			modal:true,
			close:false,
			draggable:false,
			underlay: "none"
		});
		EditProfilePictures.addPictureOverlay.setBody(spinnerBody);
		EditProfilePictures.addPictureOverlay.render(document.body);
		EditProfilePictures.addPictureOverlay.center();
		YAHOO.util.Connect.asyncRequest('GET', '#{PageRequest.current.area_base_uri}/gallery/add_profile_pic/', new ResponseHandler({
			success: function(o) {
				YAHOO.util.Dom.get('edit_picture_panel').innerHTML = o.responseText;
				Overlord.summonMinions(document.getElementById('edit_picture_panel'));
				EditProfilePictures.addPictureOverlay.center();
			},
			failure: function(o) {
				EditProfilePictures.addPictureOverlay.destroy();
			},
			scope: this
		}));
	}
});
var FilmStripInstance = new FilmStrip();
var MIN_PIC_WIDTH = 288;

function FilmStrip(id)
{
	/*  Class Variables  */
	if(!id) {
		this.id = "film_strip";
	} else {
		this.id = id;
	}
	this.gradient = new Image();
	this.currentOffset = 0;
	this.images = new Array();
	this.scrollable = true;
	this.hasPicture = true;
	this.duration = 0.25; //time in ms for animation
	
	/*  Class Functions  */
	// Build the film strip 
	this.build = function()
	{
		this.images = YAHOO.util.Dom.getChildren(this.id + "_images");
		this.comments = YAHOO.util.Dom.getChildren(this.id + "_comments");
		
		for (var i = 0; i < this.comments.length; i++)
		{
			// We have stripped all potentially nasty characters, but we put the & back in
			// so users can use &hearts; and the like. Realistically, they aren't going to
			// hurt us in any way.
			this.comments[i].innerHTML = this.comments[i].innerHTML.replace(/&amp;/g, "&");
			new Truncator(this.comments[i]);
		}
		
		if(this.images.length <= 1) {
			if(YAHOO.util.Dom.hasClass(this.images[0], "film_strip_no_picture")) {
				this.hasPicture = false;
			}
			this.scrollable = false;
		}
		
		this.gradient.src = YAHOO.util.Dom.get(this.id + "_gradient").src;
		this.images_layer = YAHOO.util.Dom.get(this.id + "_images_wrapper");
		this.maxOffset = this.images.length - 3; //3 because the first and last images are added in twice and offsets start at 0
		
		this.overlay_canvas = YAHOO.util.Dom.get(this.id + "_overlay");
		if (!this.overlay_canvas.getContext) {
			return;
		}
		this.overlay_layer = this.overlay_canvas.getContext('2d');
		
		this.width = this.overlay_canvas.width;
		this.height = this.overlay_canvas.height;
		this.size = [this.width, this.height];
		
		this.imageWidth = this.images[0].width;
		this.imageInset = (this.width - this.images[0].width) / 2;
		
		this.build_zoom_frame();
	};
	
	this.load_images = function() 
	{
		if (!this.imagesLoaded) {
			for(var i = 0; i < this.images.length; i++)
			{
				Nexopia.DelayedImage.loadImage(this.images[i]);
				Nexopia.Utilities.withImage(this.images[i], {
					load: function(image_index) {
						if(this.images[image_index].width != MIN_PIC_WIDTH)
						{
							this.images[image_index].src = YAHOO.util.Dom.get("image_not_found_image").src;
						}
					},
					scope: this,
					args: [i]
				});
			}
			this.imagesLoaded = true;
		}
	};
	
	// Build the frame for when we click on a picture.
	this.build_zoom_frame = function()
	{
		/* Build frame in the DOM then add it. */
		var zoom_frame_wrapper = document.createElement('div');
		YAHOO.util.Dom.addClass(zoom_frame_wrapper, "film_strip_zoom_frame_wrapper");
		YAHOO.util.Dom.setStyle(zoom_frame_wrapper, 'display', 'none');
		document.body.appendChild(zoom_frame_wrapper);
		
		var zoom_frame = document.createElement('div');
		YAHOO.util.Dom.addClass(zoom_frame, "zoom_frame");
		zoom_frame_wrapper.appendChild(zoom_frame);
		
		var zoom_frame_right = document.createElement('div');
		YAHOO.util.Dom.addClass(zoom_frame_right, "frame_background");
		zoom_frame.appendChild(zoom_frame_right);
		
		var image_box = document.createElement('div');
		YAHOO.util.Dom.addClass(image_box, "image_box");
		zoom_frame.appendChild(image_box);

		var zoom_frame_image = document.createElement('img');
		image_box.appendChild(zoom_frame_image);
		
		var zoom_frame_info = document.createElement('div');
		YAHOO.util.Dom.addClass(zoom_frame_info, "zoom_frame_info");
		zoom_frame.appendChild(zoom_frame_info);
		
		var zoom_frame_title = document.createElement('div');
		YAHOO.util.Dom.addClass(zoom_frame_title, "zoom_frame_title");
		zoom_frame_info.appendChild(zoom_frame_title);
		
		var zoom_frame_actions = document.createElement('div');
		YAHOO.util.Dom.addClass(zoom_frame_actions, 'zoom_frame_actions');
		zoom_frame_info.appendChild(zoom_frame_actions);
		
		var zoom_frame_link = document.createElement('a');
		YAHOO.util.Dom.addClass(zoom_frame_link, "zoom_frame_link");
		zoom_frame_actions.appendChild(zoom_frame_link);
		YAHOO.util.Event.on(zoom_frame_info, 'click', function(e)
		{
			YAHOO.util.Event.stopPropagation(e);
		});

		
		var zoom_frame_link_image = document.createElement('img');
		zoom_frame_link_image.src = YAHOO.util.Dom.get('film_strip_gallery_zoom').src;
		zoom_frame_link_image.border = 0;
		zoom_frame_link.appendChild(zoom_frame_link_image);
		
		var zoom_frame_close = document.createElement('img');
		YAHOO.util.Dom.addClass(zoom_frame_close, "zoom_frame_close");
		zoom_frame_close.src = YAHOO.util.Dom.get('film_strip_close_zoom').src;
		zoom_frame_actions.appendChild(zoom_frame_close);
		
		/* Remember wha-wha-what we got. */
		this.zoom_frame = {};
		this.zoom_frame.animation_duration = 0.3;
		this.zoom_frame.frame = zoom_frame;
		this.zoom_frame.frame_info = zoom_frame_info;
		this.zoom_frame.title = zoom_frame_title;
		this.zoom_frame.link = zoom_frame_link;
		this.zoom_frame.wrapper = zoom_frame_wrapper;
		this.zoom_frame.image = zoom_frame_image;
		this.zoom_frame.image_box = image_box;
		
		/* Align the loading spinner */
		this.zoom_frame.loading = YAHOO.util.Dom.get('film_strip_image_loading');
		YAHOO.util.Dom.setStyle(this.zoom_frame.loading, 'opacity', 0.6);
		
		/* make the background slightly transparent */
		YAHOO.util.Dom.setStyle(YAHOO.util.Dom.getElementsByClassName('frame_background', 'div', this.zoom_frame.frame), 'opacity', '0.85');
		
		this.zoom_frame.show = function(strip_image, comment)
		{
			// Actually remove the image from the "image_box", recreate it from scratch, and then append it back
			// to the parent "image_box" so that IE will properly re-render it.
			var parent = this.image.parentNode;
			parent.removeChild(this.image);
			this.image = document.createElement("img");
			this.image.src = strip_image.attributes.img_link.value;
			parent.appendChild(this.image);
			
			// Set the comment and link to the gallery for the picture 
			this.title.innerHTML = comment.innerHTML;
			this.link.href = strip_image.attributes.dest_link.value;
			
			// strip image is the image as loaded into the film strip as opposed to the actual image
			// which may be smaller or larger than the filmstrip.
			this.strip_image = strip_image;
			this.strip_image_region = YAHOO.util.Dom.getRegion(strip_image);
						
			var obj = this;			
			// Show the spinner
			YAHOO.util.Dom.setStyle(this.loading, 'display', 'block');
			Nexopia.Utilities.withImage(this.image, { load: function()
			{
				YAHOO.util.Dom.setStyle(obj.loading, 'display', 'none');
				
				obj.frame_target_top = obj.strip_image_region.top - parseInt(YAHOO.util.Dom.getStyle(obj.image_box, 'top'), 10);
				obj.frame_target_height = obj.strip_image.height + parseInt(YAHOO.util.Dom.getStyle(obj.image_box, 'top'), 10) + parseInt(YAHOO.util.Dom.getStyle(obj.image_box, 'bottom'), 10);
				obj.frame_target_left = obj.strip_image_region.left - parseInt(YAHOO.util.Dom.getStyle(obj.image_box, 'left'), 10);
				obj.frame_target_width = obj.strip_image.width + parseInt(YAHOO.util.Dom.getStyle(obj.image_box, 'left'), 10) + parseInt(YAHOO.util.Dom.getStyle(obj.image_box, 'right'), 10);

				// The wrapper is the background layer over top of the rest of the profile.
				YAHOO.util.Dom.setStyle(obj.wrapper, 'height', YAHOO.util.Dom.getDocumentHeight() + 'px');
				YAHOO.util.Dom.setStyle(obj.wrapper, 'display', 'block');

				// Set the starting attributes for the zoom frame. 
				YAHOO.util.Dom.setStyle(obj.frame, 'opacity', 0);
				YAHOO.util.Dom.setStyle(obj.frame, 'top', obj.frame_target_top + 'px');
				YAHOO.util.Dom.setStyle(obj.frame, 'height', obj.frame_target_height + 'px');
				YAHOO.util.Dom.setStyle(obj.frame, 'left', obj.frame_target_left + 'px');
				YAHOO.util.Dom.setStyle(obj.frame, 'width', obj.frame_target_width + 'px');

				obj.zoom_in();
				
				YAHOO.util.Event.removeListener(obj.image, 'load');
			}});
		};
		
		this.zoom_frame.zoom_in = function()
		{
			// Get the right size for the image in the frame
			var margin = 80;
			
			// max height/width is the size of browser window we have available to use.
			var max_width = YAHOO.util.Dom.getViewportWidth() - margin;
			var max_height = YAHOO.util.Dom.getViewportHeight() - margin;

			// Eventual size of the zoom frame is the lesser of the max size and the image size.
			var goal_width = Math.min(this.image.width, max_width);
			var goal_height = Math.min(this.image.height, max_height);

			// these ratios tell us if it's a portait or landscape picture.
			var goal_size_ratio = goal_width / goal_height;
			var image_size_ratio = this.image.width / this.image.height;
			
			// Scale the image to preserve aspect ratio.
			if (goal_size_ratio > image_size_ratio) {
				goal_width = goal_height * image_size_ratio;
			} else {
				goal_height = goal_width / image_size_ratio;
			}
			
			if (image_size_ratio > 1) {
				YAHOO.util.Dom.setStyle(this.image, 'height', goal_height + 'px'); // landscape
			} else {
				YAHOO.util.Dom.setStyle(this.image, 'width', goal_width + 'px'); // portrait
			}

			// If the image is smaller than the image in the filmstrip then we want to make the
			// frame bigger so we can get the whole comment in.
			// We do this at this point so that the zoom frame will zoom to the correct location.
			if (goal_width < MIN_PIC_WIDTH) { goal_width = MIN_PIC_WIDTH; }
			
			var goal_left = Math.round((YAHOO.util.Dom.getViewportWidth() - goal_width) / 2) + YAHOO.util.Dom.getDocumentScrollLeft();
			var goal_top = Math.round((YAHOO.util.Dom.getViewportHeight() - goal_height) / 4) + YAHOO.util.Dom.getDocumentScrollTop();
			
			// Calculate the total width of the image border that goes around the image so that this can
			// be factored into the calculation the size of the zoomed image. Note that IE 6 deals with
			// things a bit differently, so we actually don't want to do the calculation if the user is
			// viewing the page with that browser.
			var picture_border_adjustment = 0;
			var frame_info_height_adjustment = 0;
			if (!(YAHOO.env.ua.ie > 5 && YAHOO.env.ua.ie < 7))
			{
				picture_border_adjustment = this.frame.offsetWidth - this.image_box.offsetWidth;
				frame_info_height_adjustment = this.frame_info.offsetHeight;
			}

			// zoom the frame				
			// Set the destination size/location of the zoom frame.
			var attributes = {
				points: { to: [goal_left, goal_top] },
				height: { to: Math.floor(goal_height + picture_border_adjustment + frame_info_height_adjustment) },
				width: { to: Math.floor(goal_width + picture_border_adjustment) },
				opacity: { to: 1 }
			};
			var anim = new YAHOO.util.Motion(this.frame, attributes, this.animation_duration, YAHOO.util.Easing.easeBoth);
			
			var obj = this;
			anim.onComplete.subscribe(function()
			{
				YAHOO.util.Dom.setStyle(obj.image, 'opacity', '1');
				YAHOO.util.Dom.setStyle(obj.frame_info, 'opacity', '1');
			});
			anim.animate();
			
			new YAHOO.util.Scroll(this.image_box, { scroll: { from: [this.image.width/2 - this.strip_image.width/2, this.image.height/2 - this.strip_image.height/2], to: [0, 0] } }, this.animation_duration, YAHOO.util.Easing.easeBoth).animate();
		};
		
		this.zoom_frame.hide = function()
		{
			YAHOO.util.Dom.setStyle(this.image, 'height', 'auto');
			YAHOO.util.Dom.setStyle(this.image, 'width', 'auto');
		
			var obj = this;
			var attributes = {
				points: { to: [this.frame_target_left, this.frame_target_top] },
				height: { to: this.frame_target_height },
				width: { to: this.frame_target_width },
				opacity: { to: 0 }
			};
			var anim = new YAHOO.util.Motion(this.frame, attributes, this.animation_duration, YAHOO.util.Easing.easeBoth);
			anim.onComplete.subscribe(function()
			{
				YAHOO.util.Dom.setStyle(obj.wrapper, 'display', 'none');
			});
			anim.animate();

			new YAHOO.util.Scroll(this.image_box, { scroll: { to: [this.image.width/2 - this.strip_image.width/2, this.image.height/2 - this.strip_image.height/2] } }, this.animation_duration, YAHOO.util.Easing.easeBoth).animate();
		};
		
		// If they click somewhere outside the image close the zoom window.
		YAHOO.util.Event.on(this.zoom_frame.wrapper, 'click', function(e, zoom_frame) {
			zoom_frame.hide();
		}, this.zoom_frame);
		
		// If they click the 'close' icon close the zoom window
		YAHOO.util.Event.on( YAHOO.util.Dom.getElementsByClassName('zoom_frame_close', null, this.zoom_frame.frame_info), 'click', function(e, zoom_frame) {
			zoom_frame.hide();
		}, this.zoom_frame);
		
	};
	
	this.draw = function()
	{
		//alert('draw');
		this.redrawOverlay();
		//alert('overlay')
		//alert('drawImages')
		this.setPage();
	};
	
	this.scrollToImage = function()
	{
		if (!this.scrollInitialized) {
			document.getElementById("film_strip_images").style.left = "0px";
			this.images_layer.scrollLeft = this.imageWidth - this.imageInset;
			document.getElementById("film_strip_comments").style.left = "0px";
			document.getElementById("film_strip_comments_wrapper").scrollLeft = this.width;
			this.scrollInitialized = true;
		}
		
		var picturesAnim;
		var scrollTo;

		if(this.currentOffset < 0)
		{ //moving from the first image to the last image
			this.currentOffset = this.maxOffset;
			scrollTo = this.imageWidth * (-0.5) + (this.imageWidth - this.imageInset);
			picturesAnim = new YAHOO.util.Scroll(this.images_layer, { scroll: { to: [scrollTo,0] } }, this.duration/2, YAHOO.util.Easing.easeIn);
			picturesAnim.onComplete.subscribe(function() {
				scrollTo = this.imageWidth * (this.maxOffset+0.5) + (this.imageWidth - this.imageInset);
				this.images_layer.scrollLeft = scrollTo;
				scrollTo = this.imageWidth * this.maxOffset + (this.imageWidth - this.imageInset);
				picturesAnim = new YAHOO.util.Scroll(this.images_layer, { scroll: { to: [scrollTo,0] } }, this.duration/2, YAHOO.util.Easing.easeOut);
				picturesAnim.animate();
				
			}, this, true);
			picturesAnim.animate();
			var commentsAnim = new YAHOO.util.Scroll("film_strip_comments_wrapper", { scroll: { to: [0, 0] } }, this.duration, YAHOO.util.Easing.easeBoth);
			commentsAnim.onComplete.subscribe(function() {
				YAHOO.util.Dom.get("film_strip_comments_wrapper").scrollLeft = (this.maxOffset+1)*this.width;
			}, this, true);
			commentsAnim.animate();
		}
		else if(this.currentOffset > this.maxOffset)
		{ //moving from the last image to the first image
			this.currentOffset = 0;
			scrollTo = this.imageWidth * (this.maxOffset+0.5) + (this.imageWidth - this.imageInset);
			picturesAnim = new YAHOO.util.Scroll(this.images_layer, { scroll: { to: [scrollTo,0] } }, this.duration/2, YAHOO.util.Easing.easeIn);
			picturesAnim.onComplete.subscribe(function() {
				scrollTo = this.imageWidth * (-0.5) + (this.imageWidth - this.imageInset);
				this.images_layer.scrollLeft = scrollTo;
				scrollTo = this.imageWidth - this.imageInset;
				picturesAnim = new YAHOO.util.Scroll(this.images_layer, { scroll: { to: [scrollTo,0] } }, this.duration/2, YAHOO.util.Easing.easeOut);
				picturesAnim.animate();
				
			}, this, true);
			picturesAnim.animate();
			var commentsAnim = new YAHOO.util.Scroll("film_strip_comments_wrapper", { scroll: { to: [((this.maxOffset+2) * this.width), 0] } }, this.duration, YAHOO.util.Easing.easeBoth);
			commentsAnim.onComplete.subscribe(function() {
				YAHOO.util.Dom.get("film_strip_comments_wrapper").scrollLeft = this.width;
			}, this, true);
			commentsAnim.animate();
		} else {
			scrollTo = this.imageWidth * this.currentOffset + (this.imageWidth - this.imageInset);
			picturesAnim = new YAHOO.util.Scroll(this.images_layer, { scroll: { to: [scrollTo,0] } }, this.duration, YAHOO.util.Easing.easeBoth);
			picturesAnim.animate();
			var commentsAnim = new YAHOO.util.Scroll("film_strip_comments_wrapper", { scroll: { to: [((this.currentOffset+1) * this.width), 0] } }, this.duration, YAHOO.util.Easing.easeBoth);
			commentsAnim.animate();
		}
	};
	
	this.drawImages = function()
	{
		if(this.scrollable)
		{
			this.scrollToImage();
			this.setPage();
		}
	};
	
	this.setPage = function()
	{
		var commentsLink = YAHOO.util.Dom.get("film_strip_go_to_gallery");
		var index = (this.currentOffset + 1) % (this.maxOffset + 1);
		
		if(this.images.length > 0 && this.images[index].attributes.comments_count.value != "")
		{	
			commentsLink.innerHTML = "Comments (" + this.images[index].attributes.comments_count.value + ")";
			commentsLink.href = this.images[index].attributes.dest_link.value;
		}
		
		if(this.images.length > 1 ) {
			YAHOO.util.Dom.get("film_strip_page").innerHTML = (this.currentOffset + 1) + " of " + (this.maxOffset + 1);
		}
	};
	
	this.redrawOverlay = function(left, right)
	{
		if(!left) {
			left = 0.1;
		}
			
		if(!right && right != 0) {
			right = left;
		}
		
		this.overlay_layer.clearRect(0, 0, this.width, this.height);
		this.drawGradient();
		
		this.overlay_layer.fillStyle = "rgba(0,0,0,0.8)";
		this.overlay_layer.fillRect(0,this.height - 20, this.width, 20);
		
		if(this.scrollable) {
			this.drawSlideControls(left, right);
		}
	};
	
	this.drawGradient = function()
	{
		this.overlay_layer.drawImage(this.gradient, 0, 0, this.overlay_canvas.width, this.overlay_canvas.height);
	};
	
	// Draw the plus and minus on the right and left of the image slider.
	this.drawSlideControls = function(left, right)
	{
		var inset = 6;
		var size = 60;
		
		this.overlay_layer.lineWidth = 4;
		
		this.overlay_layer.strokeStyle = "rgba(255,255,255,"+left+")";
		this.overlay_layer.beginPath();
		this.overlay_layer.moveTo(inset, this.overlay_canvas.height / 2);
		this.overlay_layer.lineTo((inset + size), this.overlay_canvas.height / 2);
		this.overlay_layer.closePath();
		this.overlay_layer.stroke();
		
		this.overlay_layer.save();
			this.overlay_layer.scale(-1, 1);
			this.overlay_layer.translate(-this.overlay_canvas.width, 0);
			
			this.overlay_layer.strokeStyle = "rgba(255,255,255,"+right+")";
			this.overlay_layer.beginPath();
			this.overlay_layer.moveTo(inset, this.overlay_canvas.height / 2);
			this.overlay_layer.lineTo((inset + size), this.overlay_canvas.height / 2);
			this.overlay_layer.closePath();
			this.overlay_layer.stroke();
			
			this.overlay_layer.beginPath();
			this.overlay_layer.moveTo(inset + size/2, this.overlay_canvas.height / 2 - size / 2);
			this.overlay_layer.lineTo(inset + size/2, this.overlay_canvas.height / 2 - this.overlay_layer.lineWidth/2);
			this.overlay_layer.closePath();
			this.overlay_layer.stroke();
			
			this.overlay_layer.beginPath();
			this.overlay_layer.moveTo(inset + size/2, this.overlay_canvas.height / 2 + size / 2);
			this.overlay_layer.lineTo(inset + size/2, this.overlay_canvas.height / 2 + this.overlay_layer.lineWidth/2);
			this.overlay_layer.closePath();
			this.overlay_layer.stroke();
		this.overlay_layer.restore();
	};
	
	this.getXY = function()
	{
		return YAHOO.util.Dom.getXY(this.id);
	};

	this.fixCoordinates = function(inValue)
	{
		var outValue = new Array();
		outValue[0] = inValue[0] - this.getXY()[0];
		outValue[1] = inValue[1] - this.getXY()[1];
		
		return outValue;
	};
	
	this.init = function(e)
	{
		if (!document.getElementById(this.id)) {
			return;
		}
		this.build();
		this.draw();
		
		YAHOO.util.Event.on(this.id + "_handle", 'click', function(e)
		{
			YAHOO.util.Event.preventDefault(e);
			this.load_images();
			var pos = this.fixCoordinates(YAHOO.util.Event.getXY(e));
			
			var images = null;
			var which = null;
			var comments = null;
			
			if(pos[0] >  this.width - 70 && pos[1] > this.height - 20)
			{
				images = YAHOO.util.Dom.getChildren(this.id + "_images");
				
				which = ((this.currentOffset + 1) % images.length);
				
				window.location = images[which].attributes.dest_link.value;
			}
			else if(pos[0] > (this.width - this.imageInset))
			{
				this.currentOffset++;
				if(this.scrollable) {
					this.drawImages();
				}
			}
			else if(pos[0] < this.imageInset)
			{
				this.currentOffset--;
				if(this.scrollable) {
					this.drawImages();
				}
			}
			else
			{
				images = YAHOO.util.Dom.getChildren(this.id + "_images");
				comments = YAHOO.util.Dom.getChildren(this.id + "_comments");
				
				which = ((this.currentOffset + 1) % images.length);
				this.zoom_frame.show(images[which], comments[which]);
			}
		}, this, true);
		
		YAHOO.util.Event.on(this.id + "_handle", 'mouseover', function(e)
		{
			var pos = this.fixCoordinates(YAHOO.util.Event.getXY(e));
		}, this, true);
		
		YAHOO.util.Event.on(this.id + "_handle", 'mouseout', function(e)
		{
			var pos = this.fixCoordinates(YAHOO.util.Event.getXY(e));
			
			this.redrawOverlay(0.1);
		}, this, true);
		
		YAHOO.util.Event.on(this.id + "_handle", 'mousemove', function(e)
		{
			var pos = this.fixCoordinates(YAHOO.util.Event.getXY(e));
			
			if(pos[0] >  this.width - 70 && pos[1] > this.height - 20)
			{
				this.redrawOverlay(0.1);
			}
			else if(pos[0] > (this.width - this.imageInset)) // right side
			{
				this.redrawOverlay(0.1, 0.3);
			}
			else if(pos[0] < this.imageInset) // left side
			{
				this.redrawOverlay(0.3, 0.1);
			}
			else // middle
			{
				this.redrawOverlay(0.1);
			}
		}, this, true);
	};
}
Overlord.assign({
	minion: "userpics:film_strip",
	load: FilmStripInstance.init,
	scope: FilmStripInstance,
	init: 'load'
});
if(YAHOO.profile == undefined){
	YAHOO.namespace ("profile");
}

YAHOO.profile.FilmStripInPlaceEdit = {
	init: function()
	{
		var type_dropdown = document.getElementById("film_strip_choice");
		
		if(type_dropdown)
		{
			YAHOO.util.Event.addListener(type_dropdown, "change", YAHOO.profile.FilmStripInPlaceEdit.save_film_strip_choice, null, this);
		}
	},
	
	save_film_strip_choice: function(e)
	{
		var type_form = document.getElementById("film_strip_choice_form");
		var type_dropdown = document.getElementById("film_strip_choice");
		
		YAHOO.util.Connect.setForm(type_form);
		YAHOO.util.Connect.asyncRequest(type_form.method, type_form.action, {
			success: function(o) {
			},
			failure: function(o) {
				alert("Saving of Profile Pic type failed.")
			},
			scope: this
		}, "");
	}
};

Overlord.assign({
	minion: "userpics:film_strip_profile_edit_view",
	load: function(element) {
		YAHOO.profile.FilmStripInPlaceEdit.init();
	}
});
//require edit_profile_pictures.js

//////////////////////////////////////////////////////////////////////////////
// This is based largely on the drag and drop list reordering example from the
// yui docs.
//////////////////////////////////////////////////////////////////////////////

EditProfilePictures.ProfilePicture = function(id, sGroup, config) {

    EditProfilePictures.ProfilePicture.superclass.constructor.call(this, id, sGroup, config);

    this.logger = this.logger || YAHOO;
    var el = this.getDragEl();
    YAHOO.util.Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent

    this.goingUp = false;
    this.lastY = 0;
};

YAHOO.extend(EditProfilePictures.ProfilePicture, YAHOO.util.DDProxy, {

    startDrag: function(x, y) {
        this.logger.log(this.id + " startDrag");

        // make the proxy look like the source element
        var dragEl = this.getDragEl();
        var clickEl = this.getEl();
        YAHOO.util.Dom.setStyle(clickEl, "visibility", "hidden");

        dragEl.innerHTML = clickEl.innerHTML;

        YAHOO.util.Dom.setStyle(dragEl, "color", YAHOO.util.Dom.getStyle(clickEl, "color"));
        YAHOO.util.Dom.setStyle(dragEl, "backgroundColor", YAHOO.util.Dom.getStyle(clickEl, "backgroundColor"));
        YAHOO.util.Dom.setStyle(dragEl, "border", "2px solid gray");
    },

    endDrag: function(e) {

        var srcEl = this.getEl();
        var proxy = this.getDragEl();

        // Show the proxy element and animate it to the src element's location
        YAHOO.util.Dom.setStyle(proxy, "visibility", "");
        var a = new YAHOO.util.Motion(proxy, { 
                points: { 
                    to: YAHOO.util.Dom.getXY(srcEl)
                }
            }, 
            0.2, 
            YAHOO.util.Easing.easeOut 
        );
        var proxyid = proxy.id;
        var thisid = this.id;

		var position = 1;
		for (var i=0; i<srcEl.parentNode.childNodes.length; i++) {
			var node = srcEl.parentNode.childNodes[i];
			if (node.nodeName.toLowerCase() != "li") {
				continue;
			}
			if (srcEl == node) {
				break;
			}
			position++;
		}
		
		var form_key = YAHOO.util.Dom.get('form_key').value;
		
		YAHOO.util.Connect.asyncRequest('POST', Nexopia.areaBaseURI() + '/pictures/move/'+Nexopia.json(srcEl).gallerypicid+"/to/"+position, 
			new ResponseHandler({}), "refresh=edit_profile_pictures&form_key[]=" + form_key);

        // Hide the proxy and show the source element when finished with the animation
        a.onComplete.subscribe(function() {
                YAHOO.util.Dom.setStyle(proxyid, "visibility", "hidden");
                YAHOO.util.Dom.setStyle(thisid, "visibility", "");
            });
        a.animate();
    },

    onDrag: function(e) {

        // Keep track of the direction of the drag for use during onDragOver
        var y = YAHOO.util.Event.getPageY(e);

        if (y < this.lastY) {
            this.goingUp = true;
        } else if (y > this.lastY) {
            this.goingUp = false;
        }

        this.lastY = y;
    },

    onDragOver: function(e, id) {
    
        var srcEl = this.getEl();
        var destEl = YAHOO.util.Dom.get(id);

        // We are only concerned with list items, we ignore the dragover
        // notifications for the list.
        if (destEl.nodeName.toLowerCase() == "li") {
            var orig_p = srcEl.parentNode;
            var p = destEl.parentNode;

            if (this.goingUp) {
                p.insertBefore(srcEl, destEl); // insert above
            } else {
                p.insertBefore(srcEl, destEl.nextSibling); // insert below
            }
            YAHOO.util.DragDropMgr.refreshCache();
        }
    }
});

Overlord.assign({
	minion: "epp:profile_picture",
	load: function(el) {
		new EditProfilePictures.ProfilePicture(el);
	}
});

Overlord.assign({
	minion: "epp:remove_link",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		YAHOO.util.Connect.asyncRequest('POST', element.href, new ResponseHandler({}), "refresh=edit_profile_pictures");
	}
});
YoutubeSearchModule={};

YouTubeSearch = {
	
	find_videos: function(event, element) {
		
		if( event ) { YAHOO.util.Event.preventDefault(event); }
		
		var search_terms = document.getElementById("search_terms"); 
		if( (search_terms != "") && (search_terms != null)) {

			var spinner = document.getElementById("search_spinner");
			if( spinner ) { YAHOO.util.Dom.setStyle(spinner, "display", "block"); }

			var search_form = document.getElementById("youtube_search_form");
			YAHOO.util.Connect.setForm(search_form);
			YAHOO.util.Connect.asyncRequest(search_form.method, search_form.action, new ResponseHandler({
				success: function(o) {
					var spinner = document.getElementById("search_spinner");
					if( spinner ) { YAHOO.util.Dom.setStyle(spinner, "display", "none"); }
				},
				failure: function(o) {
					var spinner = document.getElementById("search_spinner");
					if( spinner ) { YAHOO.util.Dom.setStyle(spinner, "display", "none"); }
				},
				scope: this
			}), "");
			
		}
	},
	
	add_video: function(event, element) {

		var result_container = YAHOO.util.Dom.getAncestorByClassName(element, 'video_container');
		// remove the 'video_' bit from the container id to get the index
		var video_id = parseInt(result_container.getAttribute('id').slice(6), 10);
		var embed_code = document.getElementById("embed_" + video_id).value;

		var return_location = document.getElementById("return_location");
		var embed_input = document.getElementById(return_location.value);
		embed_input.value = embed_code.replace(/[\r\n]/g, ' ');;
		

		NexopiaPanel.current.close();
	}
	
};

Overlord.assign({
	minion: "youtube:add_video",
	click: YouTubeSearch.add_video,
	scope: YouTubeSearch
});

Overlord.assign({
	minion: "youtube:find_videos",
	submit: YouTubeSearch.find_videos,
	scope: YouTubeSearch
	
});
JsonModule={};

BlogsModule={};

Overlord.assign({
	minion: "blogs:submit_new",
	click: function(event) {
		YAHOO.util.Event.preventDefault(event);
		YAHOO.util.Dom.get('new_blog').submit();
	}
});

Overlord.assign({
	minion: "blogs:youtube_close",
	click: function(event) {
		YAHOO.util.Event.preventDefault(event);
		NexopiaPanel.current.close();
	}
});


Overlord.assign({
	minion: "blogs:tip",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		var tip = element.nextSibling;
		if (tip) {
			if (YAHOO.util.Dom.getStyle(tip, 'display') == "none") {
				YAHOO.util.Dom.setStyle(tip, 'display', 'block');
			} else {
				YAHOO.util.Dom.setStyle(tip, 'display', 'none');
			}
		}
	}
});

Overlord.assign({
	minion: "blogs:options",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		var tip = element.nextSibling;
		if (tip) {
			if (YAHOO.util.Dom.getStyle(tip, 'display') == "none") {
				YAHOO.util.Dom.setStyle(tip, 'display', 'block');
				element.innerHTML = "Fewer Options";
				element.className = "collapse";
			} else {
				YAHOO.util.Dom.setStyle(tip, 'display', 'none');
				element.innerHTML = "More Options";
				element.className = "expand";
			}
		}
	}
});
Overlord.assign({
	minion: "blogs:battle:changetab:ignore",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
	}
});

Overlord.assign({
	minion: "blogs:battle:changetab:photo",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		YAHOO.util.Dom.setStyle('blog_battle_video', 'display', 'none');
		YAHOO.util.Dom.setStyle('blog_battle_photo', 'display', 'inline');
		YAHOO.util.Dom.setStyle('blog_tip_battle_video', 'display', 'none');
		YAHOO.util.Dom.setStyle('blog_tip_battle_photo', 'display', 'inline');
		
		document.getElementById('battletype').value = 'photo';
		
		document.getElementById('video_title').name = 'video_title';
		document.getElementById('video_caption_1').name = 'video_caption_1';
		document.getElementById('video_caption_2').name = 'video_caption_2';
		document.getElementById('video_link_1').name = 'video_link_1';
		document.getElementById('video_link_2').name = 'video_link_2';
		
		document.getElementById('photo_title').name = 'blog_post_title';
		document.getElementById('photo_caption_1').name = 'caption_1';
		document.getElementById('photo_caption_2').name = 'caption_2';
		document.getElementById('blog_post_photo_link_photo_1').name = 'link_1';
		document.getElementById('blog_post_photo_link_photo_2').name = 'link_2';
	}
});

Overlord.assign({
	minion: "blogs:battle:changetab:video",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}

		YAHOO.util.Dom.setStyle('blog_battle_video', 'display', 'inline');
		YAHOO.util.Dom.setStyle('blog_battle_photo', 'display', 'none');
		YAHOO.util.Dom.setStyle('blog_tip_battle_video', 'display', 'inline');
		YAHOO.util.Dom.setStyle('blog_tip_battle_photo', 'display', 'none');
		
		document.getElementById('battletype').value = 'video';
		
		document.getElementById('photo_title').name = 'photo_title';
		document.getElementById('photo_caption_1').name = 'photo_caption_1';
		document.getElementById('photo_caption_2').name = 'photo_caption_2';
		document.getElementById('blog_post_photo_link_photo_1').name = 'photo_link_1';
		document.getElementById('blog_post_photo_link_photo_2').name = 'photo_link_2';
		
		document.getElementById('video_title').name = 'blog_post_title';
		document.getElementById('video_caption_1').name = 'caption_1';
		document.getElementById('video_caption_2').name = 'caption_2';
		document.getElementById('video_link_1').name = 'link_1';
		document.getElementById('video_link_2').name = 'link_2';
	}
});

function blogs_battle_validate(type) {
	var questionField = null;
	if (document.getElementById('photo_title').name == 'blog_post_title') {
		questionField = document.getElementById('photo_title');
	} else if (document.getElementById('video_title').name == 'blog_post_title'){
		questionField = document.getElementById('video_title');
	}
	if (questionField.value == "") {
		alert('You need to enter a title before you can ' + type);
		return false;
	}
	return true;
}

function blogs_video_battle_validate(type) {
	if ((Nexopia.Utilities.trim(document.getElementById('video_link_1').value) == '') ||
	   (Nexopia.Utilities.trim(document.getElementById('video_link_2').value) == '') ) {
		alert('You need to enter a video embed code.');
		return false;
	}
	return true;
}

function blogs_photo_battle_validate(type) {
	if ( (document.getElementById('blog_post_photo_link_photo_1').value == '') || (document.getElementById('blog_post_photo_link_photo_2').value == '') ) {
		alert('You need to enter a photo link.');
		return false;
	}
	return true;
}

function blogs_battle_video_validate_preview() {
	return blogs_battle_validate('preview');
}

function blogs_battle_photo_validate_preview() {
	return blogs_battle_validate('preview');
}

Overlord.assign({
	minion: "blogs:battle_create:video:post",
	click: function(event) {
		var visibility = document.getElementById('blog_post_visibility').value;
		var valid = blogs_battle_validate('save') && blogs_video_battle_validate('save');
		if (!valid && event) {
			YAHOO.util.Event.preventDefault(event);
		}
		return valid;
	}
});

Overlord.assign({
	minion: "blogs:battle_create:photo:post",
	click: function(event) {
		var visibility = document.getElementById('blog_post_visibility').value;
		var valid = blogs_battle_validate('save') && blogs_photo_battle_validate('save');
		if (!valid && event) {
			YAHOO.util.Event.preventDefault(event);
		}
		return valid;
	}
});

Overlord.assign({
	minion: "blogs:battle:video:preview",
	load: function(event) {
		// We want to prevalidate before allowing preview.
		NexopiaPanel.linkBeforeOpenMap['blogs_battle_video_preview'] =
			blogs_battle_video_validate_preview;
	}
});

Overlord.assign({
	minion: "blogs:battle:photo:preview",
	load: function(event) {
		// We want to prevalidate before allowing preview.
		NexopiaPanel.linkBeforeOpenMap['blogs_battle_photo_preview'] =
			blogs_battle_photo_validate_preview;
	}
});

Overlord.assign({
	minion: "blogs:battle_vote:skip",
	click: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		var submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'blog_profile_battle');
		if (submit_page == null) {
			submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'public_feed_battle');
		}
		if (submit_page == null) {
			submit_page = 'blog_poll';
		} else {
			submit_page = submit_page.className;
		}
			
		var form = YAHOO.util.Dom.getAncestorByTagName(element, 'form');
		YAHOO.util.Connect.setForm(form);
		YAHOO.util.Connect.asyncRequest("POST",
			this.href, new ResponseHandler({}), 'ajax=true&submit_page=' + submit_page);
	}
});

Overlord.assign({
	minion: "blogs:battle_vote:vote",
	click: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		var submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'blog_profile_battle');
		if (submit_page == null) {
			submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'public_feed_battle');
		}
		if (submit_page == null) {
			submit_page = 'blog_poll';
		} else {
			submit_page = submit_page.className;
		}
		
		
		// Let's check that the user actually selected an option
		var vote_id = this.parentNode.parentNode.parentNode.id;
		var radios = document.getElementsByName('vote_' + vote_id);
		var anyChecked = false;
		for (var i = 0; i < radios.length; i++) {
			if (radios[i].checked) {
				anyChecked = true;
				break;
			}
		}
		if (!anyChecked) {
			alert("You need to select an option before you can vote.");
			return false;
		}
		// Good to go, let's vote!
		vote_id = vote_id.replace('_', '/');
		var form = YAHOO.util.Dom.getAncestorByTagName(element, 'form');
		var post_url = form.action + vote_id + "/battle_vote";
		var post_params = 'ajax=true&submit_page=' + submit_page;

		YAHOO.util.Connect.setForm(form);		
		YAHOO.util.Connect.asyncRequest("POST",	post_url,
			new ResponseHandler({}), post_params);
	}
});

Overlord.assign({
	minion: "blogs:battle:photo:caption_1",
	blur: function(event) {
		if (Nexopia.Utilities.trim(this.value) == '') this.value = 'Photo 1';
	}
});

Overlord.assign({
	minion: "blogs:battle:photo:caption_2",
	blur: function(event) {
		if (Nexopia.Utilities.trim(this.value) == '') this.value = 'Photo 2';
	}
});

Overlord.assign({
	minion: "blogs:battle:video:caption_1",
	blur: function(event) {
		if (Nexopia.Utilities.trim(this.value) == '') this.value = 'Video 1';
	}
});

Overlord.assign({
	minion: "blogs:battle:video:caption_2",
	blur: function(event) {
		if (Nexopia.Utilities.trim(this.value) == '') this.value = 'Video 2';
	}
});

Overlord.assign({
	minion: "blog:year_selector",
	change: function(element){
		var yearURL = this.options[this.selectedIndex].value;
		location.href = yearURL;
	}
});

Overlord.assign({
	minion: "blog:calendar_post_link",
	click: function(event, element){
		var link = YAHOO.util.Dom.getElementBy(function(el){return true;},'a', element);
		// Link returns null if user clicks on a box without a link
		if (link != null && link != "")
			location.href = link.href;
	}
})
if(YAHOO.blog == undefined){
	YAHOO.namespace ("blog");
}

YAHOO.blog.BlogComments =
{
	/*
			This function contains all the fun for displaying the reply enhanced text editor. In addition to
			moving the editor around the page we also have to resize it to ensure it fits and resize the smilies
			tab so it scrolls properly. We also need to adjust the form action so it posts to the proper place 
			(and replies to the correct comment).
	*/
	show_reply_editor: function(e)
	{
		YAHOO.util.Event.preventDefault(e);
		
		var target = YAHOO.util.Event.getTarget(e);
		
		var editor = document.getElementById("blog_comment_editor");
		
		var id_parts = target.id.split("_");
		var comment_id = id_parts[3];
		
		var comment = document.getElementById("blog_comment_"+comment_id);
		
		var actual_comment = YAHOO.util.Dom.getElementsByClassName("single_comment_wrapper", "div", comment, function(e){})[0];

		var comment_width = YAHOO.util.Dom.getRegion(comment).width;		
		var indent = YAHOO.util.Dom.getStyle(comment, "margin-left");
		comment_width = parseInt(comment_width, 10) - parseInt(indent, 10);

		//calculate the editor width. Use of magic number is needed. The picture is 100px wide plus 12px padding, thus the 112px.
		//var text_editor_width = parseInt(comment_width, 10) - 112;
		var text_editor_width = comment_width - 112;

		// default text_editor_size to width of parent comment - picture - padding - default indent margin (15px)
		if( isNaN(text_editor_width) ) {
			text_editor_width = comment.offsetWidth - 112 - 15; 
		}

		//Reconfigure the form action path
		var base_url = document.getElementById("blog_base_comment_url");
		var editor_form = document.getElementById("dynamic_blog_comment_form");
		base_url = base_url.value;		
		base_url = base_url +"/" + comment_id + "/submit";
		editor_form.action = base_url;
		
		var text_editor = YAHOO.util.Dom.getElementsByClassName("enhanced_text_box_wrapper", "div", editor_form, null)[0];
		
		//Reinitialize the smilies tab
		var smilies_container = YAHOO.util.Dom.getElementsByClassName("smilies", "div", "dynamic_blog_comment_form")[0];
		var editor_tab_body = smilies_container.parentNode;

		editor_tab_body.removeChild(smilies_container);
		
		var editor_obj = Nexopia.enhanced_text_editor_list['blog_comment_content'];
		editor_obj.text_box_width = text_editor_width;
		var pop = editor_obj.population();

		var new_smilies = editor_obj.build_smilies(pop[3].content[0], editor_tab_body);
		editor_tab_body.appendChild(new_smilies);
		
		//Move the editor back to the first tab and clear any input from the textarea
		editor_obj.activate_tab(0);
		editor_obj.text_box.value = "";
		
		editor.parentNode.removeChild(editor);
		
		/*
			We have to resize the editor and the text field within for IE. If we don't the edges
			of the editor extend outside of the bounds of the container. It only gets worse the
			further the comment is indented.
		*/
		
		YAHOO.util.Dom.setStyle(editor, "margin-left", indent);
		YAHOO.util.Dom.setStyle(editor, "width", comment_width + "px");
		YAHOO.util.Dom.setStyle(text_editor, "width", text_editor_width + "px");		

		YAHOO.util.Dom.insertAfter(editor, actual_comment);
		YAHOO.util.Dom.setStyle(editor, "display", "block");
		YAHOO.util.Dom.setStyle(editor, "overflow", "hidden");
		
		editor_obj.text_box.focus();
		
	},
	
	post_comment: function(e)
	{
		if (e) {
			YAHOO.util.Event.preventDefault(e);
		}
		
		var editor_form = document.getElementById("dynamic_blog_comment_form");
		
		YAHOO.util.Connect.setForm(editor_form);
		YAHOO.util.Connect.asyncRequest(editor_form.method, editor_form.action + "/dynamic", new ResponseHandler({
			success: function(o) {
				YAHOO.blog.BlogComments.update_comments_view(o);
			},
			failure: function(o) {
			},
			scope: this
		}), "");
	},
	
	
	/*
		This function handles explicitly setting the width for blog comments. This prevents large images
		from spilling out and breaking the layout. This needs a javascript solution because the width of
		blog comments varies depending on their depth in the tree. As such a simple CSS fix won't do.
		
		We need to keep the CSS workaround in place for non javascript users. It's not pretty, but it
		makes the blog comments still usable.
	*/
	handle_comment_overflow: function(root_element)
	{
		var i;
		var temp;
		
		for(i=0; i < root_element.childNodes.length; i++)
		{
			temp = root_element.childNodes[i];
			YAHOO.blog.BlogComments.set_element_width(temp, 0);
		}
	},

	set_element_width: function(element, depth)
	{
		var i;
		var comment_regex = /^blog_comment_\d*$/;
		var temp;
		var temp_width;
		var max_width = YAHOO.blog.BlogComments.blog_comment_width();
		var comment_indent = 15;
		
		if(element.id && element.id.match(comment_regex))
		{
			/*
				We use the max width as the actual width of one of the blog_container elements. It's the nearest
				parent element to the blog comment with a specified width. Once we grab that we can figure out
				the width of the blog comment. Knowing this allows us to use static values for the widths of the
				comment content and comment body elements. We know they are 122px and 128px smaller, respectively.
				
				We could try to figure out dynamically the amount those elements are smaller, however this would be 
				difficult as we'd have to try to get all the margins, paddings, and borders accounted for in all 
				of the relevant parent elements prior to calculating the width.
				
				With that being an expensive task, this function will have to be manually updated if we change the
				display of blog comments.
			*/
			temp_width = max_width-depth*comment_indent;
			YAHOO.util.Dom.setStyle(element, "width", temp_width +"px");
			YAHOO.util.Dom.setStyle(element, "overflow", "hidden");
			
			var content = YAHOO.util.Dom.getElementsByClassName("comment_content", "div", element, null)[0];
			var content_width = max_width - 122 - depth*comment_indent;
			YAHOO.util.Dom.setStyle(content, "width", content_width + "px");
			
			var comment_body = YAHOO.util.Dom.getElementsByClassName("comment_body", "div", content, null)[0];
			var body_width = max_width - 128 - depth*comment_indent;
			YAHOO.util.Dom.setStyle(comment_body, "width", body_width + "px");
			
			for(i=0; i < element.childNodes.length; i++)
			{
				temp = element.childNodes[i];
				YAHOO.blog.BlogComments.set_element_width(temp, depth+1);
			}
		}
	},
		
	blog_comment_width: function()
	{
		if(!YAHOO.blog.BlogComments.blog_width)
		{
			var temp_list = YAHOO.util.Dom.getElementsByClassName("blog_container", "div", "blog", null);
		
			if(temp_list.length > 0)
			{
				YAHOO.blog.BlogComments.blog_width = parseInt(YAHOO.util.Dom.getStyle(temp_list[0], "width"), 10);
			
				if(!YAHOO.blog.BlogComments.blog_width)
				{
					YAHOO.blog.BlogComments.blog_width = 738;
				}
			}
			else
			{
				YAHOO.blog.BlogComments.blog_width = 738;
			}
		}
		
		return YAHOO.blog.BlogComments.blog_width;
	}
};

Overlord.assign({
	minion: "blog:comment_reply",
	load: function(element) {
		YAHOO.util.Event.addListener(element, "click", YAHOO.blog.BlogComments.show_reply_editor);
	}
});

Overlord.assign({
	minion: "blog_comments:select_all",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		var elements = YAHOO.util.Dom.getElementsByClassName('blog_comment_delete_input', 'input', null, function(checkbox) {checkbox.checked=true;});
		if (elements.length != 0 && YAHOO.blog.BlogComments.deleteBtn)
		{
			YAHOO.blog.BlogComments.deleteBtn.set("disabled", false);
		}
	}
});

Overlord.assign({
	minion: "blog_comments:select_none",
	click: function(event, element){
		YAHOO.util.Event.preventDefault(event);
		var elements = YAHOO.util.Dom.getElementsByClassName('blog_comment_delete_input', 'input', null, function(checkbox) {checkbox.checked=false;});
		if (elements.length != 0 && YAHOO.blog.BlogComments.deleteBtn)
		{
			YAHOO.blog.BlogComments.deleteBtn.set("disabled", true);
		}
	}
});

Overlord.assign({
	minion: "blog_comments:comment_functions",
	load: function(element){
		YAHOO.blog.BlogComments.deleteBtn = new YAHOO.widget.Button("delete_btn", {disabled:true});
	}
});

Overlord.assign({
	minion: "blog_comments:post_select",
	click: function(element){
		var disable = true;
		var postSelectElements = YAHOO.util.Dom.getElementsByClassName("blog_comment_delete_input", "input", "blog_comments_delete_form");
		for(var i = 0; i < postSelectElements.length; i++)
		{
			if (postSelectElements[i].checked)
			{
				disable = false;
				break;
			}
		}
		
		if (YAHOO.blog.BlogComments.deleteBtn)
		{
			YAHOO.blog.BlogComments.deleteBtn.set("disabled", disable);
		}
	}
});

Overlord.assign({
	minion: "blog_comments:dynamic_comment_reply_editor",
	order: 10,
	load: function(element)
	{
		YAHOO.util.Dom.setStyle(element, "display", "none");
	}
});

/*
Overlord.assign({
	minion: "blog_comments:comment_overflow",
	load: function(element)
	{
		YAHOO.blog.BlogComments.handle_comment_overflow(element);
	}
});
*/

function blogs_validate_preview() {
	return blogs_title_validate();
}

function blogs_title_validate() {
	var title = document.getElementsByName('blog_post_title')[0];
	if (title) {
		title.value = Nexopia.Utilities.trim(title.value);
		if (title.value == '') {
			alert('No title specified');
			return false;
		}
	}
	return true;
}

Overlord.assign({
	minion: "blogs:preview",
	load: function(event) {
		NexopiaPanel.linkBeforeOpenMap['blogs_preview'] =
			blogs_validate_preview;
	}
});

Overlord.assign({
	minion: "blogs:post",
	click: function(event) {
		var valid = blogs_title_validate();
		if (!valid && event) {
			YAHOO.util.Event.preventDefault(event);
		}
		return valid;
	}
});

Overlord.assign({
	minion: "blogs:post_form",
	submit: function(event) {
		
		var btn = document.getElementById('post_button-button');
		var btnParent = YAHOO.util.Dom.getAncestorByClassName(btn, 'custom_button');

		btn.disabled = true;
		YAHOO.util.Dom.addClass(btnParent, 'yui-button-disabled');
		YAHOO.util.Dom.addClass(btnParent, 'yui-push-button-disabled');
		
		return true;
	}
});

BlogPhotoUploader = function(element) {
	var container = document.getElementById('add_photo_container');
	var display = this.hasSuitableFlashVersion &&
		(!container || (container.className != 'hidden'));
	if (display) {
		this.photo_id = element.parentNode.parentNode.id;
		YAHOO.widget.Uploader.SWFURL = Site.staticFilesURL + "/gallery/flash/uploader.swf";
		this.flashUploader = new YAHOO.widget.Uploader("uploader_overlay"+this.photo_id);
		var overlay = document.getElementById('uploader_overlay'+this.photo_id);
		var button = overlay.nextSibling;
		var uiLayer = YAHOO.util.Dom.getRegion(button); 

		YAHOO.util.Dom.setStyle(overlay, 'width', (uiLayer.right-uiLayer.left+2) + "px"); 
		YAHOO.util.Dom.setStyle(overlay, 'height', (uiLayer.bottom-uiLayer.top+2) + "px"); 

		this.flashUploader.addListener('contentReady', this.configUploader, this, true);
		this.flashUploader.addListener('fileSelect', this.startUpload, this, true);
		this.flashUploader.addListener('uploadCompleteData', this.uploadComplete, this, true);
	}

};

BlogPhotoUploader.prototype = {
	flashUploader: null,
	configUploader: function() {
		this.flashUploader.setFileFilters(["*.jpeg;*.jpg;*.png;*.gif;*.bmp"], "Picture Files");
	},
	//minimum version is 9.0.45
	hasSuitableFlashVersion: function() {
		if (YAHOO.util.FlashDetect.major > 9) {
			return true;
		} else if (YAHOO.util.FlashDetect.major == 9) {
			if (YAHOO.util.FlashDetect.minor > 0 || YAHOO.util.FlashDetect.revision >= 45) {
				return true;
			}
		}
		return false;
	},
	startUpload: function(event) {
		this.showSpinner();
		this.flashUploader.uploadAll(document.getElementById("swf_upload_path"+this.photo_id).value, 'POST', {
			type: "Blogs",
			description: "",
			photo_id: this.photo_id,
			blog_id: document.getElementById('blog_id').value,
			session: YAHOO.util.Dom.get('session'+this.photo_id).value
		});
	},
	uploadComplete: function(event) {
		var success = false;
		r = new ResponseHandler({});

		var serverData = event.data;
		if (serverData.indexOf("Success") == 0) {
			serverData = serverData.slice(8,serverData.length);
			success = true;
		}

		r.handleResponse({responseText: serverData});

		this.panel.close();
	},

	showSpinner: function() {
		this.panel = new DivPanel({div_id:'blog_uploading_spinner' + this.photo_id});
		this.panel.open();
	}
};

Overlord.assign({
	minion: "blogs:photo_uploader",
	load: function(element) {
		new BlogPhotoUploader(element);
	}
});
function blogs_poll_validate(type) {
	var questionField = document.getElementById("blog_post_title");
	questionField.value = Nexopia.Utilities.trim(questionField.value);
	if (questionField.value == "") {
		alert('You need to enter a question before you can ' + type);
		return false;
	}
	
	var found = 0;
	for (i = 1; i <= 10; ++i) {
		var elem = document.getElementById("ans_" + i);
		elem.value = Nexopia.Utilities.trim(elem.value);
		if (elem.value != "") {
			found++;
		}
	}
	if (found < 2) {
		alert('You need to enter at least two answers before you can ' + type);
		return false;
	}

	return true;
}

Overlord.assign({
	minion: "blogs:poll_create:post",
	click: function(event) {
		var valid = blogs_poll_validate('save');
		if (!valid && event) {
			YAHOO.util.Event.preventDefault(event);
		}
		return valid;
	}
});

function blogs_poll_validate_preview() {
	return blogs_poll_validate('preview');
}

Overlord.assign({
	minion: "blogs:poll:preview",
	load: function(event) {
		// We want to prevalidate before allowing preview.
		NexopiaPanel.linkBeforeOpenMap['blogs_poll_preview'] =
		 	blogs_poll_validate_preview;
	}
});

Overlord.assign({
	minion: "blogs:poll_create:add_row",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		// Find first hidden answer
		for (i = 1; i <= 10; ++i) {
			var elem = document.getElementById('ans_' + i);
			if (elem.className == 'hide') {
				elem.className = 'answer';
				elem.focus();
				foundElem = true;
				break;
			}
		}
		// Showing all ten answers?  If so, hide add link
		elem = document.getElementById('ans_10');
		if (elem.className == 'answer') {
			var elem = document.getElementById("add_row");
			YAHOO.util.Dom.setStyle(elem, 'display', 'none');
		}
	}
});

function blog_poll_create_set_photo_options(value) {
	document.getElementById('size_original').disabled = value;
	document.getElementById('size_100').disabled = value;
	document.getElementById('size_75').disabled = value;
	document.getElementById('size_50').disabled = value;
	document.getElementById('size_25').disabled = value;

	document.getElementById('align_center').disabled = value;
	document.getElementById('align_left').disabled = value;
	document.getElementById('align_right').disabled = value;
}

Overlord.assign({
	minion: "blogs:poll_create:add_photo",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		document.getElementById('add_photo_button').className =
		 	'hidden';
		document.getElementById('remove_photo_button').className =
			'shown';
		document.getElementById('add_photo_container').className =
			'shown';
		Overlord.summonMinions(document.getElementById('add_photo_container'));
		blog_poll_create_set_photo_options(false);
	}
});

Overlord.assign({
	minion: "blogs:poll_create:remove_photo",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		document.getElementById('add_photo_button').className =
		 	'shown';
		document.getElementById('remove_photo_button').className =
			'hidden';
		document.getElementById('add_photo_container').className =
			'hidden';
		blog_poll_create_set_photo_options(true);
			
		// Reset the photo field
		document.getElementById('blog_post_photo_link').value = '';
	}
});

Overlord.assign({
	minion: "blogs:poll:photo_options",
	load: function(event) {
		blog_poll_create_set_photo_options(true);
	}
});

Overlord.assign({
	minion: "blogs:poll_vote:skip",
	click: function(event, element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		var submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'blog_profile_poll');
		if (submit_page == null) {
			submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'public_feed_poll');
		}
		if (submit_page == null) {
			submit_page = 'blog_poll';
		} else {
			submit_page = submit_page.className;
		}
		
		
		var form = YAHOO.util.Dom.getAncestorByTagName(element, 'form');
		YAHOO.util.Connect.setForm(form);
		YAHOO.util.Connect.asyncRequest("POST",
			element.href, new ResponseHandler({}), 'ajax=true&submit_page=' + submit_page);
	}
	
});

Overlord.assign({
	minion: "blogs:poll_vote:skip_login",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}

		top.location='/account/login?referer=' +
			escape(document.location.href);
	}
});

Overlord.assign({
	minion: "blogs:poll_vote:vote",
	click: function(event,element) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		var submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'blog_profile_poll');
		if (submit_page == null) {
			submit_page = YAHOO.util.Dom.getAncestorByClassName(element, 'public_feed_poll');
		}
		if (submit_page == null) {
			submit_page = 'blog_poll';
		} else {
			submit_page = submit_page.className;
		}

		// Let's check that the user actually selected an option
		var vote_id = this.parentNode.parentNode.parentNode.id;
		var radios = document.getElementsByName('vote_' + vote_id);
		var anyChecked = false;
		for (var i = 0; i < radios.length; i++) {
			if (radios[i].checked) {
				anyChecked = true;
				break;
			}
		}
		if (!anyChecked) {
			alert("You need to select an option before you can vote.");
			return false;
		}

		// Good to go, let's vote!
		var form = YAHOO.util.Dom.getAncestorByTagName(element, 'form');
		YAHOO.util.Connect.setForm(form);
		vote_id = vote_id.replace('_', '/');
		YAHOO.util.Connect.asyncRequest("POST",
			form.action + vote_id + "/poll_vote",
			new ResponseHandler({}), 'ajax=true&submit_page=' + submit_page);
	}
});

Overlord.assign({
	minion: "blogs:poll_vote:vote_login",
	click: function(event) {
		if (event) {
			YAHOO.util.Event.preventDefault(event);
		}
		
		top.location='/account/login?referer=' +
			escape(document.location.href);
	}
});


if(YAHOO.profile == undefined){
	YAHOO.namespace ("profile");
}

YAHOO.profile.BlogBlock =
{
	init: function()
	{
		this.resize_embeds();
	},
	
	resize_embeds: function()
	{
		var blog_block = document.getElementById("blog_profile_block");
		var obj_list = YAHOO.util.Dom.getElementsBy(function(el){return true;}, "object", blog_block, null);
		
		var i;
		for(i=0; i < obj_list.length; i++)
		{
			var parent_width = parseInt(YAHOO.util.Dom.getStyle(obj_list[i].parentNode, "width"));
			var obj_width = parseInt(YAHOO.util.Dom.getStyle(obj_list[i], "width"));
			var obj_height = parseInt(YAHOO.util.Dom.getStyle(obj_list[i], "height"));
			
			if(obj_width > parent_width)
			{
				var ratio = obj_width / parseFloat(obj_height);
				var new_width = parent_width;
				var new_height = new_width / ratio;
				
				YAHOO.util.Dom.setStyle(obj_list[i], "width", new_width + "px");
				YAHOO.util.Dom.setStyle(obj_list[i], "height", new_height + "px");
				
				var embed_list = YAHOO.util.Dom.getElementsBy(function(el){return true;}, "embed", obj_list[i], null);
				
				var j;
				for(j=0; j < embed_list.length; j++)
				{
					YAHOO.util.Dom.setStyle(embed_list[j], "width", new_width + "px");
					YAHOO.util.Dom.setStyle(embed_list[j], "height", new_height + "px");
				}
			}
		}
	}
};

Overlord.assign({
	minion: "blog_profile_block",
	load: function(element) {
		YAHOO.profile.BlogBlock.init();
	},
	order: 2
});
if(YAHOO.blog == undefined){
	YAHOO.namespace ("blog");
}

YAHOO.blog.BlogView =
{
	toggle: function(element)
	{
		// Find the elements under it that we either want to show or hide
		var blogPostDetails = YAHOO.util.Dom.getElementsByClassName('blog_post', 'div', element)[0];
		var blogPostUserFunctions = YAHOO.util.Dom.getElementsByClassName('user_functions', 'div', element)[0];
		var blogPostUserFunctionsLeft = YAHOO.util.Dom.getElementsByClassName('user_functions_left', 'div', element)[0];
		var blogPostCollapsedUserFunctions = YAHOO.util.Dom.getElementsByClassName('collapsed_user_functions', 'div', element)[0];
		var blogExtraContent = YAHOO.util.Dom.getElementsByClassName('extra_content', 'div', element)[0];

		// Find the toggle symbol span that we want to change
		var blogPostToggle = YAHOO.util.Dom.getElementsByClassName('toggle', 'span', element)[0];
		
		// Figure out whether we're showing things or hiding them
		var currentSymbol = blogPostToggle.innerHTML;
		var nextDisplay = '';
		var collapseDisplay = '';
		var handler = '';
		if (currentSymbol== '+')
		{
			handler = 'show_details';
			nextDisplay = 'block';
			collapseDisplay = 'none';
			nextSymbol = "-";
		}
		else if (currentSymbol == '-')
		{
			handler = 'hide_details';
			nextDisplay = 'none';
			collapseDisplay = 'block';
			nextSymbol = "+";
		}
		
		// Do the actual show/hide
		YAHOO.util.Dom.setStyle(blogPostDetails, 'display', nextDisplay);
		YAHOO.util.Dom.setStyle(blogPostUserFunctions, 'display', nextDisplay);
		if(blogPostUserFunctionsLeft)
		{
			YAHOO.util.Dom.setStyle(blogPostUserFunctionsLeft, 'display', nextDisplay);
		}
		YAHOO.util.Dom.setStyle(blogPostCollapsedUserFunctions, 'display', collapseDisplay);
		YAHOO.util.Dom.setStyle(blogExtraContent, 'display', nextDisplay);
		blogPostToggle.innerHTML = nextSymbol;
		
		var id = YAHOO.blog.BlogView.getDatabaseID(element);

		// TODO: Show some sort of minimalistic 'user_functions' (like comments) in the header when the post is hidden,
		// as in the actual blog spec.		
		
		return '/my/blog/navigation/' + id.blogUserID + '/' + id.postID + '/' + handler;	
	},
	
	
	getDatabaseID: function(element)
	{
		var idString = element.id.replace(/blog_post_/,'');
		var idParts = idString.split(":");
		
		return { blogUserID: idParts[0], postID: idParts[1] };
	},
	
	
	inCollapseList: function(element)
	{
		var id = YAHOO.blog.BlogView.getDatabaseID(element);
		for(var i = 0; i < Nexopia.JSONData.navigation_list.length; i++)
		{
			var keySet = Nexopia.JSONData.navigation_list[i];
			if(id.blogUserID == keySet[0] && id.postID == keySet[1])
			{
				return true;
			}
		}
		return false;
	},
	
	
	initializePostCollapsing: function(element)
	{
		var list = YAHOO.util.Dom.getElementsByClassName('blog_post_container', 'div');
		for(var i = 0; i < list.length; i++)
		{
			if (YAHOO.blog.BlogView.inCollapseList(list[i]))
			{
				// Collapse the blog post
				YAHOO.blog.BlogView.toggle(list[i]);
			}
		}
	}
};

Overlord.assign({
	minion: "blog:select_all",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		var elements = YAHOO.util.Dom.getElementsByClassName('blog_post_select', 'input', null, function(checkbox) {checkbox.checked=true;});
		if(elements.length != 0)
		{
			if (YAHOO.blog.BlogView.deleteBtn)
			{
				YAHOO.blog.BlogView.deleteBtn.set("disabled", false);
			}
			if (YAHOO.blog.BlogView.changePermissionsBtn)
			{
				YAHOO.blog.BlogView.changePermissionsBtn.set("disabled", false);
			}
		}
	}
});

Overlord.assign({
	minion: "blog:select_none",
	click: function(event, element){
		YAHOO.util.Event.preventDefault(event);
		var elements = YAHOO.util.Dom.getElementsByClassName('blog_post_select', 'input', null, function(checkbox) {checkbox.checked=false;});
		if(elements.length != 0)
		{
			if (YAHOO.blog.BlogView.deleteBtn)
			{
				YAHOO.blog.BlogView.deleteBtn.set("disabled", true);
			}
			if (YAHOO.blog.BlogView.changePermissionsBtn)
			{
				YAHOO.blog.BlogView.changePermissionsBtn.set("disabled", true);
			}
		}		
	}
});

Overlord.assign({
	minion: "blog:show_details_toggle",
	click: function(event, element){
		YAHOO.util.Event.preventDefault(event);
		
		var blogPostContainer = YAHOO.util.Dom.getAncestorByClassName(element, 'blog_post_container');
		var postURL = YAHOO.blog.BlogView.toggle(blogPostContainer);
		var formKey = document.getElementById('viewer_navigation_form_key').value;
		
		// Make an Ajax post to record the setting. Only record for logged in users, of course
		YAHOO.util.Connect.asyncRequest('POST', postURL, {
			success: function(o) {
			},
			failure: function(o) {
			},
			scope: this
		}, "ajax=true&form_key[]=" + formKey);		
	}
});

Overlord.assign({
	minion: "blog:footer",
	load: function(element) {
		YAHOO.blog.BlogView.deleteBtn = new YAHOO.widget.Button("delete_btn", {disabled:true});
		YAHOO.blog.BlogView.changePermissionsBtn = new YAHOO.widget.Button("change_permissions_btn", {disabled:true});
	}
});


Overlord.assign({
	minion: "blog:delete_one",
	click: function(event, element) {
		YAHOO.util.Event.preventDefault(event);
		
		// First uncheck all check boxes
		var elements = YAHOO.util.Dom.getElementsByClassName('blog_post_select', 'input', null, function(checkbox) {checkbox.checked=false;});
		if(elements.length != 0)
		{
			if (YAHOO.blog.BlogView.deleteBtn)
			{
				YAHOO.blog.BlogView.deleteBtn.set("disabled", false);
			}
			if (YAHOO.blog.BlogView.changePermissionsBtn)
			{
				YAHOO.blog.BlogView.changePermissionsBtn.set("disabled", false);
			}
		}
		
		// Find and check the proper checkbox
		var blog_post_id = Nexopia.json(element);
		document.getElementById('blog_post_select[' + blog_post_id + ']').checked = true;
		
		// Submit form - I looked extensively for a YUI method to accomplish this, but it wouldn't work in
		// firefox, only IE. Ended up going with this semi-hackjob method that has been tested in Safari 3,
		// FF3 and IE7.
		if (document.createEventObject) {
			// dispatch for IE
			var evt = document.createEventObject();
			document.getElementById('delete_btn-button').fireEvent('onclick',evt);
		} else {
			// dispatch for firefox + others
			var evt = document.createEvent("HTMLEvents");
			evt.initEvent('click', true, true );
			document.getElementById('delete_btn-button').dispatchEvent(evt);
		}
	}
});

Overlord.assign({
	minion: "blog:post_select",
	click: function(event, element){
		var disable = true;
		var postSelectElements = YAHOO.util.Dom.getElementsByClassName("blog_post_select", "input", "blog");
		for(var i = 0; i < postSelectElements.length; i++)
		{
			if (postSelectElements[i].checked)
			{
				disable = false;
				break;
			}
		}
		
		if (YAHOO.blog.BlogView.deleteBtn)
		{
			YAHOO.blog.BlogView.deleteBtn.set("disabled", disable);
		}
		if (YAHOO.blog.BlogView.changePermissionsBtn)
		{
			YAHOO.blog.BlogView.changePermissionsBtn.set("disabled", disable);
		}
	}
});

Overlord.assign({
	minion: "blog:filter",
	change: function(event, element) {
		var form = YAHOO.util.Dom.getAncestorByTagName(element, "form");
		form.submit();		
	}
});
if(YAHOO.blog == undefined){
	YAHOO.namespace ("blog");
}

/*
	This is needed for the blog views count. It get inclued on a few blog pages when the
	 blog user account has been view rate limited. It's included from view_blog, view_selected_entries and view_blog_post.
*/
YAHOO.blog.BlogViewCount =
{
	init: function(request_form)
	{
		if(request_form.tagName.toLowerCase() == "form" && request_form.id == "request_blog_view")
		{
			YAHOO.util.Connect.setForm(request_form);
			YAHOO.util.Connect.asyncRequest(request_form.method, request_form.action, {
				success: function(o) {
				},
				failure: function(o) {
				},
				scope: this
			}, "");
		}
	}
};

Overlord.assign({
	minion: "request_blog_view",
	load: function(element) {
		YAHOO.profile.BlogViewCount.init(element);
	}
});
Overlord.assign({
	minion: "blogs:photo_link",
	blur: function(event) {
		var value = this.value;
		this.value = value.replace(/http:\/\/(.*):\/\//, '$1:\/\/');
	}
});

PublicBlogs = 
{
	featurePostNext: function(event,element)
	{
		YAHOO.util.Event.preventDefault(event);
		
		var currentKey = Nexopia.json(element);		
		var nextKey = PublicBlogs.findNextKey(currentKey, Nexopia.JSONData.navigation_list);
		
		YAHOO.util.Connect.asyncRequest('GET', element.href + '/' + nextKey[0] + '/' + nextKey[1], new ResponseHandler({
			success: function(o) 
			{
				if(o.responseText.trim() == '')
				{
					nextKey = PublicBlogs.findNextKey(nextKey, Nexopia.JSONData.navigation_list);
					YAHOO.util.Connect.asyncRequest('GET', element.href + '/' + nextKey[0] + '/' + nextKey[1], new ResponseHandler({}), "ajax=true");
				}
			}
		}), "ajax=true");
		PublicBlogs.updateState(nextKey, Nexopia.JSONData.navigation_list);
	},
	featurePostPrevious: function(event,element)
	{
		YAHOO.util.Event.preventDefault(event);
		
		var currentKey = Nexopia.json(element);
		var previousKey = PublicBlogs.findPreviousKey(currentKey, Nexopia.JSONData.navigation_list);
		
		YAHOO.util.Connect.asyncRequest('GET', element.href + '/' + previousKey[0] + '/' + previousKey[1], new ResponseHandler({
			success: function(o) 
			{
				if(o.responseText.trim() == '')
				{
					previousKey = PublicBlogs.findPreviousKey(previousKey, Nexopia.JSONData.navigation_list);
					YAHOO.util.Connect.asyncRequest('GET', element.href + '/' + previousKey[0] + '/' + previousKey[1], new ResponseHandler({}), "ajax=true");

				}
			}			
		}), "ajax=true");
		PublicBlogs.updateState(previousKey, Nexopia.JSONData.navigation_list);
	},
	indexOf: function(key, navigationList)
	{
		for(var i = 0; i < navigationList.length; i++)
		{
			var listItem = navigationList[i];
			if(key[0] == listItem[0] && key[1] == listItem[1])
			{
				return i;
			}
		}
		
		return null;
	},
	findNextKey: function(key, navigationList)
	{
		var keyIndex = PublicBlogs.indexOf(key, navigationList);
		if(keyIndex != null && keyIndex + 1 < navigationList.length)
		{
			return navigationList[keyIndex + 1];
		}
		else
		{
			return null;
		}
	},
	
	findPreviousKey: function(key, navigationList)
	{
		var keyIndex = PublicBlogs.indexOf(key, navigationList);
		if(keyIndex != null && keyIndex - 1 >= 0)
		{
			return navigationList[keyIndex - 1];
		}
		else
		{
			return null;
		}		
	},
	
	updateState: function(key, navigationList)
	{
		var previousKey = PublicBlogs.findPreviousKey(key, navigationList);
		if(PublicBlogs.previousLink)
		{
			if(previousKey)
			{
				YAHOO.util.Dom.setStyle(PublicBlogs.previousLink, "display", "block");
			}
			else
			{
				YAHOO.util.Dom.setStyle(PublicBlogs.previousLink, "display", "none");
			}
		}
		
		var nextKey = PublicBlogs.findNextKey(key, navigationList);
		if(PublicBlogs.nextLink)
		{ 
			if(nextKey)
			{
				YAHOO.util.Dom.setStyle(PublicBlogs.nextLink, "display", "block");
			}
			else
			{
				YAHOO.util.Dom.setStyle(PublicBlogs.nextLink, "display", "none");
			}
		}
	},
	
	registerNext: function(element)
	{
		// Remove duplicate entries if there are any
		Nexopia.JSONData.navigation_list = Nexopia.JSONData.navigation_list.unique(function(a,b) { return a[0] == b[0] && a[1] == b[1]; });
		PublicBlogs.nextLink = element;
		PublicBlogs.updateState(Nexopia.json(element), Nexopia.JSONData.navigation_list);
	},
	
	registerPrevious: function(element)
	{
		// Remove duplicate entries if there are any
		Nexopia.JSONData.navigation_list = Nexopia.JSONData.navigation_list.unique(function(a,b) { return a[0] == b[0] && a[1] == b[1]; });
		
		PublicBlogs.previousLink = element;
		PublicBlogs.updateState(Nexopia.json(element), Nexopia.JSONData.navigation_list);
	},
	
	registerCommentFormDiv: function(element)
	{
		PublicBlogs.commentFormDiv = element;
	},
	
	toggleCommentForm: function(event, element)
	{
		YAHOO.util.Event.preventDefault(event);
		
		var display = YAHOO.util.Dom.getStyle(PublicBlogs.commentFormDiv, 'display');
		if(display == 'block')
		{
			YAHOO.util.Dom.setStyle(PublicBlogs.commentFormDiv, 'display', 'none');			
		}
		else
		{
			YAHOO.util.Dom.setStyle(PublicBlogs.commentFormDiv, 'display', 'block');			
			YAHOO.util.Dom.setStyle(PublicBlogs.commentSpinner, 'display', 'none');
			YAHOO.util.Dom.setStyle(PublicBlogs.commentFormSubmitButton, 'display', 'block');
			YAHOO.util.Dom.setStyle(PublicBlogs.commentFormPostingSpan, 'display', 'none');
			YAHOO.util.Dom.setStyle(PublicBlogs.successMessageDiv, 'display', 'none');
			PublicBlogs.commentInputTextArea.value = '';		
			if (!PublicBlogs.enhancedTextInput) {
				PublicBlogs.enhancedTextInput = new EnhancedTextInput(PublicBlogs.commentInputTextArea);
			}
			PublicBlogs.commentInputTextArea.focus();
		}
	},
	
	registerCommentSpinner: function(element)
	{
		PublicBlogs.commentSpinner = element;
	},
	
	registerSuccessMessageDiv: function(element)
	{
		PublicBlogs.successMessageDiv = element;
	},

	registerCommentCount: function(element)
	{
		PublicBlogs.commentCount = element;
	},
	registerCommentFormPostingSpan: function(element)
	{
		PublicBlogs.commentFormPostingSpan = element;
	},
	registerCommentFormSubmitButton: function(element)
	{
		PublicBlogs.commentFormSubmitButton = element;
	},
	registerCommentInputTextArea: function(element)
	{
		PublicBlogs.commentInputTextArea = element;
	},
	submitComment: function(event, element)
	{
		YAHOO.util.Event.preventDefault(event);
		YAHOO.util.Dom.setStyle(PublicBlogs.commentSpinner, 'display', 'block');
		
		var form = YAHOO.util.Dom.getAncestorByTagName(element, "form");
		
		YAHOO.util.Dom.setStyle(PublicBlogs.commentFormSubmitButton, 'display', 'none');
		YAHOO.util.Dom.setStyle(PublicBlogs.commentFormPostingSpan, 'display', 'inline');
				
		YAHOO.util.Connect.setForm(form);
		YAHOO.util.Connect.asyncRequest('POST', form.action, 
		{
			success : function(o) 
			{
				YAHOO.util.Dom.setStyle(PublicBlogs.commentFormDiv, 'display', 'none');
				YAHOO.util.Dom.setStyle(PublicBlogs.successMessageDiv, 'display', 'block');
				PublicBlogs.commentCount.innerHTML = parseInt(PublicBlogs.commentCount.innerHTML, 10) + 1;
			},
			failure : function(o) 
			{
			}
		}, "ajax=true");
	}
};

Overlord.assign({
	minion: "public_blogs:feature_post:next",
    click: PublicBlogs.featurePostNext,
	load: PublicBlogs.registerNext
});

Overlord.assign({
	minion: "public_blogs:feature_post:previous",
    click: PublicBlogs.featurePostPrevious,
	load: PublicBlogs.registerPrevious
});
Overlord.assign({
	minion: "public_blogs:comment_form",
	load: PublicBlogs.registerCommentFormDiv
});
Overlord.assign({
	minion: "public_blogs:comment_form:toggle",
	click: PublicBlogs.toggleCommentForm
});
Overlord.assign({
	minion: "public_blogs:comment_spinner",
	load: PublicBlogs.registerCommentSpinner
});
Overlord.assign({
	minion: "public_blogs:comment_form:submit",
	click: PublicBlogs.submitComment,
	load: PublicBlogs.registerCommentFormSubmitButton
});
Overlord.assign({
	minion: "public_blogs:comment_form:success",
	load: PublicBlogs.registerSuccessMessageDiv
});
Overlord.assign({
	minion: "public_blogs:comment_count",
	load: PublicBlogs.registerCommentCount
});
Overlord.assign({
	minion: "public_blogs:comment_form:posting",
	load: PublicBlogs.registerCommentFormPostingSpan
});
Overlord.assign({
	minion: "public_blogs:comment_input",
	load: PublicBlogs.registerCommentInputTextArea
});
Overlord.assign({
	minion: "blogs:video_embed",
	blur: function(event) {
		var value = escape(this.value);
		var form = document.getElementById("new_blog");
		var dest = '/videos/sanitize?video_embed=' + value;
		YAHOO.util.Connect.setForm(form);
		YAHOO.util.Connect.asyncRequest("POST", dest,
			new ResponseHandler({
				success: function(o) {
					this.value = o.responseText
				},
				scope: this
			}));
	}
});



