﻿(function($)
{
	$.fn.thumbgrid = function(settings, onRenderComplete)
	{
		settings = $.extend
		(
			{
				prEvent: null,
				photographerId: "",
				year: -1,
				month: -1,
				maxThumbWidth: 125,
				maxRows: 3,
				cellSpacing: 0,
				imageContainerPadding: 10,
				photos: [],
				checkedSessionId: -1,
				linkPattern: "Orderpage.aspx?pi={photoId}&po={photoOrder}",
				selectedOnly: false,
				filter: [],
				photoCount: -1,
				subEventId: "",
				selectAllLink: null,
				deselectAllLink: null,
				minColumns: 1,
				squareThumbs: true,
				loadingIndicator: null,
				disableImageLinks: false,
				showSelectionControls: true,
				showCaptions: false,
				albumId: -1,
				onFavoriteToggle: null
			},
			settings
		);

		var lastResize = new Date();
		var lastSize =
		{
			width: $("body").width(),
			height: $("body").height()
		};

		var selectedCount = 0;
		this.GetSelectedCount = function()
		{
			return selectedCount;
		};

		this.disableclick = function(e)
		{
			if (document.all)
			{
				if (event.button == 2 || event.button == 3)
				{
					if (event.srcElement.tagName == "IMG" && event.srcElement.className == "thumbgrid")
					{
						alert(L10n.pr3_js.copyrightMessage);
						return false;
					}
				}
			}
			else if (document.layers)
			{
				if (e.which == 3)
				{
					alert(L10n.pr3_js.copyrightMessage);
					return false;
				}
			}
			else if (document.getElementById)
			{
				if (e.which == 3 && e.target.tagName == "IMG" && e.target.className == "thumbgrid")
				{
					alert(L10n.pr3_js.copyrightMessage);
					return false;
				}
			}
		}
		this.disablecontext = function(e)
		{
			if (document.all)
			{
				if (event.button == 2 || event.button == 3)
				{
					if (event.srcElement.tagName == "IMG" && event.srcElement.className == "thumbgrid")
					{
						return false;
					}
				}
			}
			else if (document.layers)
			{
				if (e.which == 3)
				{
					return false;
				}
			}
			else if (document.getElementById)
			{
				if (e.which == 3 && e.target.tagName == "IMG" && e.target.className == "thumbgrid")
				{
					return false;
				}
			}
		}

		this.associateimages = function()
		{
			for (i = 0; i < document.images.length; i++)
			{
				document.images[i].onmousedown = disableclick;
			}
		}

		if (document.all)
			document.onmousedown = this.disableclick;
		else if (document.getElementById)
			document.onmouseup = this.disableclick;
		else if (document.layers)
			this.associateimages();
		document.oncontextmenu = this.disablecontext;

		return this.each(function()
		{
			var initialized = false;
			var containers = [];
			if (typeof photoGroups != "object")
				photoGroups = []; // DO NOT write var in front of this variable unless you are prepared to deal with very difficult scope issuess

			var progressbarAvailable = function()
			{
				if (!$.fn.progressbar)
					return false;
				else
					return true;
			};

			var getMaxCols = function(container)
			{
				var availableWidth = container.width() - settings.cellSpacing;
				var imageWidth = settings.showCaptions ? 200 : settings.maxThumbWidth;
				var columns = Math.floor(availableWidth / (imageWidth + settings.cellSpacing + settings.imageContainerPadding * 2));
				columns = Math.max(columns, settings.minColumns);
				return columns;
			};

			var getMaxPhotos = function(container)
			{
				return getMaxCols(container) * settings.maxRows;
			};

			var getSelectedCountActive = false;
			var getSelectedCount = function(sender, photoGroup, callback)
			{
				if (!settings.showSelectionControls)
					return 0;

				if (photoGroup.SelectedCount >= 0 && initialized)
				{
					selectedCount = photoGroup.SelectedCount;
					callback(sender, photoGroup.SelectedCount);
					return;
				}

				if (getSelectedCountActive)
					return;

				var url = "";
				var input = {};

				if (settings.prEvent !== null) // photoreflect mode
				{
					if (settings.albumId == -1) // normal mode
					{
						url = Global.VirtualRoot + "/AjaxJSON.asmx/GetCheckedPhotoCount";
						input = JSON.stringify
					(
						{
							checkedSessionId: settings.checkedSessionId,
							eventId: settings.subEventId.length > 0 ? settings.subEventId : settings.prEvent.Id,
							subEventOnly: settings.subEventId.length > 0
						}
					);
					}
					else // album mode
					{
						url = Global.VirtualRoot + "/AjaxJSON.asmx/GetAlbumCheckedPhotoCount";
						input = JSON.stringify
						(
							{
								checkedSessionId: settings.checkedSessionId,
								eventId: settings.subEventId.length > 0 ? settings.subEventId : settings.prEvent.Id,
								albumId: settings.albumId
							}
						);
					}
				}
				else if (settings.photographerId.length > 0 && settings.year > -1 && settings.month > -1) // KLC mode
				{
					url = Global.VirtualRoot + "/AjaxJSON.asmx/GetCheckedPhotoCountKLC";
					input = JSON.stringify
					(
						{
							checkedSessionId: settings.checkedSessionId,
							photographerId: settings.photographerId,
							year: settings.year,
							month: settings.month
						}
					);
				}

				$.ajax({
					type: "POST",
					contentType: "application/json; charset=utf-8",
					url: url,
					data: input,
					beforeSend: function(x)
					{
						getSelectedCountActive = true;

						if (x && x.overrideMimeType)
							x.overrideMimeType("application/json;charset=utf-8");
					},
					success: function(data)
					{
						getSelectedCountActive = false;
						var count = data.d;
						selectedCount = count;
						photoGroup.SelectedCount = count;
						callback(sender, count);
					},
					error: function(req, status)
					{
						//debugger;
						getSelectedCountActive = false;
					},
					dataType: "json"
				});
			};

			var getPhotoCountActive = false;
			var getPhotoCount = function(photoGroup)
			{
				if (!isNaN(settings.photoCount) && settings.photoCount != -1)
				{
					photoGroup.PhotoCount = settings.photoCount;
					return;
				}

				var container = $("#" + photoGroup.ContainerId);
				if (photoGroup.PhotoCount >= 0)
				{
					updateSelectionCount(container);
					return;
				}

				if (!photoGroup.SelectedOnly && settings.prEvent !== null)
				{
					photoGroup.PhotoCount = settings.prEvent.PhotoCount;
					updateSelectionCount(container);
					return;
				}

				if (getPhotoCountActive)
					return;

				if (photoGroup.SelectedOnly && settings.prEvent !== null)
				{
					var url = Global.VirtualRoot + "/AjaxJSON.asmx/GetCheckedPhotoCount";
					var input = JSON.stringify
						(
							{
								checkedSessionId: settings.checkedSessionId,
								eventId: settings.prEvent.Id,
								subEventOnly: false
							}
					);

					if (settings.albumId > 0)
					{
						url = Global.VirtualRoot + "/AjaxJSON.asmx/GetAlbumCheckedPhotoCount";
						input = JSON.stringify
						(
							{
								checkedSessionId: settings.checkedSessionId,
								eventId: settings.prEvent.Id,
								albumId: settings.albumId
							}
						);
					}

					$.ajax({
						type: "POST",
						contentType: "application/json; charset=utf-8",
						url: url,
						data: input,
						beforeSend: function(x)
						{
							getPhotoCountActive = true;

							if (x && x.overrideMimeType)
								x.overrideMimeType("application/json;charset=utf-8");
						},
						success: function(data)
						{
							getPhotoCountActive = false;
							photoGroup.PhotoCount = data.d;
							updateSelectionCount(container);

							var maxPhotos = getMaxPhotos(container);
							var pagerDelegate = function(page)
							{
								onPagerChange(container, page);
							};

							var pagerDiv = $("#" + container.attr("id") + "DivPager");
							photoGroup.Pager = pagerDiv.pager(photoGroup.Start / maxPhotos, photoGroup.PhotoCount, maxPhotos, pagerDelegate);
						},
						error: function(req, status)
						{
							//debugger;
							getPhotoCountActive = false;

							var errBox = $(document.createElement("input"));
							errBox.attr("type", "hidden");
							errBox.attr("id", "GetCheckedPhotosError");
							errBox.val("error(" + status + "): " + req.responseText);
							container.parent().append(errBox);
						},
						dataType: "json"
					});
				}
				else if (settings.photographerId.length > 0 && settings.year > -1 && settings.month > -1) // KLC favorites
				{
					$.ajax({
						type: "POST",
						contentType: "application/json; charset=utf-8",
						url: Global.VirtualRoot + "/AjaxJSON.asmx/GetKLCPhotoCount",
						data: JSON.stringify
						(
							{
								photographerId: settings.photographerId,
								year: settings.year,
								month: settings.month,
								checkedSession: settings.checkedSessionId,
								favoritesOnly: photoGroup.SelectedOnly
							}
						),
						beforeSend: function(x)
						{
							getPhotoCountActive = true;

							if (x && x.overrideMimeType)
								x.overrideMimeType("application/json;charset=utf-8");
						},
						success: function(data)
						{
							getPhotoCountActive = false;
							photoGroup.PhotoCount = data.d;
							updateSelectionCount(container);

							var maxPhotos = getMaxPhotos(container);
							var pagerDelegate = function(page)
							{
								onPagerChange(container, page);
							};

							var pagerDiv = $("#" + container.attr("id") + "DivPager");
							photoGroup.Pager = pagerDiv.pager(photoGroup.Start / maxPhotos, photoGroup.PhotoCount, maxPhotos, pagerDelegate);
						},
						error: function(req, status)
						{
							//debugger;
							getPhotoCountActive = false;
						},
						dataType: "json"
					});
				}
			};

			var updatePhotosActive = false;
			var updatePhotos = function(container)
			{
				if (!JSON)
					throw "jquery.thumbgrid.js requires json.js";

				if (updatePhotosActive)
					return;

				var group = photoGroups[container.attr("id")];
				if (settings.photos.length > 0)
				{
					group.Photos = settings.photos.slice(group.Start, group.Start + getMaxPhotos(container));
					getPhotoCount(group);
					initialized = true;
					render(container);

					return;
				}

				if (settings.prEvent !== null) // photoreflect
				{
					var eventId = settings.subEventId.length == 10 ? settings.subEventId : settings.prEvent.Id;

					$.ajax({
						type: "POST",
						contentType: "application/json; charset=utf-8",
						url: Global.VirtualRoot + "/AjaxJSON.asmx/GetEventPhotos",
						data: JSON.stringify
						(
							{
								eventId: eventId,
								start: photoGroups[container.attr("id")].Start,
								max: getMaxPhotos(container),
								checkedSession: settings.checkedSessionId,
								favoritesOnly: group.SelectedOnly,
								filters: settings.filter,
								size: settings.maxThumbWidth,
								square: settings.squareThumbs
							}
						),
						beforeSend: function(x)
						{
							updatePhotosActive = true;

							if (x && x.overrideMimeType)
								x.overrideMimeType("application/json;charset=utf-8");
						},
						success: function(data)
						{
							updatePhotosActive = false;
							var group = photoGroups[container.attr("id")];
							group.Photos = data.d;

							getPhotoCount(group);
							initialized = true;
							render(container);
						},
						error: function(req, status)
						{
							//debugger;
							updatePhotosActive = false;

							var errBox = $(document.createElement("input"));
							errBox.attr("type", "hidden");
							errBox.attr("id", "GetEventPhotosError");
							errBox.val("error(" + status + "): " + req.responseText);
							container.parent().append(errBox);
						},
						dataType: "json"
					});
				}
				else // KLC
				{
					$.ajax
					(
						{
							type: "POST",
							contentType: "application/json; charset=utf-8",
							url: Global.VirtualRoot + "/AjaxJSON.asmx/GetKLCPhotos",
							data:
							JSON.stringify
							(
								{
									photographerId: settings.photographerId,
									year: settings.year,
									month: settings.month,
									start: photoGroups[container.attr("id")].Start,
									max: getMaxPhotos(container),
									checkedSession: settings.checkedSessionId,
									favoritesOnly: group.SelectedOnly,
									filters: settings.filter,
									size: settings.maxThumbWidth,
									square: settings.squareThumbs
								}
							),
							beforeSend: function(x)
							{
								updatePhotosActive = true;

								if (x && x.overrideMimeType)
									x.overrideMimeType("application/json;charset=utf-8");
							},
							success: function(data)
							{
								updatePhotosActive = false;
								var group = photoGroups[container.attr("id")];
								group.Photos = data.d;
								getPhotoCount(group);
								initialized = true;
								render(container);
							},
							error: function(req, status)
							{
								//debugger;
								updatePhotosActive = false;
							},
							dataType: "json"
						}
					);
				}
			};

			var renderSelectionCountHackActive = false;
			var renderSelectionCount = function(container, count)
			{
				var group = photoGroups[container.attr("id")];
				var photoCountContainer = $(".thumbgrid-photocount[thumbgrid=" + container.attr("id") + "]");
				if (photoCountContainer.length === 0)
					photoCountContainer = $(".thumbgrid-photocount");

				var selectedCountContainer = $(".thumbgrid-selectedcount[thumbgrid=" + container.attr("id") + "]");
				if (selectedCountContainer.length === 0)
					selectedCountContainer = $(".thumbgrid-selectedcount");

				var totalCount = group.PhotoCount;
				photoCountContainer.text(totalCount);
				selectedCountContainer.text(count);

				if ($.browser.safari && !renderSelectionCountHackActive) // webkit
				{
					renderSelectionCountHackActive = true;

					// hide then show the actions menu to force webkit to re-render the contents properly
					var display = $("div.actionsMenu").css("display");
					$("div.actionsMenu").css("display", "none");
					setTimeout
					(
						function()
						{
							$("div.actionsMenu").css("display", display);
						},
						1
					);
				}
			};

			var updateSelectionCount = function(container)
			{
				var group = photoGroups[container.attr("id")];
				getSelectedCount(container, group, renderSelectionCount);
			};

			var toggleFavorite = function(sender, container)
			{
				if (!JSON)
					throw "jquery.thumbgrid.js requires json.js";

				sender = $(sender);

				if (sender.length === 0)
					return;

				var id = sender.attr("id");
				var cbParent = sender.parent();
				var imgId = id.replace(/Checkbox/, "");
				var fakeCb = cbParent.find("a");
				var isChecked = !fakeCb.hasClass("selected");
				fakeCb.removeClass("selected");
				fakeCb.removeClass("unselected");
				fakeCb.addClass(isChecked ? "selected" : "unselected");

				var checkFlag = "C=";

				if (!isChecked.checked)
					checkFlag = "U=";

				var group = photoGroups[container.attr("id")];
				group.SelectedCount += isChecked ? 1 : -1;

				for (var i = 0; i < group.Photos.length; i++)
				{
					if (group.Photos[i].Id == imgId)
					{
						group.Photos[i].Checked = isChecked;
						break;
					}
				}

				$.get
				(
					Global.VirtualRoot + "/AjaxData.asmx/CheckPhoto",
					{
						id: checkFlag + imgId
					}
				);

				// update the selection count
				updateSelectionCount(container);
				
				if (settings.onFavoriteToggle !== null)
					settings.onFavoriteToggle();
			};

			var toggleAll = function(container, toggleOn)
			{
				if (!JSON)
					throw "jquery.thumbgrid.js requires json.js";

				var checkFlag = "S=";

				if (!toggleOn)
					checkFlag = "D=";

				var group = photoGroups[container.attr("id")];
				group.SelectedCount = toggleOn ? group.PhotoCount : 0;

				for (var i = 0; i < group.Photos.length; i++)
					group.Photos[i].Checked = toggleOn;

				if (settings.prEvent !== null)
				{
					$.get
					(
						Global.VirtualRoot + "/AjaxData.asmx/CheckPhoto",
						{
							id: checkFlag + settings.prEvent.Id
						}
					);
				}
				else
				{
					$.get
					(
						Global.VirtualRoot + "/AjaxJSON.asmx/CheckPhotoKLC",
						{
							id: checkFlag + settings.month + "/" + settings.year,
							photographerId: settings.photographerId
						}
					);
				}

				var checkboxes = container.find(":checkbox");
				if (toggleOn)
					checkboxes.attr("checked", "checked");
				else
					checkboxes.removeAttr("checked");

				var fakeCb = checkboxes.parent().find("a");
				fakeCb.removeClass("selected");
				fakeCb.removeClass("unselected");
				fakeCb.addClass(toggleOn ? "selected" : "unselected");

				updateSelectionCount(container);
				
				if (settings.onFavoriteToggle !== null)
					settings.onFavoriteToggle();
			};

			var onPagerChange = function(container, page)
			{
				var start = getMaxPhotos(container) * page;

				if (photoGroups[container.attr("id")].Start != start)
				{
					photoGroups[container.attr("id")].Start = start;
					updatePhotos(container);
				}
			};

			var onImageLoad = function(container)
			{
				var group = photoGroups[container.attr("id")];
				group.LoadedCount++;
			};

			var showLoadingIndicator = function(group)
			{
				if (group.ShowingCount < 1)
				{
					settings.loadingIndicator.text("Page " + (group.Pager.getPage() + 1));
					settings.loadingIndicator.show();
				}
			};

			var render = function(container)
			{
				if (!initialized)
					return;

				if (!$.fn.pager)
					throw "thumbgrid requires jquery.pager.js";

				container.empty();

				var wrapperDiv = $(document.createElement("div"));
				container.append(wrapperDiv);

				var table = $(document.createElement("table"));
				table.attr("cellpadding", "2px");
				table.attr("cellspacing", settings.cellSpacing);
				wrapperDiv.append(table);

				var tr = $(document.createElement("tr"));
				table.append(tr);

				var availableWidth = container.width();
				var topPadding = "0";

				var photoGroup = photoGroups[container.attr("id")];
				var maxPhotos = getMaxPhotos(container);
				var activeCount = settings.selectedOnly ? photoGroup.SelectedCount : photoGroup.PhotoCount;
				photoGroup.LoadedCount = 0;
				if (photoGroup.Start > activeCount - maxPhotos)
					photoGroup.ShowingCount = photoGroup.Photos.length;
				else
					photoGroup.ShowingCount = maxPhotos;

				if (photoGroup.Photos.length < photoGroup.ShowingCount)
				{
					updatePhotos(container);
					return;
				}

				if (settings.loadingIndicator !== null)
					settings.loadingIndicator.hide();

				var maxCols = getMaxCols(container);

				for (var i = 0; i < photoGroup.ShowingCount; i++)
				{
					var photo = photoGroup.Photos[i];

					if (photoGroup.SelectedOnly && !photo.Checked)
						continue;

					var filterMatch = false;

					if (settings.filter.length === 0)
						filterMatch = true;
					else
					{
						for (var f = 0; f < settings.filter.length; f++)
						{
							var filter = settings.filter[f];
							if (photo.Id.indexOf(filter) == -1)
								continue;

							filterMatch = true;
							break;
						}
					}

					if (!filterMatch)
						continue;

					var outerImgTd = $(document.createElement("td"));
					outerImgTd.css("text-align", "center");
					tr.append(outerImgTd);

					var tblWidth = String.format("{0}px", settings.maxThumbWidth + settings.imageContainerPadding * 2);
					var innerTable = $(document.createElement("table"));
					innerTable.attr("cellpadding", "0");
					innerTable.attr("cellspacing", "0");
					innerTable.css("width", tblWidth);
					innerTable.attr("class", "thumbTable");
					outerImgTd.append(innerTable);

					var innerTr1 = $(document.createElement("tr"));
					innerTable.append(innerTr1);

					var innerTr1Td1 = $(document.createElement("td"));
					innerTr1Td1.css("vertical-align", "top");
					innerTr1.append(innerTr1Td1);

					var href = settings.linkPattern;
					href = href.replace(/\{photoId\}/, photo.Id);
					href = href.replace(/\{photoOrder\}/, photo.PhotoOrder);

					if (settings.filter.length > 0)
						href += String.format("&f={0}", JSON.stringify(settings.filter));

					if (settings.photoCount != -1)
						href += String.format("&pc={0}", settings.photoCount);

					if (photoGroup.SelectedOnly)
						href += "&sf=1";

					var aspectRatio = settings.squareThumbs ? 1 : photo.ThumbWidth / photo.ThumbHeight;
					var width = aspectRatio > 1 ? settings.maxThumbWidth : settings.maxThumbWidth * aspectRatio;
					var height = aspectRatio <= 1 ? settings.maxThumbWidth : settings.maxThumbWidth * (1 / aspectRatio);


					//we can disable the transparent div on top by commenting out this block.
					var div = $(document.createElement("div"));
					div.css("padding", "0");
					div.css("margin", "0");
					div.css("width", tblWidth);
					div.css("text-align", "center");
					innerTr1Td1.append(div);

					var parent = div ? div : innerTr1Td1;

					var photoLink = $(document.createElement("a"));
					photoLink.attr("href", href);
					parent.append(photoLink);

					var img = $(document.createElement("img"));
					if (div)
						img.attr("src", "/pr3/Images/space.gif");
					else
						img.attr("src", photo.ImageUrl);
					img.css("width", width + "px");
					img.css("height", height + "px");
					img.attr("GALLERYIMG", "no");
					img.addClass("thumbgrid");

					if (settings.disableImageLinks)
						parent.append(img);
					else
						photoLink.append(img);

					if (div)
					{
						var padx = (parseInt(tblWidth) - width) / 2;
						var pady = parseInt(img.css("padding-top"));
						pady += parseInt(img.css("margin-top"));
						pady += parseInt(img.css("border-top-width"));

						div.css("background", "url('" + photo.ImageUrl + "') no-repeat " + padx + "px " + pady + "px");
					}

					img.load
					(
						function()
						{
							onImageLoad(container);
						}
					);

					var innerTr2 = $(document.createElement("tr"));
					innerTable.append(innerTr2);

					var innerTr2Td1 = $(document.createElement("td"));
					innerTr2Td1.css("vertical-align", "top");
					innerTr2.append(innerTr2Td1);

					if (settings.showSelectionControls)
					{
						var checkBoxDiv = $(document.createElement("div"));
						checkBoxDiv.addClass("checkbox");
						innerTr2Td1.append(checkBoxDiv);

						var cb = $(document.createElement("input"));
						cb.attr("type", "checkbox");
						cb.attr("id", String.format("Checkbox{0}", photo.Id));
						cb.attr("checked", photo.Checked ? "checked" : "");
						cb.attr("value", "1");
						cb.css("position", "absolute");
						cb.css("left", "-10000px");
						cb.click
						(
							function()
							{
								toggleFavorite(this, container);
							}
						);
						checkBoxDiv.append(cb);

						var fakeCb = $(document.createElement("a"));
						fakeCb.attr("href", "javascript:void(0);");
						fakeCb.attr("photoid", photo.Id);
						fakeCb.addClass(photo.Checked ? "selected" : "unselected");
						fakeCb.addClass("checkbox");
						fakeCb.click
						(
							function()
							{
								var imgCb = $("#Checkbox" + $(this).attr("photoid"));
								imgCb[0].checked = !imgCb[0].checked;
								toggleFavorite(imgCb, container);
							}
						);
						checkBoxDiv.append(fakeCb);
					}

					if (settings.showCaptions)
					{
						var captionDiv = $("<div/>");
						captionDiv.addClass("caption");
						captionDiv.text(photo.Caption);
						innerTr2Td1.append(captionDiv);
						innerTable.css("width", "200px");
					}

					if (tr.children("td").length == maxCols + 1)
					{
						tr = $(document.createElement("tr"));
						table.append(tr);
						outerImgTd.appendTo(tr);
					}

					// aubsequent tables in the tr may be taller, so adjust all tables in the tr
					tr.find("table").css("height", outerImgTd.height() + "px");
				}

				if (settings.selectAllLink !== null && settings.selectAllLink.length > 0)
				{
					settings.selectAllLink.attr("href", "javascript:void(0);");
					settings.selectAllLink.unbind();
					settings.selectAllLink.click
					(
						function()
						{
							toggleAll(container, true);
						}
					);
				}

				if (settings.deselectAllLink !== null && settings.deselectAllLink.length > 0)
				{
					settings.deselectAllLink.attr("href", "javascript:void(0);");
					settings.deselectAllLink.unbind();
					settings.deselectAllLink.click
					(
						function()
						{
							toggleAll(container, false);
						}
					);
				}

				var addToAlbumCallback = function(sender, count)
				{
					$("body").css("cursor", "auto");

					if (count === 0)
					{
						alert("Please select some photos to add to an album.");
						return;
					}

					location = sender.attr("rel"); // success! use the original href
				};

				var addToAlbumLink = $("a[id$=AddToAlbum]");
				if (addToAlbumLink.length > 0)
				{
					if (addToAlbumLink.attr("href").indexOf("javascript:void(0);") !== 0)
					{
						addToAlbumLink.attr("rel", addToAlbumLink.attr("href"));
						addToAlbumLink.attr("href", "javascript:void(0);");
					}
					addToAlbumLink.removeAttr("onclick");
					addToAlbumLink.unbind();
					addToAlbumLink.click
					(
						function()
						{
							$("body").css("cursor", "wait");
							getSelectedCount(addToAlbumLink, photoGroup, addToAlbumCallback);
						}
					);
				}

				var gridControls = $(document.createElement("div"));
				gridControls.addClass("thumbGrid");
				container.append(gridControls);

				var pagerCenter = $(document.createElement("center"));
				gridControls.append(pagerCenter);

				var pagerTable = $(document.createElement("table"));
				pagerTable.attr("id", container.attr("id") + "TablePager");
				pagerCenter.append(pagerTable);

				var pagerTr = $(document.createElement("tr"));
				pagerTable.append(pagerTr);

				var pagerTd = $(document.createElement("td"));
				pagerTd.attr("id", container.attr("id") + "TdPager");
				pagerTr.append(pagerTd);

				var pagerDiv = $(document.createElement("div"));
				pagerDiv.attr("id", container.attr("id") + "DivPager");
				pagerDiv.addClass("pages");
				pagerTd.append(pagerDiv);

				var pagerDelegate = function(page)
				{
					onPagerChange(container, page);
				};

				var pagerPhotoCount = photoGroup.SelectedOnly ? photoGroup.SelectedCount : photoGroup.PhotoCount;
				photoGroup.Pager = pagerDiv.pager(photoGroup.Start / maxPhotos, pagerPhotoCount, maxPhotos, pagerDelegate);

				updateSelectionCount(container);

				if (onRenderComplete)
					onRenderComplete();
			};

			var renderEmpty = function(container)
			{
				if (initialized || !updatePhotosActive)
					return;

				if (!$.fn.pager)
					throw "thumbgrid requires jquery.pager.js";

				container.empty();

				var wrapperDiv = $(document.createElement("div"));
				container.append(wrapperDiv);

				var table = $(document.createElement("table"));
				table.attr("cellpadding", "2px");
				table.attr("cellspacing", settings.cellSpacing);
				wrapperDiv.append(table);

				var tr = $(document.createElement("tr"));
				table.append(tr);

				var availableWidth = container.width();
				var topPadding = "0";

				var photoGroup = photoGroups[container.attr("id")];
				var maxPhotos = getMaxPhotos(container);
				var activeCount = settings.photoCount;
				photoGroup.LoadedCount = 0;
				if (photoGroup.Start > activeCount - maxPhotos)
					activeCount = ((activeCount > maxPhotos) ? (activeCount - maxPhotos) : activeCount);
				else
					activeCount = maxPhotos;

				var maxCols = getMaxCols(container);

				for (var i = 0; i < activeCount; i++)
				{

					var outerImgTd = $(document.createElement("td"));
					outerImgTd.css("text-align", "center");
					tr.append(outerImgTd);

					var innerTable = $(document.createElement("table"));
					innerTable.attr("cellpadding", "0");
					innerTable.attr("cellspacing", "0");
					innerTable.css("width", String.format("{0}px", settings.maxThumbWidth + settings.imageContainerPadding * 2));
					innerTable.attr("class", "thumbTable");
					outerImgTd.append(innerTable);

					var innerTr1 = $(document.createElement("tr"));
					innerTable.append(innerTr1);

					var innerTr1Td1 = $(document.createElement("td"));
					innerTr1Td1.css("vertical-align", "top");
					innerTr1.append(innerTr1Td1);

					var aspectRatio = 1;
					var width = settings.maxThumbWidth;
					var height = settings.maxThumbWidth;

					//we can disable the transparent div on top by commenting out this block.
					var div = $(document.createElement("div"));
					div.css("padding", "0");
					div.css("margin", "0");
					innerTr1Td1.append(div);

					var parent = div ? div : innerTr1Td1;

					var photoLink = $(document.createElement("a"));
					photoLink.attr("href", "#");
					parent.append(photoLink);

					var img = $(document.createElement("img"));
					img.attr("src", "/pr3/Images/space.gif");
					img.css("width", width + "px");
					img.css("height", height + "px");
					img.attr("GALLERYIMG", "no");
					img.addClass("thumbgrid");

					if (settings.disableImageLinks)
						parent.append(img);
					else
						photoLink.append(img);

					if (div)
					{
						var padx = parseInt(img.css("padding-left"));
						var pady = parseInt(img.css("padding-top"));
						padx += parseInt(img.css("margin-left"));
						pady += parseInt(img.css("margin-top"));
						padx += parseInt(img.css("border-left-width"));
						pady += parseInt(img.css("border-top-width"));

						padx += parseInt(img.css("padding-right"));
						pady += parseInt(img.css("padding-bottom"));
						padx += parseInt(img.css("margin-right"));
						pady += parseInt(img.css("margin-bottom"));
						padx += parseInt(img.css("border-right-width"));
						pady += parseInt(img.css("border-bottom-width"));

						div.css("width", width + padx + "px");
						div.css("height", height + pady + "px");
					}

					var innerTr2 = $(document.createElement("tr"));
					innerTable.append(innerTr2);

					var innerTr2Td1 = $(document.createElement("td"));
					innerTr2Td1.css("vertical-align", "top");
					innerTr2.append(innerTr2Td1);

					if (settings.showSelectionControls)
					{
						var checkBoxDiv = $(document.createElement("div"));
						checkBoxDiv.addClass("checkbox");
						innerTr2Td1.append(checkBoxDiv);

						var cb = $(document.createElement("input"));
						cb.attr("type", "checkbox");
						cb.attr("id", String.format("Checkbox{0}", i));
						cb.attr("checked", "");
						cb.attr("value", "1");
						cb.css("position", "absolute");
						cb.css("left", "-10000px");
						cb.click
						(
							function()
							{
								toggleFavorite(this, container);
							}
						);
						checkBoxDiv.append(cb);

						var fakeCb = $(document.createElement("a"));
						fakeCb.attr("href", "javascript:void(0);");
						fakeCb.attr("photoid", i);
						fakeCb.addClass("unselected");
						fakeCb.addClass("checkbox");
						fakeCb.click
						(
							function()
							{
								var imgCb = $("#Checkbox" + $(this).attr("photoid"));
								imgCb[0].checked = !imgCb[0].checked;
								toggleFavorite(imgCb, container);
							}
						);
						checkBoxDiv.append(fakeCb);
					}

					if (settings.showCaptions)
					{
						var captionDiv = $("<div/>");
						captionDiv.addClass("caption");
						captionDiv.text("");
						innerTr2Td1.append(captionDiv);
						innerTable.css("width", "200px");
					}

					if (tr.children("td").length == maxCols + 1)
					{
						tr = $(document.createElement("tr"));
						table.append(tr);
						outerImgTd.appendTo(tr);
					}

					// aubsequent tables in the tr may be taller, so adjust all tables in the tr
					tr.find("table").css("height", outerImgTd.height() + "px");
				}

				if (settings.selectAllLink !== null && settings.selectAllLink.length > 0)
				{
					settings.selectAllLink.attr("href", "javascript:void(0);");
					settings.selectAllLink.unbind();
					settings.selectAllLink.click
					(
						function()
						{
							toggleAll(container, true);
						}
					);
				}

				if (settings.deselectAllLink !== null && settings.deselectAllLink.length > 0)
				{
					settings.deselectAllLink.attr("href", "javascript:void(0);");
					settings.deselectAllLink.unbind();
					settings.deselectAllLink.click
					(
						function()
						{
							toggleAll(container, false);
						}
					);
				}

				var addToAlbumCallback = function(sender, count)
				{
					$("body").css("cursor", "auto");

					if (count === 0)
					{
						alert("Please select some photos to add to an album.");
						return;
					}

					location = sender.attr("rel"); // success! use the original href
				};

				var addToAlbumLink = $("a[id$=AddToAlbum]");
				if (addToAlbumLink.length > 0)
				{
					if (addToAlbumLink.attr("href").indexOf("javascript:void(0);") !== 0)
					{
						addToAlbumLink.attr("rel", addToAlbumLink.attr("href"));
						addToAlbumLink.attr("href", "javascript:void(0);");
					}
					addToAlbumLink.removeAttr("onclick");
					addToAlbumLink.unbind();
					addToAlbumLink.click
					(
						function()
						{
							$("body").css("cursor", "wait");
							getSelectedCount(addToAlbumLink, photoGroup, addToAlbumCallback);
						}
					);
				}

				var gridControls = $(document.createElement("div"));
				gridControls.addClass("thumbGrid");
				container.append(gridControls);

				var pagerCenter = $(document.createElement("center"));
				gridControls.append(pagerCenter);

				var pagerTable = $(document.createElement("table"));
				pagerTable.attr("id", container.attr("id") + "TablePager");
				pagerCenter.append(pagerTable);

				var pagerTr = $(document.createElement("tr"));
				pagerTable.append(pagerTr);

				var pagerTd = $(document.createElement("td"));
				pagerTd.attr("id", container.attr("id") + "TdPager");
				pagerTr.append(pagerTd);

				var pagerDiv = $(document.createElement("div"));
				pagerDiv.attr("id", container.attr("id") + "DivPager");
				pagerDiv.addClass("pages");
				pagerTd.append(pagerDiv);

				var pagerDelegate = function(page)
				{
					onPagerChange(container, page);
				};

				var pagerPhotoCount = photoGroup.SelectedOnly ? photoGroup.SelectedCount : photoGroup.PhotoCount;
				photoGroup.Pager = pagerDiv.pager(photoGroup.Start / maxPhotos, pagerPhotoCount, maxPhotos, pagerDelegate);

				updateSelectionCount(container);

				if (onRenderComplete)
					onRenderComplete();
			};

			var container = $(this);
			if (container.attr("id").length === 0)
				container.attr("id", "ThumbGridContainer" + containers.length);

			var bookmark = 0;

			if ($.cookie)
			{
				var cookie = $.cookie("thumbgrid");
				if (cookie !== null && cookie.length > 0)
				{
					var pairs = cookie.split("&");
					for (var i = 0; i < pairs.length; i++)
					{
						var name = pairs[i].split("=")[0];
						var value = pairs[i].split("=")[1];

						switch (name)
						{
							case "eventId":
								if (value != settings.prEvent.Id)
								{
									// the bookmark in the cookie is for a different event, ignore it and continue
									bookmark = 0;
									continue;
								}
								break;
							case "bookmark":
								bookmark = parseInt(value, 10);
								break;
						}
					}
				}
			}

			var maxPhotos = getMaxPhotos(container);
			var start = Math.floor(bookmark / maxPhotos) * maxPhotos;
			start = Math.max(start, 0);

			// ignore bookmark in selected only mode
			if (settings.selectedOnly)
				start = 0;

			containers.push(container);
			photoGroups[container.attr("id")] =
			(
				{
					Photos: settings.photos.slice(0),
					MaxColumns: getMaxCols(container),
					Start: start,
					PhotoCount: settings.photos.length,
					SelectedCount: -1,
					ContainerId: container.attr("id"),
					Pager: null,
					SelectedOnly: settings.selectedOnly
				}
			);

			getSelectedCount
			(
				null,
				photoGroups[container.attr("id")],
				function(sender, count)
				{
					photoGroups[container.attr("id")].SelectedCount = count;
					renderSelectionCount(container, count);
				}
			);

			var allowResize = function()
			{
				if (settings.prEvent === null)
					return false;

				if (updatePhotosActive)
					return false;

				var group = photoGroups[container.attr("id")];
				if (group.SelectedOnly && group.SelectedCount == -1)
				{
					getSelectedCount
					(
						null,
						group,
						function(sender, count)
						{
							group.SelectedCount = count;
						}
					);

					return false;
				}

				var newSize =
				{
					width: $("body").width(),
					height: $("body").height()
				};


				if (Math.abs(newSize.width - lastSize.width) < 10) // only resize when change is at least 10px
					return false;

				lastSize.width = newSize.width;
				lastSize.height = newSize.height;

				return true;
			};

			$(window).resize(function()
			{
				if (!allowResize())
					return;

				lastResize = new Date();

				var wrapper = container.children("div");
				wrapper.css("display", "none");

				var group = photoGroups[container.attr("id")];
				var maxCols = getMaxCols(container);
				var maxPhotos = getMaxPhotos(container);

				// calculate new start position that will keep as many photos from the current page as possible
				var start = Math.round(photoGroups[container.attr("id")].Start / maxPhotos) * maxPhotos;
				group.Start = start;

				var pagePhotoCount = Math.min(maxPhotos, group.PhotoCount - start);

				if (group.SelectedOnly)
				{
					if (group.SelectedCount > maxPhotos && group.Photos.length + group.Start < pagePhotoCount)
						updatePhotos(container);
				}
				else
				{
					if (group.PhotoCount > maxPhotos && group.Photos.length < pagePhotoCount)
						updatePhotos(container);
				}

				if (maxCols != group.MaxColumns)
				{
					group.MaxColumns = maxCols;
					render(container);
				}

				wrapper.css("display", "block");
			});

			var photoGroup = photoGroups[container.attr("id")];
			initialized = photoGroup.Photos.length > 0;
			if (!initialized)
			{
				if (settings.loadingIndicator !== null)
				{
					setTimeout(function()
					{
						showLoadingIndicator(photoGroup);
					},
					1500);
				}
				updatePhotos(container);
				renderEmpty(container);
			}
			else
				render(container);
		});
	};
})(jQuery);
