//This is copied over from prototype since we don't want to fully include it here
var Class = {
	create: function() {
		return function() {
		  this.initialize.apply(this, arguments);
		}
	}
}

/**
 * QueryParser
 * Takes a query string and qscr value and creates a hashmap
 * of name value pairs to aid in rewriting urls
 * 
 * @author <a href="mailto:mkirsch@expedia.com">mkirsch</a>
 * 
 */
var QueryParser = Class.create();
QueryParser.prototype = 
{
	initialize: function(queryString, qscrValue, form)
	{
		this.queryString = queryString;
		this.qscrValue = qscrValue;
		this.queryHash = null;
		this.form = form;
	},
	isHashed: function()
	{
		return null != this.queryHash;
	},
	//Adds parameters from the query string to the has as well as teh qscrValue
	createHash: function()
	{
		if(this.isHashed())
		{
			return;
		}
		else
		{
			this.queryHash = new Object();
			
			//Add the qscrValue first
			this.queryHash['qscr'] = this.qscrValue;
			if(this.queryString != '')
			{
				var nameValues = this.queryString.split('&');
				var i, c=nameValues.length;
				for(i=0; i<c; i++)
				{
					var parts=nameValues[i].split('=');
					var name=parts[0];
					var value='';
				
					if(2 == parts.length)
					{
						value=parts[1];
					}
					
					if(!this.queryHash[name])
					{
						this.queryHash[name] = value;
					}
				}
			}
			if(this.form != null)
			{
				var x = this.form;
				if(x.length > 0)
				{
					for (var i=0;i < x.length;i++)
					{
						var name = x.elements[i].name;
						if(name != '')
						{
							if(!this.queryHash[name])
							{
								this.queryHash[name] = x.elements[i].value;
							}
						}
					}
				}
			}
		}
	},
	getQueryHash: function()
	{
		if(!this.isHashed())
		{
			this.createHash();
		}

		return this.queryHash;
	},
	//Gets a value from the hash given the name
	getValue: function(name)
	{
		if(!this.isHashed())
		{
			this.createHash();
		}

		var value = this.queryHash[name];
		return value ? value : '';
	},
	//Returns true or false based on whether or not a flag was set for this
	//character
	getFlag: function(ch)
	{
		var flag = this.getValue('flag');
		return -1 == flag.indexOf(ch);
	}
}

/**
 * UrlRedirector
 * This class allows for url rediction by acting as a container RedirectRules.
 * It then tests the rules and applies their rewrite methods
 * 
 * @author <a href="mailto:mkirsch@expedia.com">mkirsch</a>
 * 
 */
UrlRedirector = Class.create();
UrlRedirector.prototype =
{
	initialize: function()
	{
		this.redirectRules = [];	
	},
	addRedirectRule: function(redirectRule)
	{
		this.redirectRules[this.redirectRules.length] = redirectRule;
	},
	//Determines if a given url has an applying rule
	isRedirectable: function(qscrTag, queryString, form)
	{
		var qp = new QueryParser(queryString, qscrTag, form);
		
		var redirectRule = this.getRule(qp);
		
		return null != redirectRule;
	},
	//Retrieves the new url given form information.  
	//If no rule applies the old url is returned.
	getRedirectUrl: function(url, qscrTag, queryString, form)
	{
		var newUrl = url;
		var qp = new QueryParser(queryString, qscrTag, form);
		
		var redirectRule = this.getRule(qp);
		if(null != redirectRule)
		{
			newUrl = redirectRule.createRedirect(qp);
		}
		return newUrl;
	},
//This is not used at the moment	
//	redirect: function(url, qscrTag, queryString, form)
//	{
//		var newUrl = this.getRedirectUrl(url, qscrTag, queryString, form);
//		if(null != newUrl)
//		{
//			window.location.href = newUrl;
//		}
//		else
//		{
//			window.location.href = url;
//		}
//	},
	//Retrieves the url which is capable of redirecting the query parser
	getRule: function(queryParser)
	{
		var isFound = false;
		var redirectRule = null;
		if(queryParser)
		{
			var i=0;
			var c=this.redirectRules.length;
			for(i=0;i<c && !isFound;i++)
			{
				redirectRule = this.redirectRules[i];
				isFound = redirectRule.isRedirect(queryParser);
			}
		}
		
		if(!isFound)
		{
			redirectRule = null;
		}
		return redirectRule;
	}
};

/**
 * UrlRedirectRule
 * Each rule consists of 2 methods.  One that tests if a given rule applies
 * and second the rule that rewrites the url
 * 
 * @author <a href="mailto:mkirsch@expedia.com">mkirsch</a>
 * 
 */
UrlRedirectRule = Class.create();
UrlRedirectRule.prototype =
{
	initialize: function(fnIsRedirect, fnCreateRedirect)
	{
		this.isRedirect = fnIsRedirect;
		this.createRedirect = fnCreateRedirect;
	}
}