StyleSheetSelect = function(settings)
{
	///	<summary>Creates a select (dropdownlist) that can be used to switch between alternate style sheets</summary>
	/// <param name="settings" type="object" optional="true">Optional settings in object literal notation, e.g., { id: "StyleSheetSelect", label: "Style: " ... }</param>
	/// <remarks>
	///	
	/// </remarks>

	// settings
	var settings = settings || {};
	this._id = typeof settings.id != "undefined" ? settings.id : "StyleSheetSelect";
	this._label = typeof settings.label != "undefined" ? settings.label : "";
	this._title = typeof settings.title != "undefined" ? settings.title : "Style";
	this._cookieName = typeof settings.cookieName != "undefined" ? settings.cookieName : "StyleSheet";
	this._cookieDays = typeof settings.cookieDays != "undefined" ? settings.cookieDays : 0;
	
	// class variables
	this._select = null;
	this._alternateStyleSheets = [];
	this._alternateStyleSheetTitles = [];
	this._preferredStyleSheetTitle = "";

	// initialization
	this.getAlternateStyleSheets();
	this.insertSelect();
	this.setActiveStyleSheets();
}

StyleSheetSelect.prototype = 
{
	getAlternateStyleSheets: function()
	{
		/// <summary>Gets arrays of alternate stylesheets and alternate stylesheet titles, and the preferred stylesheet title, if any.</summary>
		/// <remarks>There may be multiple stylesheets with the same title.</remarks>
		var links = document.getElementsByTagName("link");
		for (var i = 0, n = links.length; i < n; i++) {
			var link = links[i];
			if (link.rel.indexOf("stylesheet") != -1 && link.title) {
				this._alternateStyleSheets.push(link);
				if (!Utility.inArray(link.title, this._alternateStyleSheetTitles))
				{
					this._alternateStyleSheetTitles.push(link.title);
				}
				if (this._preferredStyleSheetTitle == "" && link.rel.indexOf("alternate") == -1) {
					this._preferredStyleSheetTitle = link.title;
				}
				link.disabled = true; // initially disable all alternate stylesheets so IE & Webkit are able to re-enable them 
			}
		}
	},
	
	insertSelect: function()
	{
		/// <summary>Creates and inserts the stylesheet select (dropdownlist)</summary>
		if (this._alternateStyleSheets.length > 0) {
			var selectedStyleSheetTitle = Utility.inArray(Utility.getCookie(this._cookieName), this._alternateStyleSheetTitles) ? Utility.getCookie(this._cookieName) : this._preferredStyleSheetTitle;
			var parent = document.getElementById(this._id) || document.body;
			var select = document.createElement("select");
			select.id = this._id + "Select";
			select.onchange = Utility.createDelegate(this, this.setActiveStyleSheets);
			if (!this._label) {
				select.title = this._title;	
			}
			if (this._preferredStyleSheetTitle == "") {
				select.appendChild(document.createElement("option"));
			}
			for (var i = 0, n = this._alternateStyleSheetTitles.length; i < n; i++) {
				var option = document.createElement("option");
				option.appendChild(document.createTextNode(option.value = this._alternateStyleSheetTitles[i]));
				if (this._alternateStyleSheetTitles[i] == selectedStyleSheetTitle) {
					option.selected = true;
				}
				select.appendChild(option);
			}
			this._select = parent.insertBefore(select, parent.firstChild);
			if (this._label) {
				var label = document.createElement("label");
				label.htmlFor = select.id;
				label.appendChild(document.createTextNode(this._label));
				parent.insertBefore(label, this._select);
			}
		}
	},

	setActiveStyleSheets: function() 
	{
		/// <summary>Disables all but the selected alternate stylesheets; Sets a cookie to store the selection.</summary>
		if (this._select) {
			for (var i = 0, n = this._alternateStyleSheets.length; i < n; i++) {
				this._alternateStyleSheets[i].disabled = (this._alternateStyleSheets[i].title != this._select.value);
			}
			Utility.setCookie(this._cookieName, this._select.value, this._cookieDays);
		}	
	}
	
}

StyleSheetSelect.init = function(settings)
{
	///	<summary>Static method that initializes a StyleSheetSelect.</summary>
	/// <param name="settings" type="object" optional="true">Optional settings in object literal notation, e.g., { id: "StyleSheetSelect", label: "Style: " ... }</param>
	if (document.getElementsByTagName && document.createElement && Function.apply) {
		var styleSheetSelect = new StyleSheetSelect(settings);
	}
}

// Utility Methods
var Utility = Utility ||
{
	///	<summary>Utility Class</summary>
}

Utility.createDelegate = Utility.createDelegate || function(instance, method, argumentsArray)
{
	/// <summary>Creates a delegate to allow the specified method to run in the context of the specified instance.</summary>
	///	<param name="instance" type="Object"></param>
	///	<param name="method" type="Function"></param>
	///	<param name="argumentsArray" type="Array" optional="true">Optional arguments to pass on to the specified method.</param>
	/// <returns type="Function"></returns>
	///	<remarks>
	///	 Allows "this" in event handlers to reference a specific object rather than the event source element.
	///	 Syntax: element.eventhandler = Utility.createDelegate(this, this.method, [optionalArgument1, optionalArgument2, ...])
	///	 Not supported in Internet Explorer 5.0 or earlier.
	///	</remarks>
	return function() {
		return method.apply(instance, argumentsArray || []);
	}
}

Utility.inArray = Utility.inArray || function(value, array)
{
	/// <summary>Indicates whether a specified value exists within an array.</summary>
	///	<param name="value" type="Object"></param>
	///	<param name="array" type="array"></param>
	/// <returns type="boolean"></returns>
	for (var i = 0; i < array.length; i++) {
		if (array[i] === value) { 
			return true;
		} 
	} 
	return false; 
}

Utility.getCookie = Utility.getCookie || function(name) {
	/// <summary>Gets the value of a specified cookie.</summary>
	///	<param name="name" type="string"></param>
	/// <returns type="string"></returns>
	var match = document.cookie.match("(^|;) ?" + name + "=([^;]*)(;|$)");
	return match ? unescape(match[2]) : null;
}

Utility.setCookie = Utility.setCookie || function(name, value, days, path, domain, secure) {
	/// <summary>Stores a cookie with the specified parameters.</summary>
	///	<param name="name" type="string"></param>
	///	<param name="value" type="string"></param>
	///	<param name="days" type="int"></param>
	///	<param name="path" type="string"></param>
	///	<param name="domain" type="string"></param>
	///	<param name="secure" type="boolean"></param>
	var expirationDate = null;
	if (days && isFinite(days)) {
		var expirationDate = new Date();
		expirationDate.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
	}
	document.cookie = name + "=" + escape(value) + (expirationDate ? ";expires=" + expirationDate.toGMTString() : "" ) + (path ? ";path=" + escape(path) : "") + (domain ? ";domain=" + escape(domain) : "") + (secure ? ";secure" : "");
}

Utility.addLoadEvent = Utility.addLoadEvent || function(handler)
{
	/// <summary>Adds handlers to window.onload</summary>
	/// <param name="handler" type="function"></param>
	/// <remarks>Usage: addLoadEvent(handler) or addLoadEvent(function() { ... })</remarks>
	var oldonload = window.onload;
	if (typeof window.onload != 'function')	{
		window.onload = handler;
	} 
	else {
		window.onload = function() {
			if (oldonload) { oldonload(); }
			handler();
		}
	}	
}