
	/**
	 * CustomerGardens is the client side logic behind customer_gardens
	 * @param {Object} options
	 * options["url"] = the AJAX service to interface with
	 * options["main_image"] = The ID of the main img tag for an image
	 * options["image_title"] = The ID of the image title div
	 * options["customer_name"] = The ID of the customer name div
	 * options["image_desc"] = The ID of the image description div
	 * options["next_page_btn"] = The ID of the next page button
	 * options["prev_page_btn"] = The ID of the prev page button
	 * options["next_img_btn"] = The ID of the next image button
	 * options["prev_img_btn"] = The ID of the prev image button
	 * options["image_select_bar"] = The ID of the Image select bar
	 * options["images_per_page"] = How many images per page?
	 * options["image_loading"] = The URL of the loading image
	 */
	function CustomerGardens(options)
	{		
		this.init(options)
		return this;
	}
	
	/**
	 * Utility function
	 */
	function IsNumeric(input)
	{
	   return (input - 0) == input && input.length > 0;
	}
	
	$.extend(CustomerGardens.prototype, {
		
		ImagePages 		: [],
		ToAdd			: [],
		Loaded			: false,
		Elements		: null,
		CurrentPage		: 1,
		CurrentImage	: 1,
		InitalImageId	: null,
		CurrentThumb	: null,
		
		/**
		 * Inits the customer gallery
		 */
		init : function(options)
		{
			var that = this;
						
			$(document).ready(function(){
				
				// add in our sweet historyness
				$.history.init(function(hash){that.navEvent(hash)});
				
				// Get all of our elements
				that.Options = options;
				that.Elements = {
					MainImage		: $("#" + options.main_image),
					ImageTitle		: $("#" + options.image_title),
					CustomerName	: $("#" + options.customer_name),
					ImageDesc		: $("#" + options.image_desc),
					NextPage		: $("#" + options.next_page_btn),
					PrevPage		: $("#" + options.prev_page_btn),
					NextImg			: $("#" + options.next_img_btn),
					PrevImg			: $("#" + options.prev_img_btn),
					ImgSelect		: $("#" + options.image_select_bar)
				};
				
				var imageLoader = new Image();
				that.Elements.ImageLoader = imageLoader;
				that.Elements.ImageLoader.onload = function(){
					that.finishSwitch($(this).attr("src"));
				}
				
				that.Loaded = true;
				
				// Add all queued images
				for (var i = 0; i < that.ToAdd.length; i++)
				{
					that.addImages(that.ToAdd[i].page, that.ToAdd[i].images);
				}
				
				if (that.InitalImageId)
					that.setImageById(that.InitalImageId);
				
				// Add the events
				that.Elements.NextPage.click(function(){
					that.nextPage();
					return false;		
				});
				
				that.Elements.PrevPage.click(function(){
					that.prevPage();
					return false;		
				});
				
				that.Elements.NextImg.click(function(){
					that.nextImage();
					return false;		
				});
				
				that.Elements.PrevImg.click(function(){
					that.prevImage();
					return false;		
				});
				
				// now select the first image
				if (that.ImagePages.length)
					that.switchImage(that.CurrentPage, that.CurrentImage, false);
			});
		},
		
		/**
		 * Used for back/forward/bookmarks
		 */
		navEvent : function(hash, that)
		{
			var match = hash.match(/^(\d+)/);
			
			if (match)
				this.setImageById(match[1]);
			else if (hash == "" && this.ImagePages.length 
				&& this.ImagePages[0].ImageWrappers.length)
				this.switchImage(1, 1, false);
		},
		
		/**
		 * 
		 */
		setImageById : function(id)
		{
			if (!this.Loaded)
			{
				this.InitalImageId = id;
				return;
			}
			
			var found = null;
			
			for (var i = 0; i < this.ImagePages.length; i++)
			{
				for (var j = 0; j < this.ImagePages[i].ImageWrappers.length; j++)
				{
					var image = this.ImagePages[i].ImageWrappers[j].Data;
					if (image.id == id)
					{
						found = [i + 1, j + 1];
						break;
					}
				}
				
				if (found)
					break;
			}
			
			if (!found)
				return;
			
			this.switchImage(found[0], found[1], false);
		},
		
		/**
		 * Goes to the next page, or stops
		 */
		nextPage : function()
		{
			if (this.ImagePages.length > this.CurrentPage)
			{
				this.switchPage(this.CurrentPage + 1);
				return true;
			}
			return false;
		},
		
		/**
		 * Goes to the prev page, or stops
		 */
		prevPage : function()
		{
			if (this.CurrentPage > 1)
			{
				this.switchPage(this.CurrentPage - 1);
				return true;
			}
			return false;
		},
		
		/**
		 * Goes to the next image, or stops. Also moves to the next page if required
		 */
		nextImage : function()
		{
			if (this.CurrentImage < this.ImagePages[this.CurrentPage - 1].ImageData.length)
			{
				this.switchImage(this.CurrentPage, this.CurrentImage + 1);
			}
			else
			{
				if (this.nextPage())
				{
					this.switchImage(this.CurrentPage, 1);
				}
			}
		},
		
		/**
		 * Goes to the prev image, or stops. Also moves to the next page if required
		 */
		prevImage : function()
		{
			if (this.CurrentImage > 1)
			{
				this.switchImage(this.CurrentPage, this.CurrentImage - 1);
			}
			else
			{
				if (this.prevPage())
				{
					this.switchImage(this.CurrentPage, this.Options.images_per_page);
				}
			}
		},
		
		/**
		 * Switches to a different image in the main image box
		 * @param {Object} page
		 * The page this image is on
		 * @param {Object} image
		 * The image index of this image
		 * @param {bool} doHistory
		 * Should we add this to the history?
		 */
		switchImage : function(page, image, doHistory)
		{
			if (doHistory == null)
				doHistory = true;
			 
			if (!this.ImagePages.length)
				return;
			 
			if (this.CurrentThumb)
			{
				$(this.CurrentThumb).removeClass("ImageSelected");
			}
			
			if (page != this.CurrentPage)
				this.switchPage(page);
			
			var imageRow = this.ImagePages[page - 1].ImageWrappers[image - 1];
			var imageData = imageRow.Data;
			
			if (doHistory)
			{
				document.title = imageData.title;
				$.history.load(imageData.id + "-" + imageData.title);
			}
			
			var ele = $(imageRow.Element);
			ele.addClass("ImageSelected");
			this.CurrentThumb = ele;
			
			$(this.Elements.ImageLoader).attr("src", imageData.url)
			this.Elements.MainImage.attr("src", "images/loadinggraphic.jpg");
			this.CurrentImage = image;
			
			this.Elements.CustomerName.html(imageData.name);
			this.Elements.ImageTitle.html(imageData.title);
			this.Elements.ImageDesc.html(imageData.desc);
		},
		
		finishSwitch : function(url)
		{
			var that = this;
			window.setTimeout(function(){				
				that.Elements.MainImage.attr("src", url);
			}, 250);
		},
		
		/**
		 * Switches to a new page
		 * @param {Object} page
		 */
		switchPage : function(page)
		{
			var imageRow = this.ImagePages[page - 1].ImageRow;
			var current = this.ImagePages[this.CurrentPage - 1].ImageRow;
			
			
			this.CurrentPage = page;
			this.Elements.ImgSelect.animate({
				marginLeft		: ((500 * (page - 1)) * -1) + "px"
			}, 500);
		},
		
		/**
		 * Adds a page of images to the selctor. Can be called from AJAX call or from the page itself
		 * (coldfusion). It will eaither use a set of already created elements, or create new ones if
		 * they don't exist - including the event handelrs for the img tags
		 * @param {Object} page
		 * The page index, starting at 1, of the page these images go in
		 * @param {Object} images
		 * An array of images. They have the following type:
		 * images[0] = {url, name, description}
		 */
		addImages : function(page, images)
		{
			if (!this.Loaded)
			{
				this.ToAdd.push({"page" : page, "images" : images});
				return;
			}
			
			// first, see if the HTML already exists for this set
			var ele = this.Elements.ImgSelect;
			var find = $("#" + this.Options.image_select_bar + " #ImagePage" + page);
			var imagePageEle = null;
			
			if (!find[0])
			{				
				// nopers, we have to create it
				var newImages = 
					$(document.createElement("div"))
						.attr("class", "ImagePage")
						.attr("id", "ImagePage" + page);
						
				// add the rows...
				for (var i = 0; i < images.length; i++)
				{
					var newRow =
						$(document.createElement("div"))
							.attr("class", "ImageWrapper")
							.attr("id", "ImageP" + page + "I" + (i + 1));					
					
					var newImg =
						$(document.createElement("img"))
							.attr("class", "GalleryImage")
							.attr("src", images[i].thumb)
							.css("height", 67)
							.attr("width", 90);
							
					if (i && !(i % 5))
						newRow.css("clear", "both");
							
					newRow.append(newImg);
					newImages.append(newRow);
				}
				
				// and add the PAGE
				ele.append(newImages);
				imagePageEle = newImages;
			}
			else
				imagePageEle = find[0];
			
			// now add all of the images
			var imageData = null;

			if (this.ImagePages.length >= (page - 1)) // < damn 1-bassed indexing
			{
				// we have to add this to our internal structure...
				imageData = {
					ImageData		: images,
					ImageRow		: $("#" + this.Options.image_select_bar + " #ImagePage" + page)[0],			
					ImageWrappers	: []
				};
				
				for (var i = 0; i < images.length; i++)
				{
					var imageEle = $("#ImageP" + page + "I" + (i + 1));
					var imagePusher = $("#ImageP" + page + "I" + (i + 1) + "Pusher");
					imageEle = imageEle[0];
					
					imageEle.Gallery = this;
					
					imageData.ImageWrappers.push({
						Element	: imageEle
					});
					
					$(imageEle).click(function(){
						if (this.Gallery.CurrentImage == this.ImageData.index
							&& this.Gallery.CurrentPage == (this.ImageData.page + 1))
							return false;
						this.Gallery.switchImage(this.ImageData.page, this.ImageData.index);
						return false;
					});
					
					$(imageEle).hover(function(){
						$(this).addClass("ImageOver");
					}, function(){
						$(this).removeClass("ImageOver");
					});
				}
				
				this.ImagePages.push(imageData);
			}
			else
				imageData = this.ImagePages[page];
				
			// whohooo now we can add/edit the images
			for (var i = 0; i < images.length; i++)
			{
				images[i].page = page;
				images[i].index = i + 1;
				
				imageData.ImageWrappers[i].Data = images[i];
				imageData.ImageWrappers[i].Element.ImageData = images[i];
				
				var img = $("#ImageP" + page + "I" + (i + 1) + " img");

				var find = img;
				
				if (!find)
					alert("WTF?!");
					
				find.attr("src", images[i].thumb);
			}
			
			// Now we need to set the width of the inner image select to contain all pages
			this.Elements.ImgSelect.css("width", this.ImagePages.length * 500);
			
			// if we have more then one page, show the buttons
			if (this.ImagePages.length <= 1)
			{
				this.Elements.NextPage.css("display", "none");
				this.Elements.PrevPage.css("display", "none");
			}
			else
			{
				this.Elements.NextPage.css("display", "block");
				this.Elements.PrevPage.css("display", "block");
			}
		}
		
	});
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	