// Dynamic Font Size Changer


//__________________________________________________________________
//*************************Prototype string methods*****************
//	Required by FontSizer - do not seperate!
//___________________________________________________________________

//returns just the numeric part of the string
//only reads numbers up until it finds NAN
String.prototype.DropAlpha = function()
{
var strRetVal = new String();
var strValidChars = "0123456789.";

	for(var i=0;i<this.length;i++)
	{
		if(strValidChars.indexOf(this.charAt(i)) > -1)	//is this a numeric value??
		{//Aye
			strRetVal += this.charAt(i);		
		}
		else
		{//nope
			break;	//drop out of loop - NAN reached
		}	
	}	
	return strRetVal;	//send it back as a string
}

//returns the NAN part of the string - The NAN part is anything from 
//the first occorance of a NAN char onwards.
String.prototype.GetNAN = function()
{
var rubbish = new String();

	rubbish = this.DropAlpha();	//we need this to measure!
	//we want to return the string after the number - but all the string if NAN
	if(rubbish.length > 0)	return this.substr(rubbish.length);
	else return this;
}

//returns the index of 'var' in a single dimensioned array.  returns -1 if not found
Array.prototype.FindIndex = function (val)
{
var found = new Boolean;

	found = false;
	for(y=0; y < this.length; y++)
	{
		if(this[y] == val)
		{
			found = true;
			break;
		}
	}
	if(found == true) return y;
	else return -1;
}

//Constructor (Class) for FontSizer object
//	--------------------------------------------------------------------------------
// Params:
// 	nMaxIncrease 	- Maximum % increase to allow
//	nChangePercent 	- The percentage increase or decrease to apply to the font size
//
//	--------------------------------------------------------------------------------
//
//	*************************  Usage *****************************************
//
//	Instantiate a FontSizer object passing the  required parameters 
//		var fontControl = new FontSizer(50,10);
//
//	Call one of the follwoing methods to set the scope of the font change.
//
//		SetScopeID(arrVals) 	- an array of strings containing element ID's
//		SetScopeClass(arrVals) 	- an array of string containing Classes
//		SetScopeTags(arrVals)	- an array of strings containg Tags
//		SetScopeAll()			- (default) Applies the settings to the entire document.
//
//	You may only set scope by one defining property, so a call to one scope method
//	immediatley after a call to another will disable the previous scoping rule.
//
//	You may add restrictions to the scoping by calling one of the following methods
//	In each case arrVals is an string array of relvant values either id's classes, or tags
//
//		SetRestrictionsID(arrVals)		- Restrict by ID
//		SetRestrictionsClass(arrVals)	- Restrict by Class
//		SetRestrictionsTags(arrVals)	- Restrcited by Tag
//		SetRestrictionsNone()			- (default) Remove all restrcitions
//
//	Note that unlike SetScope you may have multiple restrictions applied, so
//	for example you could restrict an entire class and also certain id's or tags.
//	Bear in mind that retricting an element does not absolutley preserve its settings
//	as it may be changed through inheritence, such as by changing a parent element.
//
//	The font size can then be changed by calling either:
//	
//		IncreaseFont()
//		DecreaseFont()
//
//	An implimentation of this object that was required to act on an entire document would be as follows:
//	
//		var fontControl = new FontSizer(50,10);		//init object
//		fontControl.IncreaseFont()	//incerase font
//		fontCOntrol.DecreaseFont()  //reduce font
//
//	An implimentation that was required to change all P, DIV and A tags but not touch TD tags
//	or any tags that have a class of fixed-font:
//
//		var fontControl = new FontSizer(50,10);		//init object
//
//			//construct the arrays of scope and Restriction values
//
//		var arrTags = new Array ('div', 'p', 'a'); 
//		var arrExludesID = new Array ('fixed_font');
//
//		//apply the scope and restrction settings
//
//		fontControl.SetScopeTags(arrTags);
//		fontControl.SetRestrictionsID(arrExcludesID);
//
//		fontControl.IncreaseFont()	//incerase font
//		fontControl.DecreaseFont()  //reduce font
//
//	Additional properties are:
//		
//		.bDisplayExceptions (true/false) [default false]	- turn debugging on/off
//		.bDisableAfterException (true/false) [default true] - Disable script after an exception
//		.bPersist 			(true/false) [default true] - turn cookie persistance on/off
//
//	******************************* setup **************************************
//		
//	Add an onload event that calls a function that constructs the object with the 
//	required settings.
//
//	reference the (object).DecreaseFont() and .IncreaseFont() methods from within
//	script or using a script reference in a HTML event such as in an 
//	anchor <A href="javascript:(object).IncreaseFont();">Bigger</A>
//
//	Note - For persistant state functionality to work correctly across browsers 
//		the FontSizer object must be initialised after document load.
function FontSizer(nMaxIncrease, nChangePercent)
{
	//properties
	this.nFontChangePercent = nChangePercent;
	this.nMaxUp = nMaxIncrease;
	this.nMaxDown = 0;
	this.bDisplayExceptions = new Boolean(false);
	this.bDisableAfterException = new Boolean(true);
	this.bEnabled = new Boolean(true);
	this.bPersist = new Boolean(true);
	this.dontUpdate = new Boolean(false);
	this.FirstTagBase = "";
	this.FirstTagCurrent = "";
	this.bFirstExecute = new Boolean(true);
	this.nPerFactor = 0;
	
	//nested object
	this.Scope = new iScope();
	this.RestoreState();	//restore any existing state from cookie
}

//-------------------------------------------
//	Scope constructor, stores object state for scope and restrictions
//		Used internally by the FontSizer object
//
function iScope()
{
	//member properties
	this.scopeMethod = "all";
	this.arrScopeVars = new Array();
	this.arrRestrictionID = new Array();
	this.arrRestrictionTag = new Array();
	this.arrRestrictionClass = new Array();
}
	
	
//________________________________________________
//member functions follow (Scope)
//________________________________________________

//returns true or false dependant on if the (strVal) of the type(strType)
//is set as restricted in the relivant scope array
iScope.prototype.IsRestricted = function(strType,strVal)
{
var bRestricted = new Boolean(false);

	switch(strType)	//find the case we are dealing with
	{
		case "tag" :
			{		//check if array contains val
				if(this.arrRestrictionTag.FindIndex(strVal) > -1)
				{
					bRestricted = true;
				}		
				break;
			}
		case "class" :
			{
				//check if array contains val
				if(this.arrRestrictionClass.FindIndex(strVal) > -1)
				{
					bRestricted = true;
				}				
				break;
			}
		case "id" :
			{
				//check if array contains val
				if(this.arrRestrictionID.FindIndex(strVal) > -1)
				{
					bRestricted = true;
				}
				break;
			}
		default :
			{
				myException = new Exception("(IsRestricted) Parameter strType is not of valid type.");
				throw myException;
				break;
			}		
	}	
	return bRestricted
}

//Returns true or false indicating if the supplied element is a member of the
//scope vars array
iScope.prototype.IsInScope = function(strVal)
{
	//check scope array for strVal return true if found, else false
	if(arrScopeVars.FindIndex(strVal)) return true;
	else return false;
}

//________________________________________________
//member functions follow (FontSizer)
//_______________________________________________

//sets an array of element ids that are not to have their
//font sizes adjusted
FontSizer.prototype.SetRestrictionsID = function(arrVals)
{
	try
	{
		this.Scope.arrRestrictionID = arrVals;		
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetRestrictionsID) Exception raised - " + e.message);
		throw myException;
	}
}

//Sets an array Classes that are not to have their font size
//adjusted
FontSizer.prototype.SetRestrictionsClass = function(arrVals)
{
	try
	{
		this.Scope.arrRestrictionClass = arrVals;		
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetRestrictionsClass) Exception raised - " + e.message);
		throw myException;
	}
}

//Sets an array of tags that should not have their
//font size modified
FontSizer.prototype.SetRestrictionsTags = function(arrVals)
{
	try
	{		
		this.Scope.arrRestrictionTag = arrVals;		
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetRestrictionsTags) Exception raised - " + e.message);
		throw myException;
	}
}

//Removes all existing restrictions
FontSizer.prototype.SetRestrictionsNone = function()
{
	try
	{	//simple blank all the arrays
		this.Scope.arrRestrictionTag = new Array();	
		this.Scope.arrRestrictionClass = new Array();
		this.Scope.arrRestrictionID = new Array();
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetRestrictionsNone) Exception raised - " + e.message);
		throw myException;
	}
}

//Sets the scope to element id and provides an array of element id's that
//should have their font sizes changed
FontSizer.prototype.SetScopeID = function(arrVals)
{
	try
	{	//set the vars array
		this.Scope.arrScopeVars = arrVals;		
		this.scopeMethod = "id";	//set the method
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetScopeID) Exception raised - " + e.message);
		throw myException;
	}	
}

//Sets the scope to class and provides an array of classes that
//should have their font sizes changed
FontSizer.prototype.SetScopeClass = function(arrVals)
{
	try
	{	//set the vars array
		this.Scope.arrScopeVars = arrVals;		
		this.scopeMethod = "class";	//set the method
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetScopeClass) Exception raised - " + e.message);
		throw myException;
	}	
}

//Sets the scope to tag and provides an array of tags that
//should have their font sizes changed
FontSizer.prototype.SetScopeTags = function(arrVals)
{
	try
	{	//set the vars array
		this.Scope.arrScopeVars = arrVals;		
		this.scopeMethod = "tags";	//set the method
	}
	catch(e)
	{	//pass it on
		myException = new Exception("(SetScopeTags) Exception raised - " + e.message);
		throw myException;
	}	
}

//sets the scope to global and denotes that every element with a font size 
//property should have it adjusted
FontSizer.prototype.SetScopeAll = function()
{
	this.Scope.scopeMethod = "all";
}

FontSizer.prototype.IncreaseFont = function()
{
	if((this.nPerFactor < this.nMaxUp) && (this.bEnabled == true) || this.dontUpdate == true)	//are we within set limits
	{
		try
		{		
			//what scoping method are we using?
			switch (this.Scope.scopeMethod)
			{				
				case "all":
				{
					this.ResizeFontAll("up");
					break;
				}			
				case 'tags':
				{
					this.ResizeFontTags("up");
					break;
				}			
				case 'class':
				{
					this.ResizeFontClass("up");
					break;
				}			
				case 'id':
				{
					this.ResizeFontID("up");
					break;
				}	
				default :
				{				
					myException = new Exception("(IncreaseFont) ScopeMethod is not valid : " + this.Scope.scopeMethod);
					throw myException;
				}
			}
			//preserve the new settings
			if(this.dontUpdate == false)
			{
				this.PreserveState();
			}
		}
		catch(e)
		{
			if(this.bDisplayExceptions == true)
			{
				var strMessage = new String();
				strMessage = "An exception has been caught : " + e.name + " : " + e.message;
				alert(strMessage);
			}
			if(this.bDisableAfterException == true)
			{
				this.bEnabled = false;
			}
		}		
	}
}

FontSizer.prototype.DecreaseFont = function()
{	
	if(this.nPerFactor > 0 && this.bEnabled == true)	//within good limits?
	{
		try
		{		
			var oldVal = this.nFontChangePercent;
			//are going to drop below the starting size of the page?
			if(this.nPerFactor - this.nFontChangePercent < 0)
			{//we need to normalise back to the starting factor
				this.nFontChangePercent = this.nPerFactor;
			}
			
			//what scoping method are we using?
			switch (this.Scope.scopeMethod)
			{			
				case "all" :
				{
					this.ResizeFontAll("down");
					break;
				}
				
				case "tags" :
				{
					this.ResizeFontTags("down");
					break;
				}
				
				case "class" :
				{
					this.ResizeFontClass("down");
					break;
				}
				
				case "id" :
				{
					this.ResizeFontID("down");
					break;
				}
				default :
				{
					this.nFontChangePercent = oldVal;	//set this back
					myException = new Exception("(DecreaseFont) ScopeMethod is not valid : " + this.Scope.scopeMethod);
					throw myException;
				}
			}
			this.nFontChangePercent = oldVal;	//set this back
			//preserve the new settings
			if(this.dontUpdate == false)
			{
				this.PreserveState();
			}
		}
		catch(e)
		{
			if(this.bDisplayExceptions == true)
			{
				var strMessage = new String();
				strMessage = "An exception has been caught : " + e.name + " : " + e.message;
				alert(strMessage);
			}
			if(this.bDisableAfterException == true)
			{
				this.bEnabled = false;
			}			
		}		
	}
}

//resizes fonts in the entire document
FontSizer.prototype.ResizeFontAll = function(strDirection)
{	//cycle through all obvious tags and update font size accordingly
var bFirstTag = new Boolean(true);

	if (document.getElementsByTagName)
	{		
		try
		{
			tags = new Array('body');	//may need more here, but on most browsers body is good - firefox linux needs table also!
			//tags = new Array ('body','div','span','p', 'h1','h2','h3','h4','h5','h6','strong','em','abbr','acronym','address','bdo','blockquote','cite','q','code','ins','del','dfn','kbd','pre','samp','var','br','a','base','ul','ol','li','dl','dt','dd','table','tr','td','th','tbody','thead','tfoot','col','colgroup','caption','form','input','textarea','select','option','optgroup','button','label','fieldset','legend'); 			
	
			for (j = 0; j < tags.length; j ++) 
	  		{ 
				//is this an excluded tag
				if(this.Scope.IsRestricted("tag",tags[j]) == false)
				{					
					var tagElements = document.getElementsByTagName(tags[j]); 
							
					for (i = 0; i < tagElements.length; i ++) 
					{ 
						var objElement = tagElements[i];
						//is this an excluded element?
						if(this.Scope.IsRestricted("class",objElement.className) == false && this.Scope.IsRestricted("id",objElement.id) == false) 
						{
							if(objElement.innerHTML != "")	//no point changing styles for tags with no contents
							{
								var fontSize = this.GetCurrentSize(objElement);
								//if we are good to go
								if(fontSize != "disable" && fontSize != "undefined")	//did we get the value?
								{									
									if(this.bFirstExecute == true)
									{
										this.FirstTagBase = fontSize.DropAlpha();	//store the original value of first tag											
										this.bFirstExecute = false;					//we need this for calculating factor	
									}									
									if(strDirection == "up")	//enlarge the font
									{								
										var pxVal = parseInt(fontSize.DropAlpha());
										var newFontSize = pxVal + this.GetPercentageFromPX(pxVal);
										objElement.style.fontSize = newFontSize + fontSize.GetNAN();								
									}
									else
									{//reduce the font							
										var pxVal = parseInt(fontSize.DropAlpha());
										var newFontSize = pxVal - this.GetPercentageFromPX(pxVal);
										objElement.style.fontSize = newFontSize + fontSize.GetNAN(); 					
									}
									if(bFirstTag == true)
									{	//calculate the factor increase / decrease
										this.FirstTagCurrent = newFontSize;
										this.nPerFactor = ((this.FirstTagCurrent - this.FirstTagBase)/ (this.FirstTagBase)) * 100;
										bFirstTag = false;
									}																	
								}
							}	
						}
					}
				}				
			}
		}
		catch(e)
		{//pass it on
			myException = new Exception("(ResizeFontAll) Exception thrown - " + e.message);
			throw myException;
		}
	}
	else
	{//throw a compatibility exception
		myException = new Exception("Browser is not compatible with getElementsByTagName");
		throw myException;
	}
}

//resizes fonts with a specified class (set by state)
FontSizer.prototype.ResizeFontClass = function(strDirection)
{
	if (document.getElementsByTagName)
	{
		try
		{
			tags = new Array ('body','div','span','p', 'h1','h2','h3','h4','h5','h6','strong','em','abbr','acronym','address','bdo','blockquote','cite','q','code','ins','del','dfn','kbd','pre','samp','var','br','a','base','ul','ol','li','dl','dt','dd','table','tr','td','th','tbody','thead','tfoot','col','colgroup','caption','form','input','textarea','select','option','optgroup','button','label','fieldset','legend'); 			
			for (j = 0; j < tags.length; j ++) 
	  		{ 
				//is this an excluded tag
				if(this.Scope.IsRestricted("tag",tags[j]) == false)
				{
					var tagElements = document.getElementsByTagName(tags[j]); 
							
					for (i = 0; i < tagElements.length; i ++) 
					{ 
						var objElement = tagElements[i];
						//is this an included element? check its class?
						if(this.Scope.IsInScope(objElement.className) == true)
						{
							//is this an excluded element?
							if(this.Scope.IsRestricted("class",objElement.className) == false && this.Scope.IsRestricted("id",objElement.id) == false) 
							{
								if(objElement.innerHTML != "")	//no point changing styles for tags with no contents
								{
									var fontSize = this.GetCurrentSize(objElement);
									//if we are good to go
									if(fontSize != "disable" && fontSize != "undefined")	//did we get the value?
									{									
										if(this.bFirstExecute == true)
										{
											this.FirstTagBase = fontSize.DropAlpha();	//store the original value of first tag											
											this.bFirstExecute = false;					//we need this for calculating factor	
										}									
										if(strDirection == "up")	//enlarge the font
										{								
											var pxVal = parseInt(fontSize.DropAlpha());
											var newFontSize = pxVal + this.GetPercentageFromPX(pxVal);
											objElement.style.fontSize = newFontSize + fontSize.GetNAN();								
										}
										else
										{//reduce the font							
											var pxVal = parseInt(fontSize.DropAlpha());
											var newFontSize = pxVal - this.GetPercentageFromPX(pxVal);
											objElement.style.fontSize = newFontSize + fontSize.GetNAN(); 					
										}
										if(bFirstTag == true)
										{	//calculate the factor increase / decrease
											this.FirstTagCurrent = newFontSize;
											this.nPerFactor = ((this.FirstTagCurrent - this.FirstTagBase)/ (this.FirstTagBase)) * 100;
											bFirstTag = false;
										}																	
									}
								}	
							}
						}
					}
				}				
			}
		}
		catch(e)
		{//pass it on
			myException = new Exception("(ResizeFontAll) Exception thrown - " + e.message);
			throw myException;
		}
	}
	else
	{//throw a compatibility exception
		myException = new Exception("Browser is not compatible with getElementsByTagName");
		throw myException;
	}
}

//resizes fonts on specified elements (set by state)
FontSizer.prototype.ResizeFontTags = function(strDirection)
{
	if (document.getElementsByTagName)
	{
		try
		{
			//we are scoping by tags so only use those provided.
			tags = this.Scope.arrScopeVars; 			
			for (j = 0; j < tags.length; j ++) 
	  		{ 
				//is this an excluded tag
				if(this.Scope.IsRestricted("tag",tags[j]) == false)
				{
					var tagElements = document.getElementsByTagName(tags[j]); 
							
					for (i = 0; i < tagElements.length; i ++) 
					{ 
						var objElement = tagElements[i];
						//is this an excluded element?
						if(this.Scope.IsRestricted("class",objElement.className) == false && this.Scope.IsRestricted("id",objElement.id) == false) 
						{
							if(objElement.innerHTML != "")	//no point changing styles for tags with no contents
							{
								var fontSize = this.GetCurrentSize(objElement);
								//if we are good to go
								if(fontSize != "disable" && fontSize != "undefined")	//did we get the value?
								{									
									if(this.bFirstExecute == true)
									{
										this.FirstTagBase = fontSize.DropAlpha();	//store the original value of first tag											
										this.bFirstExecute = false;					//we need this for calculating factor	
									}									
									if(strDirection == "up")	//enlarge the font
									{								
										var pxVal = parseInt(fontSize.DropAlpha());
										var newFontSize = pxVal + this.GetPercentageFromPX(pxVal);
										objElement.style.fontSize = newFontSize + fontSize.GetNAN();								
									}
									else
									{//reduce the font							
										var pxVal = parseInt(fontSize.DropAlpha());
										var newFontSize = pxVal - this.GetPercentageFromPX(pxVal);
										objElement.style.fontSize = newFontSize + fontSize.GetNAN(); 					
									}
									if(bFirstTag == true)
									{	//calculate the factor increase / decrease
										this.FirstTagCurrent = newFontSize;
										this.nPerFactor = ((this.FirstTagCurrent - this.FirstTagBase)/ (this.FirstTagBase)) * 100;
										bFirstTag = false;
									}																	
								}
							}	
						}
					}
				}				
			}
		}
		catch(e)
		{//pass it on
			myException = new Exception("(ResizeFontAll) Exception thrown - " + e.message);
			throw myException;
		}
	}
	else
	{//throw a compatibility exception
		myException = new Exception("Browser is not compatible with getElementsByTagName");
		throw myException;
	}	
}

//resizes fonts by id (set by state)
FontSizer.prototype.ResizeFontID = function(strDirection)
{
	if (document.getElementsByTagName)
	{
		try
		{
			tags = new Array ('body','div','span','p', 'h1','h2','h3','h4','h5','h6','strong','em','abbr','acronym','address','bdo','blockquote','cite','q','code','ins','del','dfn','kbd','pre','samp','var','br','a','base','ul','ol','li','dl','dt','dd','table','tr','td','th','tbody','thead','tfoot','col','colgroup','caption','form','input','textarea','select','option','optgroup','button','label','fieldset','legend'); 			
			for (j = 0; j < tags.length; j ++) 
	  		{ 
				//is this an excluded tag
				if(this.Scope.IsRestricted("tag",tags[j]) == false)
				{
					var tagElements = document.getElementsByTagName(tags[j]); 
							
					for (i = 0; i < tagElements.length; i ++) 
					{ 
						var objElement = tagElements[i];
						//is this an included element? check its id
						if(this.Scope.IsInScope(objElement.id) == true)
						{
							//is this an excluded element?
							if(this.Scope.IsRestricted("class",objElement.className) == false && this.Scope.IsRestricted("id",objElement.id) == false) 
							{
								if(objElement.innerHTML != "")	//no point changing styles for tags with no contents
								{
									var fontSize = this.GetCurrentSize(objElement);
									//if we are good to go
									if(fontSize != "disable" && fontSize != "undefined")	//did we get the value?
									{									
										if(this.bFirstExecute == true)
										{
											this.FirstTagBase = fontSize.DropAlpha();	//store the original value of first tag											
											this.bFirstExecute = false;					//we need this for calculating factor	
										}									
										if(strDirection == "up")	//enlarge the font
										{								
											var pxVal = parseInt(fontSize.DropAlpha());
											var newFontSize = pxVal + this.GetPercentageFromPX(pxVal);
											objElement.style.fontSize = newFontSize + fontSize.GetNAN();								
										}
										else
										{//reduce the font							
											var pxVal = parseInt(fontSize.DropAlpha());
											var newFontSize = pxVal - this.GetPercentageFromPX(pxVal);
											objElement.style.fontSize = newFontSize + fontSize.GetNAN(); 					
										}
										if(bFirstTag == true)
										{	//calculate the factor increase / decrease
											this.FirstTagCurrent = newFontSize;
											this.nPerFactor = ((this.FirstTagCurrent - this.FirstTagBase)/ (this.FirstTagBase)) * 100;
											bFirstTag = false;
										}																	
									}
								}	
							}
						}
					}
				}				
			}
		}
		catch(e)
		{//pass it on
			myException = new Exception("(ResizeFontAll) Exception thrown - " + e.message);
			throw myException;
		}
	}
	else
	{//throw a compatibility exception
		myException = new Exception("Browser is not compatible with getElementsByTagName");
		throw myException;
	}
}

//gets the current font size for the element (objElement)
FontSizer.prototype.GetCurrentSize = function(objElement)
{
	try
	{
		if (objElement.currentStyle)	//ie
		{
			fontSize = objElement.currentStyle['fontSize'];
		}
		else if (window.getComputedStyle) //opera and firefox
		{
			fontSize = document.defaultView.getComputedStyle(objElement,null).getPropertyValue('font-Size');
		}
		else
		{
			return "disable";	//we cannot get the font size using this browser!
		}	
		
		return fontSize;
	}
	catch(e)
	{
		return "undefined";
	}
}

//takes a px value and returns the value in px of nFontChangePercent
FontSizer.prototype.GetPercentageFromPX = function(pxSize)
{
	return (this.nFontChangePercent/100)*pxSize;
}

//serialise state to cookie
FontSizer.prototype.PreserveState = function()
{
	//we need to serialise settings to the cookie
	try
	{
		if(this.bPersist == true)	//we need to save state
		{
			CreateCookie("scopemethod",this.Scope.scopeMethod,null);
			CreateCookie("displayexceptions",this.bDisplayExceptions,null);
			CreateCookie("disableafterexception",this.bDisableAfterException,null);
			CreateCookie("fontchangepercent",this.nFontChangePercent,null);
			CreateCookie("maxincrease",this.nMaxIncrease,null);
			CreateCookie("maxdecrease",this.nMaxDecrease,null);
			CreateCookie("enabled",this.bEnabled,null);
			CreateCookie("perFactor",this.nPerFactor,null);
			if(this.Scope.arrScopeVars.length > 0)
			{
				CreateCookie("scopevars",this.Scope.arrScopeVars.join(','),null);
			}
			if(this.Scope.arrRestrictionID.length > 0)
			{
				CreateCookie("restrictionid",this.Scope.arrRestrictionID.join(','),null);
			}
			if(this.Scope.arrRestrictionTag.length > 0)
			{
				CreateCookie("restrictiontags",this.Scope.arrRestrictionTag.join(','),null);
			}
			if(this.Scope.arrRestrictionClass.length > 0)
			{
				CreateCookie("restrictionclass",this.Scope.arrRestrictionClass.join(','),null);
			}
		}
	}
	catch(e)
	{
		//ignore this
		//alert(e.message);
	}
}

//restore state from cookie
FontSizer.prototype.RestoreState = function()
{	
	try
	{
		if(ReadCookie("scopemethod") != null)
		{	//we have stored state
			//restore scope method			
			this.Scope.scopeMethod = ReadCookie("scopemethod");
			this.bDisplayExceptions = new Boolean(ReadCookie("displayexceptions"));
			this.bDisableAfterException = new Boolean(ReadCookie("disableafterexception"));
			this.nFontChangePercent = ReadCookie("fontchangepercent");
			this.nMaxIncrease = ReadCookie("maxincrease");
			this.nMaxDecrease = ReadCookie("maxdecrease");
			this.bEnabled = new Boolean(ReadCookie("enabled"));
			this.nPerFactor = ReadCookie("perFactor");
			
			//these are a little more tricky as they are arrays stoed as , delmited strings
			
			if(ReadCookie("scopevars") != null)
			{
				this.Scope.arrScopeVars = new Array(ReadCookie("scopevars"));
			}
			if(ReadCookie("restrictionid") != null)
			{
				this.Scope.arrRestrictionID = new Array(ReadCookie("restrictionid"));
			}
			if(ReadCookie("restrictiontags") != null)
			{
				this.Scope.arrRestrictionTag = new Array(ReadCookie("restrictiontags"));
			}
			if(ReadCookie("restrictionclass") != null)
			{
				this.Scope.arrRestrictionClass = new Array(ReadCookie("restrictionclass"));
			}
			//so far so good - lets apply the state to the document
			
			if(this.nPerFactor > 0)
			{//we have work to do - must reapply settings to document
				
				this.dontUpdate = true;	//withhold state update

				//get the percentage increase from cookie
				
				//alert(this.nPerFactor);
				
				var temp = this.nFontChangePercent;
				this.nFontChangePercent = this.nPerFactor;
					
				this.IncreaseFont();
				
				this.nFontChangePercent = temp;
				
				this.dontUpdate = false;	//restore state update
			}
		}
		//nothing to do
	}
	catch(e)
	{
		//ignore this
		//alert(e.message);
	}
}

//exception class
function Exception(message) 
{
   this.message = message;
   this.name = "A user defined exception has been caught";
}

//cookie functions  --  Required -- do not seperate!!

function CreateCookie(name,value,days)
{
	if (days)
	{
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function ReadCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++)
	{
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name)
{
	CreateCookie(name,"",-1);
}

function setFont(s){
    var fs = new lclFontSizes();
    // Change the current font size and write the value back to cookie
    document.body.style.fontSize = fs[s];
    document.cookie = FONT_COOKIE + '=' + s;
}

function lclFontSizes(){
    this.normal = '100%';
    //this.normal = '125%';
    this.large = '125%';
    this.largest = '150%';
}


