/**
 * @fileoverview
 * Form convenience Functions
 *
 * @author &copy; Copyright Mike Brockington 2004 - 2006 All rights reserved.
 * @version 1.0
 * This version, Copyright: 05/07/2006 21:52
 */

/**
 * Extends the Number prototype to give formatted output.
 * @param String (Usually a) single character representing the currency in use.
 * @type Function
 * @returns String: Formatted number, pre-fixed with given symbol.
 */
Number.prototype.toCurrency = function(charCurrencySymbol)
{
    // To Do: add feature to insert commas for every three digits
    if(charCurrencySymbol)
    {
        // no problem?
    }else{
        charCurrencySymbol = "";   // ensures that this is not 'null' or 'undefined'
    }
    // UK, USA, etc:
    return charCurrencySymbol + this.toFixed(2).addSeperators();
}

/**
 * Extends the String prototype to give formatted output.
 * @param String (Usually a) single character representing the currency in use.
 * @type Function
 * @returns String: Formatted number, pre-fixed with given symbol.
 */
String.prototype.toCurrency = function(charCurrencySymbol)
{
    var fltValue = parseFloat(this);
    return fltValue.toCurrency(charCurrencySymbol);
}

/**
 * Extends the Number prototype to give formatted output.
 * Uses String.prototype.addSeperators() to carry out formatting.
 * @param String A single character to seperate each group of digits.
 * @type Function
 * @returns String: Formatted number.
 */
Number.prototype.addSeperators = function(charSeperator)
{
    if(charSeperator)
    {
        return this.toString().addSeperators(charSeperator);
    }else{
        return this.toString().addSeperators();
    }
}

/**
 * Extends the String prototype to give formatted output.
 * @param String A single character to seperate each group of digits.
 * @type Function
 * @returns String: Formatted number.
 */
String.prototype.addSeperators = function(charSeperator)
{
    if(charSeperator)
    {
        // no problem?
    }else{
        charSeperator = ",";   // ensures that this is not 'null' or 'undefined'
    }
    // UK, USA, etc:
    if(this.indexOf(".") < 4)
    {
        return this; // no need to add any seperators for such a small number
    }
    var numParts = null;
    if(this.indexOf(".") > -1)
    {
        numParts = this.split(".");
    }else{
        numParts = [this, ""];
    }
    return addSeperator(numParts[0], charSeperator) + "." + numParts[1];
}

/**
 * Used recursively to add numeric group seperators.
 * @param String Collection of digits.
 * @param String Character to use to seperate each group of digits.
 * @type Function
 * @returns String: Formatted number.
 */
function addSeperator(strInput, charSeperator)
{
    if(charSeperator)
    {
        // no problem?
    }else{
        charSeperator = ",";   // ensures that this is not 'null' or 'undefined'
    }
    if(strInput.length > 3)
    {
        var front = strInput.slice(0,-3);
        var back = strInput.slice(-3);
        if(front.length > 3)
        {
            return addSeperator(front, charSeperator) + charSeperator + back;
        }else{
            return front + charSeperator + back;
        }
    }else{
        return strInput;
    }
}

/**
 *
 * @type Function
 */
function isValidNumber(strFieldName)
{
    if((strFieldName == null) || (strFieldName == ""))
    {
        return false;
    }
    var thisInput = document.getElementById(strFieldName);
    if(thisInput)
    {
        if(thisInput.value)
        {
            if(isFinite(thisInput.value) )
            {
                return true;
            }
        }
    }
    return false;
}

/**
 *
 * @type Function
 */
function isItemChosen(strFieldName)
{
    if((strFieldName == null) || (strFieldName == ""))
    {
        return false;
    }
    var thisSelect = document.getElementById(strFieldName);
    if(thisSelect)
    {
        if(thisSelect.selectedIndex)
        {
            var optionValue = thisSelect.options[thisSelect.selectedIndex].value;
            if((optionValue == null) || (optionValue == "") || (optionValue == 0))
            {
                return false;
            }
            return true;
        }
    }
    return false;
}

/**
 *
 * @type Function
 */
function getMultiplier(strFieldName)
{
    if((strFieldName == null) || (strFieldName == ""))
    {
        return 1;  // effectively no multiplier
    }
    var thisSelect = document.getElementById(strFieldName);
    if(thisSelect)
    {
        return thisSelect.options[thisSelect.selectedIndex].value;
    }else{
        return 1;
    }
}



/**
 *
 * @type Function
 */
function getSelectValue(strFieldName)
{
    if((strFieldName == null) || (strFieldName == ""))
    {
        return 0; // not ideal, but we shouldn't have got this far anyway
    }
    var thisSelect = document.getElementById(strFieldName);
    if(thisSelect)
    {
        return thisSelect.options[thisSelect.selectedIndex].value;
    }else{
        return "";
    }
}

/**
 *
 * @type Function
 */
function getSelectText(strFieldName)
{
    if((strFieldName == null) || (strFieldName == ""))
    {
        return 0; // not ideal, but we shouldn't have got this far anyway
    }
    var thisSelect = document.getElementById(strFieldName);
    if(thisSelect)
    {
        return thisSelect.options[thisSelect.selectedIndex].text;
    }else{
        return "";
    }
}

/**
 *
 * @type Function
 */
function getValue(strFieldName)  // Where a Numeric value is required
{
    if((strFieldName == null) || (strFieldName == ""))
    {
        return 0; // not ideal, but we shouldn't have got this far anyway
    }
    var thisInput = document.getElementById(strFieldName);
    if(thisInput)
    {
        return thisInput.value;
    }else{
        return 0;
    }
}

/**
 *
 * @type Function
 */
function getRadioBoolean(strRadioItem) // strRadioItem = ID of element
{
    if((strRadioItem == null) || (strRadioItem == "") )
    {
        return this.no_such_value; // 'undefined' - makes this a three-state boolean
    }
    var thisButton = document.getElementById(strRadioItem);
    if(thisButton)
    {
        if(thisButton.checked)
        {
            return true;
        }else{
            return false;
        }
    }else{
        return this.no_such_value; // 'undefined' - makes this a three-state boolean
    }
}

/**
 *
 * @type Function
 */
function getSelectBoolean(strSelectName, strValueExpected)
{
    if((strSelectName == null) || (strValueExpected == null) || (strSelectName == "") || (strValueExpected == NaN))
    {
        return this.no_such_value; // 'undefined' - makes this a three-state boolean
    }
    var thisSelect = document.getElementById(strSelectName);
    if(thisSelect)
    {
        if(thisSelect.selectedIndex)
        {
            if(thisSelect.options[thisSelect.selectedIndex].text == strValueExpected)
            {
                return true;
            }else{
                return false;
            }
        }else{
            return this.no_such_value; // 'undefined' - makes this a three-state boolean
        }
    }else{
        return this.no_such_value; // 'undefined' - makes this a three-state boolean
    }
}


/**
 * Transform special characters into the corresponding HTML entity
 * @type Function
 * @Returns Escaped string
 */
String.prototype.escapeHTML = function()
{
    var strTemp = this;
        strTemp = strTemp.replace(/&/g, "&amp;");   // must come first in list
        strTemp = strTemp.replace(/£/g, "&pound;");
        strTemp = strTemp.replace(/¥/g, "&yen;");
        strTemp = strTemp.replace(/</g, "&lt;");
        strTemp = strTemp.replace(/\$/g, "&#36;");
        strTemp = strTemp.replace(/>/g, "&gt;");
        strTemp = strTemp.replace(/¢/g, "&cent;");
        strTemp = strTemp.replace(/¤/g, "&curren;");
        strTemp = strTemp.replace(/v/g, "&#8730;"); // square root
    return strTemp;
}


// Constructor:
function SpinWidget(paramObject)
{
    if(paramObject.fieldName)
    {
        this.name = paramObject.fieldName;
    }else{
        alert("Error 654: Could not create SpinWidget:"+ paramObject);
        return null;
    }
    if(paramObject.startValue && isFinite(paramObject.startValue) )
    {
        this.val = paramObject.startValue;
    }else{
        this.val = 0;
    }
    if(paramObject.width)
    {
        this.width = paramObject.width;
    }else{
        this.width = "83px";
    }
    if(paramObject.MAX_VALUE)
    {
        this.MAX_VALUE = paramObject.MAX_VALUE;
    }else{
        this.MAX_VALUE = 999;
    }
    if(paramObject.MIN_VALUE)
    {
        this.MIN_VALUE = paramObject.MIN_VALUE;
    }else{
        this.MIN_VALUE = -999;
    }
    if(paramObject.smallStep)
    {
        this.smallStep = paramObject.smallStep;
    }else{
        this.smallStep = 1;
    }
    if(paramObject.largeStep)
    {
        this.largeStep = paramObject.largeStep;
    }else{
        this.largeStep = 10;
    }
    if(paramObject.CSS_class)
    {
        this.CSS_class = paramObject.CSS_class;
    }else{
        this.CSS_class = "CR_SpinWidget";
    }
    this.draw();
}

SpinWidget.prototype.draw           = SW_draw;
SpinWidget.prototype.show           = SW_show;
SpinWidget.prototype.maximiseValue  = SW_maximiseValue;
SpinWidget.prototype.minimiseValue  = SW_minimiseValue;
SpinWidget.prototype.incrementField = SW_incrementField;
SpinWidget.prototype.decrementField = SW_decrementField;

function SW_maximiseValue()
{
    this.val = this.MAX_VALUE;
    this.show();
}

function SW_minimiseValue()
{
    this.val = this.MIN_VALUE;
    this.show();
}

function SW_incrementField(stepSize)
{
    if(!(stepSize)) { stepSize = 1; }
    var thisField = document.getElementById(this.name); // don't rely on the internal value - may have been changed by hand
    var thisValue = thisField.value;
    var nextValue = 1 * thisValue + stepSize;  // multiplication performs an implicit cast to numeric
    if( (nextValue) > this.MAX_VALUE )
    {
        this.val = this.MAX_VALUE;
    }else{
        this.val = nextValue;
    }
    this.show();
}

function SW_decrementField(stepSize)
{
    if(!(stepSize)) { stepSize = 1; }
    var thisField = document.getElementById(this.name);
    var thisValue = thisField.value;
    var nextValue = thisValue - stepSize;
    if( (nextValue) < this.MIN_VALUE )
    {
        this.val = this.MIN_VALUE;
    }else{
        this.val = nextValue;
    }
    this.show();
}

// Syncronise visible value with internal value
function SW_show()
{
  document.getElementById(this.name).value = this.val;
}

function SW_draw()
{
  document.write("<div class='" + this.CSS_class + "' id='div" + this.name + "' style='width:" + this.width + ";margin:0;'>");
  document.write("<input class='arrow' type='image' value='<' src='/gfx/widgets/spin/small/up.png'    onclick='SB.Widgets." + this.name + ".incrementField("+this.smallStep+");return false'>");
  document.write("<input class='arrow' type='image' value='<' src='/gfx/widgets/spin/small/upDbl.png' onclick='SB.Widgets." + this.name + ".incrementField("+this.largeStep+");return false'>");
  document.write("<input class='arrow' type='image' value='<' src='/gfx/widgets/spin/small/upMax.png' onclick='SB.Widgets." + this.name + ".maximiseValue();return false'>");
  document.write("<input class='intField' type='text' name='" + this.name + "' id='" + this.name + "' value='" + this.val + "'>");
  document.write("<input class='arrow' type='image' value='<' src='/gfx/widgets/spin/small/down.png'    onclick='SB.Widgets." + this.name + ".decrementField("+this.smallStep+");return false'>");
  document.write("<input class='arrow' type='image' value='<' src='/gfx/widgets/spin/small/dnDbl.png' onclick='SB.Widgets." + this.name + ".decrementField("+this.largeStep+");return false'>");
  document.write("<input class='arrow' type='image' value='<' src='/gfx/widgets/spin/small/dnMax.png' onclick='SB.Widgets." + this.name + ".minimiseValue();return false'>");
  document.write("</div>");
}


