/**********************************************************************
QS.JS : QS Wrapper Class Library
**********************************************************************/

function QS()
{
	// Inherit from Packed
	// -------------------
	
	// Collections
	this.aData		= new Array();			// Stored data
	this.abValid	= new Array();			// Is data under same key valid ?
	
	// Methods
	this.Add			= Packed_Add;			// Add a mapping
	this.Crop		= Packed_Crop;			// Remove all but one mapping
	this.Feed		= Packed_Feed;			// Create a Packed Object from a true packed array
	this.GetLength	= Packed_GetLength;	// Get number of mappings
	this.GetValue	= Packed_GetValue;	// Obtain a key's value
	this.HasKey		= Packed_HasKey;		// Does this object have this key ?
	this.Mutation	= Packed_Mutation;	// Expert conversion to a string
	this.Remove		= Packed_Remove;		// Remove a mapping
	this.Seed		= Packed_Seed;			// Create a Packed Object from an assoc. array 
	this.Spawn		= Packed_Spawn;		// Create a conversion to an assoc. array
	this.toString	= Packed_toString;	// Default conversion to a string
	
	// New components
	// --------------
	
	// Properties
	this.strURL = "";
	
	// Methods
	this.Combine	= QS_Combine;			// Combine two QS Objects
	this.Flush		= QS_Flush;				// OVERRIDE: Clear all mappings & URL
	this.Load		= QS_Load;				// Load from Gauntlet
	this.Show		= QS_Show;				// Display Full URL contained within
	this.Split		= QS_Split;				// URL+QS ==> URL & QS
	
	var strBuffer = location.search;
	
	// Handle IE3
	if ( !strBuffer )
		strBuffer = document.location.search;
		
	strBuffer = strBuffer.substring( 1, strBuffer.length );
	this.Feed( strBuffer, '&', '=' );
}

// QS::Combine()
// Combine two QS Objects with one another
// qsRight -- Other QS Object to combine with
// bReplace -- Does qsRight's mappings do a replace on collision ?
function QS_Combine( qsRight, bReplace )
{
	if ( this.GetLength() == 0 &&						// Both lval and rval have no mappings.
		qsRight.GetLength() == 0 )						// ..Early exit
		return true;

	var strPreserve = this.strURL;					// Preserve URL property

	if ( this.GetLength() == 0 )						// Invoked object has no mappings,
	{															//	..absorb passed in object
		this.Seed( qsRight.Spawn() );
		this.strURL = strPreserve;
		return true;
	}
	
	if ( qsRight.GetLength() == 0 )					// Passed-in object has no mappings.
		return true;										// ..Early exit
		
	// objects --> strings, then concatenate
	var strLeft		= bReplace ? this.toString()    : qsRight.toString();
	var strRight	= bReplace ? qsRight.toString() : this.toString();
	var strRet		= "";
	
	strLeft += '&' + strRight;
	strRet = this.Feed( strLeft, '&', '=' );		// Feed in concatenation
	this.strURL = strPreserve;
	
	return strRet;
}

// QS::Split()
// Split a URL from its QueryString and assign to this object
// Returns success boolean
function QS_Split( strFullURL )
{
	if ( !strFullURL )																// Malformed parameter
		return false;
		
	var iQuestionMark = strFullURL.indexOf( '?' );							// index of '?'
	var nLen = strFullURL.length;													// length of strFullURL

	if ( iQuestionMark < 0 )														// Handle lack of QueryString
	{
		this.Flush();
		this.strURL = strFullURL;
		return true;
	}
		
	if ( iQuestionMark == 0 )														// '?' cannot be at strFullURL[0]
		return false;
	
	var strBuffer = strFullURL.substring( iQuestionMark + 1, nLen );	// Right of '?' is QueryString
	var bFed = false;																	// Feeding success boolean
	
	bFed = this.Feed( strBuffer, '&', '=' );
	
	if ( bFed )											// Feed in QueryString
	{
		strBuffer = strFullURL.substring( 0, iQuestionMark );				// Left of '?' is URL
		this.strURL = strBuffer;
	}
	
	return bFed;
}

// QS::Flush()
// Empty collections and nullify properties
function QS_Flush()
{
	this.aData		= new Array();
	this.abValid	= new Array();
	this.strURL		= "";
}

// QS::Show()
// Display full URL contained within (URL+?+QueryString)
function QS_Show()
{
	var strBuffer = this.toString();
	
	if ( strBuffer && this.strURL)
		strBuffer = this.strURL + '?' + strBuffer;	// Show both
	else if ( this.strURL )
		strBuffer = this.strURL;							// Show URL
	
	return strBuffer;											// Show QS or NULL
}

// QS::Load()
// Load from Gauntlet
// strLoad -- string to load from
// Return success boolean
function QS_Load( strLoad )
{		
	if ( !this.Feed( strLoad, '&', '=' ) )
		return false;
		
	this.strURL = this.GetValue( "_strURL" );
	this.Remove( "_strURL" );
	
	return true;
}

// -= END of qs.js =-

