// String.js
// Extra methods for String object
//
// Copyright 2001-2004 NobleTech Limited. All rights reserved
// If supplied as part of a project, this file is licenced for internal use
// on that project only. It may not be redistributed in human-readable form
// The contents of this file are declared as pre-existing IPR of NobleTech
// Phone 01235 831746 for further licencing options
// Leave this header intact
//
// Functions declared in this file are mainly added as members
// to the built-in JavaScript object String
//
// This file created by Nathan Phillips of NobleTech Limited
// See version control for history
/////////////////////////////////////////////////////////////////////////////


function String_isAll(fnGuard)
{
	for(var i = 0; i < this.length; i++)
		if( !fnGuard( this.charAt(i) ) )
			return false;
	return true;
}

function String_isAny(fnGuard)
{
	for(var i = 0; i < this.length; i++)
		if( fnGuard( this.charAt(i) ) )
			return true;
	return false;
}

function String_isAllInList(listOfChars)
{
	function isInList(c) { return listOfChars.indexOf( c ) != -1; }
	return this.isAll(isInList);
}

function String_isAnyInList(listOfChars)
{
	function isInList(c) { return listOfChars.indexOf( c ) != -1; }
	return this.isAny(isInList);
}

function String_isWhiteSpace()
{
	return /^\s*$/.test(this);
}

function String_isPunctuation()
{
	return this.isAllInList("\"-?,.!'/()");
}

function String_trimWhiteSpace()
{
	return this.replace(/^\s+|\s+$/g, "");
}

function String_compressWhiteSpace()
{
	return this.replace(/\s+/g, " ");
}

function String_isNumeric()
{
	// Use parseFloat to see if JScript can make sense of it as a number
	return !isNaN(parseFloat(this));
}

function String_isAlphaChar() {
	return this.toLowerCase() != this.toUpperCase();
}

function String_isAlpha()
{
	function isAlphaChar(c) {
		return c.toLowerCase() != c.toUpperCase();
	}
	return this.isAll(isAlphaChar);
}

function String_toTitleCase()
{
	// Not yet used
	var arLowerCaseWords = new Array("and", "of", "a");
	// Whether to capitalise next letter
	var bCapitaliseNext = true;
	var strResult = "";
	for(var nChar = 0; nChar < this.length; nChar++) {
		var c = this.charAt(nChar);
		if( bCapitaliseNext && c.isAlphaChar() ) {
			strResult += c.toUpperCase();
			bCapitaliseNext = false;
		} else {
			strResult += c.toLowerCase();
			if( c.isWhiteSpace() || c.isPunctuation() )
				bCapitaliseNext = true;
		}
	}
	return strResult;
}

function String_toCharArray()
{
	var arChars = new Array();
	for(var nChar = 0; nChar < this.length; nChar++)
		arChars[nChar] = this.charAt(nChar);
	return arChars;
}

function String_replaceAll(arSearch, arReplace)
{
	var strResult = this;
	for(var nItem = 0; nItem < arSearch.length; nItem++)
		strResult = strResult.replace(new RegExp(arSearch[nItem], "g"), arReplace[nItem]);
	return strResult;
}

function String_encodeHTMLQuotes()
{
	return this.replace(/"/g, "&quot;");
}

function String_htmlEncode()
{
	var strBaaadChars = "&\"<>\n\r";	// Must do & first
	var arReplacements = new Array("&amp;", "&quot;", "&lt;", "&gt;", "<BR>", "");
	return this.replaceAll( strBaaadChars.toCharArray(), arReplacements );
}

function htmlEncode(strInput) {
	if(strInput == null)
		return "";
	else if(typeof(strInput) == "string")
		return strInput.htmlEncode();
	else
		throw new Error("Trying to HTML encode a " + typeof(strInput) + " (" + strInput + ")");
}

// Remove all nasty characters from string
function String_makeID()
{
	var strID = this;
	var strEvils = " \t\n@!.,;";
	for(var nChar = 0; nChar < strEvils.length; nChar++)
		strID = strID.replace(new RegExp(strEvils.charAt(nChar), "g"), "");
	return strID;
}


//////////////////////////////////////////////////////////////////
// Register all the methods - call from early inline code
// Inline code is run before any <SCRIPT> immediate code
function registerStringMethods()
{
	String.prototype.isAll = String_isAll;
	String.prototype.isAny = String_isAny;
	String.prototype.isAllInList = String_isAllInList;
	String.prototype.isAnyInList = String_isAnyInList;
	String.prototype.isWhiteSpace = String_isWhiteSpace;
	String.prototype.isPunctuation = String_isPunctuation;
	String.prototype.trimWhiteSpace = String_trimWhiteSpace;
	String.prototype.compressWhiteSpace = String_compressWhiteSpace;
	String.prototype.isNumeric = String_isNumeric;
	String.prototype.isAlphaChar = String_isAlphaChar;
	String.prototype.isAlpha = String_isAlpha;
	String.prototype.toTitleCase = String_toTitleCase;
	String.prototype.toCharArray = String_toCharArray;
	String.prototype.replaceAll = String_replaceAll;
	String.prototype.encodeHTMLQuotes = String_encodeHTMLQuotes;
	String.prototype.htmlEncode = String_htmlEncode;
	String.prototype.makeID = String_makeID;
}

// For benefit of client-side code
registerStringMethods();
