



//--------------------------------------------------------------------------------------------------------------------
// MarkHiddenThumbs puts a red X on thumbnails in the Smugmug view that are hidden
//
// Installation and support is here: http://www.dgrin.com/showthread.php?t=143433.
//--------------------------------------------------------------------------------------------------------------------
if (typeof(JLF) == "undefined") var JLF = new Object;

// Declare a global object with our various methods on it.  This puts all of our methods in their own namespace like YUI does.
JLF.HiddenMarkers = 
{
	// global data variables on the object
	oldHidePhoto: "",
	
	// externally accessible methods
	
	// Replacement for the built-in hidePhoto function.  
	// It calls the original function, then updates the hidden marker for the affected thumb
	NewHidePhoto: function(status, ImageID, ImageKey)
	{
		var retVal = JLF.HiddenMarkers.oldHidePhoto.apply(this, arguments);
		var thumb = YD.get("photoBox_" + ImageID);
		if (thumb)
		{
			JLF.HiddenMarkers.MarkSingleHiddenThumb(thumb);
		}
		return(retVal);
	},
	
	// Set the style from a whole style string rather than one attribute at a time
	SetStyleString: function(element, str)
	{
		var styles = str.split(/\s*;\s*/);
		for (var i in styles)
		{
			var pieces = styles[i].split(/\s*:\s*/);
			if (pieces.length > 1)
			{
				YD.setStyle(element, pieces[0], pieces[1]);
			}
		}
	},
	
	// Update the hidden status of a single thumb
	MarkSingleHiddenThumb: function(element)
	{
		try
		{
			// get existing marker if here
			var markers = YD.getElementsByClassName("hiddenMarker", "div", element);
			var imageID = element.id.substr(9);		// strip off "photoBox_" off the id to get just the id
			if (photoInfo[imageID].Status == "Hidden")
			{
				// if there is no marker yet, add one
				if (!markers || (markers.length == 0))
				{
					var links = element.getElementsByTagName("a");
					var imgs = links[0].getElementsByTagName("img");
					var newDiv = document.createElement("div");
					newDiv.className = "hiddenMarker";
					JLF.HiddenMarkers.SetStyleString(newDiv, "position: absolute; top:1px; left:5px; z-index:10; color: #F00; font-size: 14pt; font-weight: bold; font-family: Arial;");
					newDiv.innerHTML = "X";
					imgs[0].parentNode.insertBefore(newDiv, imgs[0]);
				}
			}
			else	// not hidden now
			{
				// if there's a hidden marker, then remove it
				if (markers && (markers.length != 0))
				{
					markers[0].parentNode.removeChild(markers[0]);		// remove it
				}
			}
		} catch (e) {console.log(e);}
	},
	
	// Update the hidden status of all thumbs
	// Only written to work in the Smugmug view when logged in
	// Other views don't appear to have the photoInfo array which gives us the hidden status
	MarkAllHiddenThumbs: function()
	{
		
		if (YD.hasClass(document.body, "loggedIn") && YD.hasClass(document.body, "smugmug"))
		{
			YD.getElementsByClassName("photo", "div", YD.get("thumbnails"), JLF.HiddenMarkers.MarkSingleHiddenThumb);
		}
	}
};

// Install our replacement function for hidePhoto
if (typeof(hidePhoto) == "function")
{
	JLF.HiddenMarkers.oldHidePhoto = hidePhoto;
	hidePhoto = JLF.HiddenMarkers.NewHidePhoto;
}

// Register for notifications when the Smugmug view has been rendered
onPhotoShow.subscribe(JLF.HiddenMarkers.MarkAllHiddenThumbs);

// --------------------------------------
// End of MarkHiddenThumbs code
// --------------------------------------




















//------------------------------------------------------------------------------------------
// Highlight the link in your navbar that matches the current page.
//
// See http://www.dgrin.com/showthread.php?t=141678 for documentation.
//------------------------------------------------------------------------------------------
YE.onContentReady("navcontainer", function ()
{
	function AddTrailingSlash(str)
	{
		if (str.search(/\/$/) == -1)
		{
			str = str + "/";
		}
		return(str);
	}
	
	function StripDomainAndHash(oldStr)
	{
		var str = oldStr.replace(/#.*$/, "");				// get rid of hash value
		str = AddTrailingSlash(str);							// make sure it always ends in a slash
		str = str.replace(/^https?:\/\/[^\/]*/, "");			// get rid of domain on the front
		return(str);
	}
	
	var links = this.getElementsByTagName("a");
	if (links && (links.length > 0))
	{
		var pageURL = StripDomainAndHash(window.location.href);
	
		var foundExactMatch = false;
		var partialIndex = -1;		// index of best partial match
		var partialLength = 0;		// length of the best partial match
		var galleriesIndex = -1;		// index of the /galleries link
		
		// check each link for an href match with our current page
		for (var i = 0; i < links.length; i++)
		{
			var testLink = StripDomainAndHash(links[i].href);			// relative link will be turned into absolute link here
			if (testLink == pageURL)
			{
				YD.addClass(links[i], "navCurrentPage navCurrentPageExact");
				YD.addClass(links[i].parentNode, "navCurrentPageParent navCurrentPageExact");
				foundExactMatch = true;
				break;
			}
			// if testLink is not the top level (don't want to do partial matches for top level)
			else if (testLink != "/")
			{
				// if the testLink is contained within the pageURL 
				// (e.g. the current page link is longer than the navbar link and starts with it),
				// remember it as a partial match
				if (pageURL.indexOf(testLink) == 0)
				{
					// save the longest partial match (assuming it to be the most specific)
					if (testLink.length > partialLength)
					{
						partialIndex = i;
						partialLength = testLink.length;
					}
				}
				else if (testLink == "/galleries/")
				{
					galleriesIndex = i;
				}
			}
		}
		if (!foundExactMatch)
		{
			// since we had no exact match, check for partial matches
			if (partialIndex != -1)
			{
				YD.addClass(links[partialIndex], "navCurrentPage navCurrentPagePartial");
				YD.addClass(links[partialIndex].parentNode, "navCurrentPageParent navCurrentPageParentPartial");
			}
			// if no exact match and no partial matches 
			// and we did have a galleries link 
			// and we're on a gallery page or a category or subcategory page
			// then, mark the galleries link
			else if ((galleriesIndex != -1) && (YD.hasClass(document.body, "galleryPage") || YD.hasClass(document.body, "category")))
			{
				YD.addClass(links[galleriesIndex], "navCurrentPage navCurrentPageGallery");
				YD.addClass(links[galleriesIndex].parentNode, "navCurrentPageParent navCurrentPageParentGallery");
			}
		}
	}
});







// ---------------------------------------------
// Slideshow parameter modification
// ---------------------------------------------
function MyEmbedSWF(swfURL, containerID, swfID, version, backgroundColor, expressInstall)
{
	// catch all exceptions here so, if there's an error, we just continue on as if we weren't here
	try {
		var overrides = null;
		if (this._type == "gallery")
		{
			overrides = this.gallerySlideshowOverrides;
		}
		else if (this._type == "fullScreen")
		{
			overrides = this.fullScreenSlideshowOverrides;
		}
		if (overrides)
		{
			// copy all overrides over into the objects flashVars
			for (var i in overrides)
			{
				this._flashVars[i] = overrides[i];
			}
		}
	} catch (e) {}
	oldEmbedSWF.apply(this, arguments);		// call the regular handler for this method
}


function SetSlideshowOverrides()
{
	var globalGallerySlideshowConfigOverride = {
		showButtons: "false",
		showSpeed: "false",
		showThumbs: "false",
		captions: "false",
		transparent: "true"		// no comma after the last entry in this table or IE7 will barf
	};

	var globalFullScreenSlideshowConfigOverride = {
		showButtons: "false",
		showSpeed: "false"		// no comma after the last entry in this table or IE7 will barf
	};
	
	SM.flash.Slideshow.prototype.gallerySlideshowOverrides = globalGallerySlideshowConfigOverride;
	SM.flash.Slideshow.prototype.fullScreenSlideshowOverrides = globalFullScreenSlideshowConfigOverride;
	
	// now check to see if anything was defined just for this gallery and use it instead
	if (typeof(localGallerySlideshowConfigOverride) == "object")
	{
		SM.flash.Slideshow.prototype.gallerySlideshowOverrides = localGallerySlideshowConfigOverride;
	}
	if (typeof(localFullScreenSlideshowConfigOverride) == "object")
	{
		SM.flash.Slideshow.prototype.fullScreenSlideshowOverrides = localFullScreenSlideshowConfigOverride;
	}
}

// SM.flash.Slideshow is only defined in a galleries page
if (typeof(SM.flash.Slideshow) == "function")
{
	var oldEmbedSWF = SM.flash.Slideshow.superclass._embedSWF;
	SM.flash.Slideshow.superclass._embedSWF = MyEmbedSWF;
	SetSlideshowOverrides();
}

// ---------------------------------------------
// end of slideshow customization
// ---------------------------------------------


//------------------------------------------------------------------------------------------------------------------------------------------
// Script to allow you to use CSS to hide any individual menu items in the Share or Style menus
// This script will add a class name to each top level menu item in the Share and Style menus.
// That class name will be of the form "buttonname_menuitemname_menuitem".
// The class name will be all lowercase and any spaces or other non-alpha numeric chars in it will be converted to underscores.
// Here are some examples of class names:
//	share_be_social_menuitem
//	share_social_bookmarking_menuitem
//	style_traditional_menuitem
//
// And some example CSS to hide a menu item would look like this:
//	.share_be_social_menuitem {display:none;}
//	.style_traditional_menuitem {display:none;}
//
// You can also hide menu items only in certain contexts using all the normal Smugmug CSS classifiers. 
// To hide social bookmarking only in your vacation category, you would use CSS like this:
//	.category_Vaction .share_be_social_menuitem {display:none;}
//------------------------------------------------------------------------------------------------------------------------------------------

YE.onContentReady("viewingStylesButton", TagMenuItemsSetup);
YE.onContentReady("shareButton", TagMenuItemsSetup);

function TagMenuItemsSetup()
{
	// now that the object is created, we can register an interest in the beforeShowEvent
	// we can't modify the menu until then because of lazyLoading
	var button = YAHOO.widget.Button.getButton(this.id);
	var menu = button.getMenu();
	var menuName = button.get("label");
	menu.beforeShowEvent.subscribe(TagMenuItems);
	
	function TagMenuItems(event, args, data)
	{
		// called in the context of the menu
		try
		{
			// get the list of menu items in our menu
			var menuItems = this.getItems();
			
			// look through each menu item to see if it matches anything in our stylesToRemove array
			for (var i = 0; i < menuItems.length; i++)
			{
				// get the text value from the menu item and make it into a new class name
				var newClassName = menuItems[i].cfg.config.text.value;
				newClassName = menuName + "_" + newClassName + "_menuitem";
				newClassName = newClassName.replace(/\s+|\&[a-z]+;|[^_a-zA-Z0-9-]/g, "_");	// replace illegal CSS chars with underscore
				// add the new class name to the menu item so we can hide/style it with pure CSS
				YD.addClass(menuItems[i].id, newClassName.toLowerCase());
				
				// if this item itself is a sub-menu, then register for it's show event too
				var submenu = menuItems[i].cfg.getProperty("submenu");
				if (submenu)
				{
					submenu.beforeShowEvent.subscribe(TagMenuItems);
				}
			}
			// no need to call this again everytime we show the menu
			this.beforeShowEvent.unsubscribe(TagMenuItems);
		} catch (e) {}		// catch any exceptions and ignore them - errors will just cause the styles not to get removed, but not affect any other scripts
	}
}









 




function GetFeedImages(feedURL, resultsFunc, parm)
{
	var callback = 
	{
		timeout: 5000,
		success: function(s)
		{
			var root = s.responseXML.documentElement;
			var items = root.getElementsByTagName("item");
			
			// array of images (contains an array 
			var images = new Array;
			
			for (var i = 0; i < items.length; i++)
			{
				var imageObj = new Object;
				var linkTags = items[i].getElementsByTagName("link");
				if (linkTags.length > 0)
				{
					imageObj.link = linkTags[0].textContent;
				}
				var mediaGroups = items[i].getElementsByTagName("media:group");
				if (mediaGroups.length > 0)
				{
					var mediaContents = mediaGroups[0].getElementsByTagName("media:content");
					for (var j = 0; j < mediaContents.length; j++)
					{
						var image = new Object;		// create new object for each size of a given image we have
						image.url = mediaContents[j].getAttribute("url");
						image.height = mediaContents[j].getAttribute("height");
						image.width = mediaContents[j].getAttribute("width");
						image.filesize = mediaContents[j].getAttribute("fileSize");
						image.type = mediaContents[j].getAttribute("type");
						
						// now parse out which size this is
						// http://jfriend.smugmug.com/photos/344287800_YL8Ha-Ti.jpg
						// find a slash, followed by sequence of digits, then underscore, then 5 alpha numerics, then a dash, then one or two characters, then .jpg, then the end of the string
						var matches = image.url.match(/\/([\d]+)_([^-\.]{5})-([a-zA-Z0-9]{1,2})\.jpg$/);
						if (matches && (matches.length > 3))
						{
							imageObj.imageID = matches[1];
							imageObj.imageKey = matches[2];
							var imageSizeMoniker = "size" + matches[3];
							if (!imageObj.sizes)
							{
								imageObj.sizes = new Object;
							}
							imageObj.sizes[imageSizeMoniker] = image;		// save this image instance onto the imageObj
						}
					}
					images.push(imageObj);		// put this list of image sizes into the images array
				}
			}
			resultsFunc(parm, images);		// call with results
		},
		
		failure: function(s)
		{
			resultsFunc(parm, null);		// call with no results
		}
	}
	var transaction = YAHOO.util.Connect.asyncRequest('GET', feedURL, callback, null);
}

function ProcessFeedImages()
{
	function ProcessFeedResults(parm, images)
	{
		var i = 1;
	}
	
	GetFeedImages("http://jfriend.smugmug.com/hack/feed.mg?Type=gallery&Data=5608779_ZJ27n&format=rss200",  ProcessFeedResults, null);
}

if (IsLoggedIn())
{
	//YE.onDOMReady(ProcessFeedImages);
}









rightClickWarning = "These photos are copyright John Friend.  All rights reserved.  Unauthorized use is prohibited.";

// Utility functions
function IsLoggedIn()
{
	return(YD.hasClass(document.body, "loggedIn"));
}

function IsSmugmugView()
{
	return(YD.hasClass(document.body, "smugmug"));
}

function IsGalleryPage()
{
	return(YD.hasClass(document.body, "galleryPage"));
}


function GetUserTopPage()
{
	if (window.smugmugUserHomepage && (window.smugmugUserHomepage != ""))
	{
		return(window.smugmugUserHomepage);
	}
	if (window.webServer && (window.webServer != ""))
	{
		return(window.webServer);
	}
	if (IsLoggedIn() && (userTopPage == ""))
	{
		window.alert("userTopPage is empty.");
	}
	return("");
}


// put our referral code into the Smugmug link in the footer 
function AddReferralCode()
{
	var footerDiv = document.getElementById("footer");
	if (footerDiv)
	{
		var links = footerDiv.getElementsByTagName("A");
		if (links && (links.length != 0))
		{
			var smugLink = links.item(0);
			smugLink.href = "http://www.smugmug.com/?referrer=3elo1xh75JSiI";
		}
	}
}

YE.onContentReady("footer", AddReferralCode);




// <div id="addClassNames" classNames="foo, bar"></div>
YE.onAvailable("addClassNames", ProcessClassNames);

function ProcessClassNames()
{
	var classAttribute = this.getAttribute("classNames");
	if (classAttribute)
	{
		var newClasses = classAttribute.split(",");
		for (var i in newClasses)
		{
			YD.addClass(document.body, newClasses[i]);
		}
	}
}

// ------------------------------------------------------------------------
// Code to insert a download button 
// 
// Works for any gallery that has originals enabled
// And right-click protection off
// ------------------------------------------------------------------------
function IsAnySmugmugView()
{
    return(YD.hasClass(document.body, "smugmug") || YD.hasClass(document.body, "smugmug_small"));
}

function IsGalleryPage()
{
	return(YD.hasClass(document.body, "galleryPage"));
}

onPhotoShow.subscribe(ProcessDownloadButton);

function ProcessDownloadButton()
{
	// set onlyInGalleries to true if you only want a download button in gallery views
	// set onlyInGalleries to false if you want a download button in other views too like (search, keywords, date, etc...)
	var onlyInGalleries = false;
	if (IsAnySmugmugView() && (IsGalleryPage() || !onlyInGalleries))
	{
		if (photoInfo[ImageID].albumOriginals && !photoInfo[ImageID]['protected'] && (photoInfo[ImageID].Format !== "MP4"))
		{
			var downloadParent = "cartButtonsWrapper";
			if (!document.getElementById("cartButtonsWrapper"))
			{
				downloadParent = "altViews";
			}
			InsertDownloadButton(downloadParent);
		}
		else
		{
			// disable the button
			var downloadButton = YAHOO.widget.Button.getButton("downloadButtonId");
			if (downloadButton)
			{
				downloadButton.set("disabled", true);
			}
		}
	}
}

function InsertDownloadButton(parentId)
{
	// now add the download button
	var parentDiv = document.getElementById(parentId);
	var downloadButton = document.getElementById("downloadButtonId");
	if (downloadButton)
	{
		// make sure it is enabled
		YAHOO.widget.Button.getButton("downloadButtonId").set("disabled", false);
	}
	else if (parentDiv)
	{
		var downloadButtonInfo =
		{
			id: "downloadButtonId",
			label: "Download Image...",
			container: parentDiv,
			type: "button",
			className: "sm-button sm-button-small themesButton glyphButton",
			onclick: { fn: InitiateDownloadImage }
		};
		
		var dButtonObj = new YAHOO.widget.Button(downloadButtonInfo);
	}
}

function InitiateDownloadImage()
{
	// construct the download URL
	window.location = "/photos/" + ImageID + "_" + ImageKey + "-D.jpg";
}

// End of code to insert Download Button



var homePageTag;

function MarkSpecialHomepage()
{
	if (YD.hasClass(document.body, "homepage"))
	{
		var re = new RegExp(/^\/([a-zA-Z][^\/ ]*)[\/]?$/)
		var matches = re.exec(window.location.pathname);
		if (matches && (matches.length > 1))
		{
			YD.addClass(document.body, "homepage_" + matches[1]);
			homePageTag = matches[1];
		}
		else
		{
			YD.addClass(document.body, "homepage_only");
		}
	}
}

MarkSpecialHomepage();



// -----------------------------------------------------------
// Code to add descriptions to categories and/or sub-categories
// -----------------------------------------------------------

function addCategoryTitleToBreadcrumb(description) 
{
    var breadCrumb = YD.get("breadcrumb");
    if (breadCrumb)
    {
        var divTag = document.createElement("div");
        divTag.className = "categoryDescription";
        divTag.innerHTML = description;
        breadCrumb.parentNode.insertBefore(divTag, breadCrumb.nextSibling);
    }
}

function addCategoryTitleToThumbs(descriptionObject, boxObjectName) 
{
    var re = /\>([^\<]+)<\/a>/i;    // pattern to find the category name between the <a> and </a> tags
    var divTag = YD.get(boxObjectName);
    if (divTag) 
    {
        var divTags = YD.getElementsByClassName("albumTitle", "p", divTag);
        for (var i = 0; i < divTags.length; i++) 
        {
            var matches = re.exec(divTags[i].innerHTML);    // get just the category name
            // if we found a category name and the category name exists in our categoryDescription object, then add the description
            if (matches && (matches.length > 1) && descriptionObject[matches[1]] != undefined) 
            {
                var pTag = document.createElement("p");
                pTag.className = "categoryDescription";
                pTag.innerHTML = descriptionObject[matches[1]];
                divTags[i].parentNode.insertBefore(pTag, divTags[i].nextSibling);
            }
        }
    }
}

/* Category descriptions */
function addCategoryDescription() 
{
    var categoryDescription = {
        // list "categoryname" : "category title",
        // or "categoryname.subcategoryname" : "subcategory title",
        // Examples:
        // "Kenya"  : "Our vacation to Kenya",
        // "Kenya.Highlights" : "The highlights galleries from our vacation to Kenya",
        "xxKenya"  : "Our vacation to Kenya",
        "xxKenya.Highlights" : "The highlights galleries from our vacation to Kenya",
        "xxcategory2"  : "This is another test.",
        "xxcategory3"  : "Final test"
    };
    
    var re, matches, i;        // various local variables

    // now fix it so that it works automatically even if the category or sub-category name has spaces in it
    // we replace those spaces with underscores (which is what the classname does) and add those to our object so we can match those too
    for (i in categoryDescription) 
    {
        var newName = i.replace(/ /g, "_");
        categoryDescription[newName] = categoryDescription[i];    // add a property to the object that has only underscores in the name
    }
    // on the homepage, we want to check for category names and add a description if a match found
    // on a category page, we want to check to see if the category that the page is needs a description under the breadcrumb
    //      and, we need to see if any of the sub-category items on the page need us to add a description under the name
    // on a sub-category page, we want to check to see if the sub-category that the page is needs a description under the breadcrumb
    if (YD.hasClass(document.body, "category")) 
    {
        // fetch the category name
        re = /category_(\S+)/i;
        matches = re.exec(document.body.className);
        if (matches && (matches.length > 1)) 
        {
            var categoryName = matches[1];
            // now see if we have a subcategory too
            if (YD.hasClass(document.body, "subcategory")) 
            {
                re = /subcategory_(\S+)/i;
                matches = re.exec(document.body.className);
                if (matches && (matches.length > 1)) 
                {
                    var subcatName = matches[1];
                    // category and subcategory so we are on a subcategory page showing a list of galleries in this subcategory
                    // we need to just add a subcategory title to this page if the category-subcategory matches
                    var fullName = categoryName + "." + subcatName;
                    if (categoryDescription[fullName])
                    {
                        addCategoryTitleToBreadcrumb(categoryDescription[fullName]);
                    }
                }
            }
            // here we're on a category page
            // we need to add a category description for the category page
            // and potentially add subcategory descriptions to the subcategory names displayed on this page
            else 
            {
                if (categoryDescription[categoryName])
                {
                    addCategoryTitleToBreadcrumb(categoryDescription[categoryName]);
                }
                // now we need to build a temporary subcategoryDescription object that has only the subcategory names in it that are in this category
                var subcatDescriptions = {};
                re = new RegExp("^" + categoryName + "\\.(.+)$", "i");
                for (i in categoryDescription)
                {
                    matches = re.exec(i);
                    if (matches && (matches.length > 1))
                    {
                        subcatDescriptions[matches[1]] = categoryDescription[i];
                    }
                }
                addCategoryTitleToThumbs(subcatDescriptions, "subcategoriesBox");
            }
        }
    }

    // then see if we're on the homepage
    if (YD.hasClass(document.body, "homepage")) 
    {
        addCategoryTitleToThumbs(categoryDescription, "categoriesBox");
    }
}

YE.onDOMReady(addCategoryDescription);




//====GetCategoryInfo====
// Retreives category and subcategory names from the body tag classes
// returns an object
function GetCategoryInfo()
{
	var info = new Object;
	info.cat = "";
	info.subcat = "";
	
	if (YD.hasClass(document.body, "category"))
	{
		var re = /category_(\S+)/i;
		var matches = re.exec(document.body.className);
		if (matches && (matches.length > 1))
		{
			info.cat = matches[1];
		}
		if (YD.hasClass(document.body, "subcategory"))
		{
			re = /subcategory_(\S+)/i;
			matches = re.exec(document.body.className);
			if (matches && (matches.length > 1))
			{
				info.subcat = matches[1];
			}
		}
	}
	return(info);
}

YE.onContentReady("category", ProcessCategory);

function ProcessCategory()
{
	// this is the list of categories to combine galleries and categories in the same list
	var categoriesToCombineWithGalleries = ["category_Family"];
	
	for (var i in categoriesToCombineWithGalleries)
	{
		if (YD.hasClass(document.body, categoriesToCombineWithGalleries[i]))
		{
			CombineCategoriesWithGalleries();
			break;
		}
	}
	// now see if we should divide into sections
	DivideIntoSections();	
}

function IsArrayEmpty(testVal)
{
	return(!testVal || (testVal.length == 0));
}


function CombineCategoriesWithGalleries()
{
	// get miniBoxes in the subcategoriesBox object
	var subcategoriesObj = document.getElementById("subcategoriesBox");
	if (!subcategoriesObj)
	{
		return;
	}
	var miniBoxes = YD.getElementsByClassName("miniBox", "div", subcategoriesObj);
	// get target galleriesBox object
	var galleriesObj = document.getElementById("galleriesBox");
	var galleryMiniBoxes = new Array;

	// now find the right miniBox in the galleriesBox in order to insert the sub-categories
	if (galleriesObj)
	{
		galleryMiniBoxes = YD.getElementsByClassName("miniBox", "div", galleriesObj);
	}
	
	// if we don't have everything we need, then return without doing anything
	if (!galleriesObj || IsArrayEmpty(miniBoxes) || IsArrayEmpty(galleryMiniBoxes) || (window.location.hash == "#stop"))
	{
		subcategoriesObj.style.display = "block";		
		return;
	}
	
	// move all the sub-categories over to the gallery listing
	for (var i in miniBoxes)
	{
		miniBoxes[i].parentNode.removeChild(miniBoxes[i]);
		galleryMiniBoxes[0].parentNode.insertBefore(miniBoxes[i], galleryMiniBoxes[0]);
	}
	subcategoriesObj.style.display = "none";
}

function CompareAlpha(a,b)
{
	// we have to do it this way because IE doesn't work right when comparing numeric things to alpha things if we just subtract the two
	if (a < b) return -1;
	if (a > b) return 1;
	return 0;
}

function CompareFamilySpecial(a,b)
{
	if (a == "Other") return -1;
	if (b == "Other") return 1;
	return(CompareAlpha(a,b));
}

function DivideIntoSections()
{
	// for the Barracudas Fall 2008 sub-category, use these section rules
	// if gallery title has "vs." in it, then put it in the "Games" section
	// if gallery title has "Team" or "Season" in it, then put it in the "Team" section
	// anything else put in the "Players" section
	
	var barracudasSectionDefinitions = [
		{re: /vs\./, sectionName: "Games"},
		{re: /Team|Season/, sectionName:  "Team"},
		{re: /./, sectionName: "Players"}
	];
	
	var u16b321SectionDefinitions = [
		{re: /vs|Sept|Oct/, sectionName: "Games"},
		{re: /Highlights/, sectionName: "Highlights"},
		{re: /./, sectionName: "Players"}
	];
	
	var purpleSectionDefinitions = [
		{re: /Highlights|Closeups/, sectionName: "Team"},
		{re: /./, sectionName: "Players"}
	];
	
	var juniorOlympics2009Definitions = [
		{re: /Highlights|Assembly|Training|Pep Rally|Opening/, sectionName: "General"},
		{re: /\dth grade/, sectionName: "", modRegExp: /\dth grade\s*/, modRegExpReplace: ""},
		{re: /Finals/, sectionName: "Finals"},
		{re: /./, sectionName: "Other Events"}
	];
	
	var schoolSectionDefinitions = [
		{re: /\d\d\d\d(?:\s*)$/, sectionName: ""}	// group by year
	];
	
	var sportsSectionDefinitions = [
		{re: /\d\d\d\d(?:\s*)$/, sectionName: ""}	// group by year
	];
	
	var force2009SpringDefinitions = [
		{re: /Highlights|Girls/, sectionName: "Team"},
		{re: /\d{1,2}\-\d{1,2}\s*$/, sectionName: "Games", modRegExp: /\s*-\s*\d{1,2}\-\d{1,2}\s*$/, modRegExpReplace: ""},
		{re: /./, sectionName: "Players"}
	];

	
	var familySectionDefinitions = [
		{re: /\d\d\d\d(?:\s*)$/, sectionName: "", modRegExp: /[\d]*[\s\-]*\d\d\d\d\s*$/, modRegExpReplace: ""},	// group by year
		{re: /./, sectionName: "Other"}
	];
	
	var sections = [
		
		// categories must go after the subcategories because they will match first
		{bodyClassName: "category_Family", sectionDefinitions: familySectionDefinitions, sortType: CompareFamilySpecial}
	];

	// only trigger  this code in a category or sub-category we have a table entry for
	var sectionDefinitions = null;
	var sectionMatch;
	var topObjName = "galleriesBox";		// assume galleriesBox
	for (var k in sections)
	{
		if (YD.hasClass(document.body, sections[k].bodyClassName))
		{
			// if it's a category we're searching for, make sure we don't match a sub-category in that category
			if (sections[k].bodyClassName.search(/^category_/) != -1)
			{
				if (YD.hasClass(document.body, "subcategory"))
				{
					continue;		// skip  the subcategory that we matched only on the category
				}
			}
			sectionMatch = sections[k];
			sectionDefinitions = sections[k].sectionDefinitions;
			
			// find out which object we want to process
			if (sections[k].objName)
			{
				topObjName = sections[k].objName;
			}
			break;
		}
	}
	
	// if we found an object in this page that we have a table entry for, then process it
	if (sectionDefinitions)
	{
		// get the boxBottom element
		var topBox = document.getElementById(topObjName);
		if (!topBox)
		{
			return;		// no galleries
		}
		var boxBottoms = YD.getElementsByClassName("boxBottom", "div", topBox);
		if (boxBottoms.length < 1)
		{
			return;		// no boxBottom
		}
		// get the list of all miniBoxes in boxBottom
		var miniBoxes = YD.getElementsByClassName("miniBox", "div", boxBottoms[0]);
		if (miniBoxes.length < 1)
		{
			return;		// no miniBoxes
		}
		
		// miniBox groups (a hash of arrays, index is the sectionName, content is a list of miniboxes for that section)
		var miniBoxGroups = {};
		
		// cycle through all miniBoxes to find the gallery titles
		for (var i in miniBoxes)
		{
			// get div class="albumTitle"
			var titles = YD.getElementsByClassName("albumTitle", "p", miniBoxes[i]);
			if (titles.length < 1)
			{
				continue;		// no albumTitle here,  go to next miniBox
			}
			// get link in the albumTitle div
			var container = "";
			var titleLinks = titles[0].getElementsByTagName("a");
			if (titleLinks.length < 1)
			{
				continue;		// no albumTitle link here, go to next miniBox
			}
			
			// regular expressions that define each section and the corresponding section name
			for (var j in sectionDefinitions)
			{
				var results = titleLinks[0].innerHTML.match(sectionDefinitions[j].re);
				if (results && (results.length > 0))
				{
					if (sectionDefinitions[j].sectionName != "")
					{
						container = sectionDefinitions[j].sectionName;
					}
					else
					{
						container = results[0];		// use the regular expression match results as the container name
					}
					// now see if there's a reg exp to match and replace
					if (sectionDefinitions[j].modRegExp)
					{
						titleLinks[0].innerHTML = titleLinks[0].innerHTML.replace(sectionDefinitions[j].modRegExp, sectionDefinitions[j].modRegExpReplace);
					}
					// or a custom function to call
					else if (sectionDefinitions[j].modFunc)
					{
						sectionDefinitions[j].modFunc(titleLinks[0]);
					}
					break;
				}
			}
			
			// if no container established, then skip this minibox
			if (container == "")
			{
				continue;
			}
			
			// if this is the first one for this year, then create the hash entry for this year 
			if (!miniBoxGroups[container])
			{
				// create a new container object that has a name (containerName) and an array of miniboxes (list)
				miniBoxGroups[container] = new Object;
				miniBoxGroups[container].containerName = container;
				miniBoxGroups[container].list = new Array;
			}
			// add this minibox to the right container
			miniBoxGroups[container].list.push(miniBoxes[i]);
		}
		
		// now we have all the miniBoxes grouped by their reg exp match in the miniBoxGroups array or arrays
		
		// so that we can sort the collection, lets put it into an array that has a definitive order
		var miniBoxGroupsArray = new Array;
		for (var i in miniBoxGroups)
		{
			miniBoxGroupsArray.push(miniBoxGroups[i]);
		}
		
		// see if we need to sort the array into alpha order
		if (sectionMatch.sortType)
		{
			if (sectionMatch.sortType == "alpha")
			{
				miniBoxGroupsArray.sort(function(a, b){return(CompareAlpha(a.containerName, b.containerName))});
			}
			else if (sectionMatch.sortType == "reverseAlpha")
			{
				miniBoxGroupsArray.sort(function(a, b){return(CompareAlpha(b.containerName, a.containerName))});
			}
			// if it's a custom sort function, then use that
			else if (typeof sectionMatch.sortType == "function")
			{
				miniBoxGroupsArray.sort(function(a, b){return(sectionMatch.sortType(b.containerName, a.containerName))});
			}
		}
		
		var catSectionClassName = "catSection first";
		var catSectionHeaderClassName = "catSectionHeader first";
		for (i in miniBoxGroupsArray)
		{
			var newSpacer = document.createElement("div");
			newSpacer.className = "spacer";
			
			var newDiv = document.createElement("div");
			newDiv.className = catSectionClassName;
			newDiv.innerHTML = '<div class="' + catSectionHeaderClassName + '"><h3 class="title notopmargin">' + miniBoxGroupsArray[i].containerName + '</h3></div>';
			
			// now insert these two new divs into the  boxBottom object
			boxBottoms[0].appendChild(newDiv);
			boxBottoms[0].appendChild(newSpacer);
			
			// now move the miniBoxes into this div for this year
			for (var j in miniBoxGroupsArray[i].list)
			{
				var miniBox = miniBoxGroupsArray[i].list[j];		// get it out of the array
				miniBox.parentNode.removeChild(miniBox);	// remove it from where it was
				newDiv.appendChild(miniBox);				// add it to the new div
			}
			catSectionClassName = "catSection";
			catSectionHeaderClassName = "catSectionHeader";
		}
	}
}



//====TagThumbs====
// adds a CSS classname to the minibox for a category or sub-category thumb so you can then style them individually with CSS (including hiding them)
function TagThumbs() 
{
	// get current category and subcategory
	var info = GetCategoryInfo();
	
	// get list of miniBox divs in the "this" object
	var miniBoxList = YD.getElementsByClassName('miniBox', 'div', this);

	// for each miniBox, get the category or sub-category name from the albumTitle div
	for (var i = 0; i < miniBoxList.length; i++) 
	{
		// get the albumTitle p tag
		var titleTags = YD.getElementsByClassName("albumTitle", "p", miniBoxList[i]);
		if (titleTags && (titleTags.length > 0))
		{
			// get the link in the albumTitle
			var linkTags = titleTags[0].getElementsByTagName('a');
			if (linkTags && (linkTags.length > 0))
			{
				// grab the name of the category/subcategory from the thumb
				var thumbName = linkTags[0].innerHTML;
				thumbName = thumbName.replace(/\s+|\&[a-z]+;|[^_a-zA-Z0-9-]/g, "_");	// replace illegal CSS chars with underscore
				var newClassName = "thumbnail_";
				if (info.cat)
				{
					newClassName += info.cat + "_";
				}
				if (info.subcat)
				{
					newClassName += info.subcat + "_";
				}
				newClassName += thumbName;
				YD.addClass(miniBoxList[i], newClassName);
			}
		}
		
		// get the photo div in each miniBox
		var photoTags = YD.getElementsByClassName("photo", "div", miniBoxList[i]);
		if (!photoTags || (photoTags.length == 0))
		{
			photoTags = YD.getElementsByClassName("photoLarge", "div", miniBoxList[i]);
		}
		if (photoTags && (photoTags.length > 0))
		{
			// get the link in the photo tag
			var photoLinkTags = photoTags[0].getElementsByTagName('a');
			if (photoLinkTags && (photoLinkTags.length > 0))
			{
				// grab the URL of the gallery
				var link = photoLinkTags[0].href;
				// href should be "/gallery/5608799_ZJ27n"
				var matches = link.match(/\/gallery\/(\d+)_/);
				if (matches && (matches.length > 1))
				{
					YD.addClass(miniBoxList[i], "thumbnail_gallery_" + matches[1]);
				}
				
			}
			
		}
	}
}



YE.onContentReady('categoriesBox', TagThumbs);
YE.onContentReady('subcategoriesBox', TagThumbs);
YE.onContentReady('galleriesBox', TagThumbs);

//====End of TagThumbs====

// Script to change the breadcrumb link to your homepage to point to your galleries page instead of your slideshow
// It also changes that link to say "Galleries" instead of your user name

function AdjustBreadcrumb()
{
    // there are something like six different forms of the breadcrumb including search and keyword and date and communities, categories and galleries that we have to make this work for
    var tags = YD.getElementsByClassName("nav", "a", this);        // get all the <a> tags with class "nav"
    var filteredTags = new Array;
    // filter out any that aren't at the top level in the breadCrumbTrail (this gets rid of the relatedDate tags)
    for (var i in tags)
    {
        if (tags[i].parentNode == this)
        {
            filteredTags.push(tags[i]);
        }
    }
    if (filteredTags.length == 0)
    {
        return;
    }
    // default to targeting the first filtered tag
    var targetTag = filteredTags[0];
    
    // see if we have a community here
    if (filteredTags.length > 1)
    {
        // if we have a community here, then the user top level is in the 2nd position
        if (filteredTags[0].href.search(/\/community\//) != -1)
        {
            targetTag = filteredTags[1];
        }
    }
    // make sure URL ends with a slash
    var str = targetTag.href;
    if (str.search(/\/$/) == -1)
    {
        str += "/";
    }
    str +="galleries";
    targetTag.href = str;
    targetTag.innerHTML = "Galleries";
}

YE.onContentReady("breadCrumbTrail", AdjustBreadcrumb);