/*
SaeSolved::sitewidgets.com(TM) JavaScript Class Library for  
Calculators -- Version 1.0, 20000124
Copyright (C) 2000 by SaeSolved::(TM), http://www.sitewidgets.com.

This Library provides a set of classes for use in building calculators.
It handles the basic input and output issues such as formatting and 
data validation. Calculator algorithms need to be incorporated in an 
instance of the method OperateOnValues() to create a specific calculator.
An example at the end of this library illustrates how this may be done.

This Library is open source software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
(http://www.gnu.org/copyleft/lesser.txt) as published by the Free
Software Foundation; either version 2.1 of the License, or (at your
option) any later version.

In particular you may copy and distribute verbatim copies of the
Library's complete source code as you receive it, in any medium,
provided that you conspicuously and appropriately publish on each 
copy an appropriate copyright notice and disclaimer of warranty; 
keep intact all the notices that refer to this License and to the 
absence of any warranty; and distribute a copy of this License along 
with the Library.

This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License (http://www.gnu.org/copyleft/lesser.txt)
for more details.

A copy of the GNU Lesser General Public License may be obtained from
the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307, USA.

It is requested, but not required, that you use the statement in the 
variable "this.License" in the function Calculator below in a 
document.write statement in such a way as to conspicuously and 
appropriately publish on each web page where the calculator is used 
the hyperlinked credits, copyright notice, and disclaimer of warranty
contained in the variable "this.License."

SaeSolved::(TM) may be contacted at 16 Beverly Road East, Tequesta, 
FL 33469-3108, USA; email: webmaster@saesolved.com.
*/

js_version = 1.1;

function Calculator(name, title, helpUsed){
    this.CalculatorName   = name;
    this.CalculatorTitle  = title;
    if (helpUsed == null){
        this.HelpUsed     = false;
    }else{
        this.HelpUsed     = helpUsed;
    }
    if (this.HelpUsed){
        this.TotalColumns = 3;
    }else{
        this.TotalColumns = 2;
    }
    this.License          = '' +
        '' +
        '' +
        '' +
        '' +
        '';
    this.FontFamily       = 'verdana,sans-serif';
    this.FontPoint        = '11 px';
    this.FontColor        = '#414141';
    this.TableFormat      = null;
   // this.TitleFormatBegin = null;
   // this.TitleFormatEnd   = null;
    this.RowFormat        = new Array();
    this.RowFormat[0]     = null;
    this.RowFormat[1]     = null;
    this.RowFormatEnd     = null;
    this.LicenseFormatted = null; 
    this.index            = 0;
    this.Element          = new Object();
    this.AddElement       = AddElement;
    this.Calculate        = Calculate;
    this.SetStyles        = SetStyles;
    this.ShowCalculator   = ShowCalculator;
    this.GetValues        = GetValues;
    this.PutValues        = PutValues;
}

function AddElement(obj){
    this[obj.name]             = obj;
    this.Element[this.index++] = obj;
}

function SetStyles(){
    // This uses defaults for each of the variables unless they have 
    // been given explicit values after an object is instantiated
    if(this.TableFormat == null) this.TableFormat = 
        '<table width="100%" border="0" ' +
        'cellspacing="0" cellpadding="4" align="center" ' +
        '>';
   // if(this.TitleFormatBegin == null) this.TitleFormatBegin = 
       // '<tr style="font-size: ' + this.FontPoint + 
       // ';  font-family: ' + this.FontFamily + '; color: ' + 
       // this.FontColor + '; font-style: normal; font-weight: ' +
       // 'normal;">' +
       // '<th colspan="' + this.TotalColumns + '">' +
       // '<font face="' + this.FontFamily + '" size="3">';
   // if(this.TitleFormatEnd == null) this.TitleFormatEnd = 
     //   '</font></td></tr>';
    if(this.RowFormat[0] == null) this.RowFormat[0] = 
        '<tr class="body">';
    if(this.RowFormat[1] == null) this.RowFormat[1] = 
        '<tr class="body">';
    if(this.RowFormatEnd == null) this.RowFormatEnd = '</tr>';
    if(this.LicenseFormatted == null) this.LicenseFormatted = 
        '<tr <span class="body"><td colspan="' + 
        this.TotalColumns + '"><font face="' + this.FontFamily + 
        '" size="1">' + this.License + '</font></td></tr>\n';
}

function Calculate(){
    var obj = self.document[this.CalculatorName];
    this.GetValues(obj);
    this.OperateOnValues();
    this.PutValues(obj);
}

function ShowCalculator(){
    this.SetStyles();
    document.write('<form name="' + this.CalculatorName + '" id="' +
        this.CalculatorName + '" target="_self" action="' +
        window.location + '" method="get">\n');
    document.write(this.TableFormat,'\n');
    //document.write(this.TitleFormatBegin,'\n',this.CalculatorTitle,
        //'\n', this.TitleFormatEnd,'\n');
    for (var i = 0; i < this.index; i++){
        document.write('   ' + this.RowFormat[i % 2] + '\n');
        this.Element[i].ShowElement(this.HelpUsed, this.TotalColumns);
        if (i == 0 && this.HelpUsed){
            document.write(
'       <td rowspan="' + (this.index - 1).toString() +
                '" align="left" valign="middle">\n',
'           <font face="' + this.FontFamily + '" size="1">\n',
'           \n',
'           </font>\n',
'       </td>\n');
        }
        document.write('   ' + this.RowFormatEnd + '\n');
    }
    document.write(this.LicenseFormatted, '</table>\n</form>');
}

function GetValues(obj){
    for (var i = 0; i < this.index; i++){
            if (this.Element[i].type == 'text')
                this.Element[i].value =
                    parseFloat(obj[this.Element[i].value_name].value);
    }
}

function PutValues(obj){
    for (var i = 0; i < this.index; i++){
            if (this.Element[i].type == 'text')
                obj[this.Element[i].value_name].value =
                    this.Element[i].ShowDecimals();
    }
}

function CalculatorElement(type, name, label){
    this.type              = type;
    this.name              = name;
    this.label             = label;
    this.value             = '';
    this.decimals          = null;
    this.size              = 5;
    this.help              = '';
    this.value_name        = name + '_value';
    this.help_name         = name + '_help';
    this.max_value         = null;
    this.min_value         = null;
    this.FontFamily        = 'verdana,sans-serif';
    this.FontSize          = '2';
    this.LabelFormatBegin  = null;
    this.LabelFormatEnd    = null;
    this.ValueFormatBegin  = null;
    this.ValueFormatEnd    = null;
    this.HelpFormatBegin   = null;
    this.HelpFormatEnd     = null;
    this.ButtonFormatBegin = null;
    this.ButtonFormatMid   = null;
    this.ButtonFormatEnd   = null; 
    this.SetFormats        = SetFormats;
    this.ShowElement       = ShowElement;
    this.ShowDecimals      = ShowDecimals;
    this.Validate          = Validate;
    this.HelpScreen        = HelpScreen;
}

function SetFormats(){
    // This uses defaults for each of the variables unless they have 
    // been given explicit values after an object is instantiated
    if(this.LabelFormatBegin == null) this.LabelFormatBegin = 
        '<td align="left" class="body">';
    if(this.LabelFormatEnd == null) this.LabelFormatEnd = 
        '</td>';
    if(this.ValueFormatBegin == null) this.ValueFormatBegin = 
        '<td nowrap class="body">';
    if(this.ValueFormatEnd == null) this.ValueFormatEnd = '';
    if(this.HelpFormatBegin == null) this.HelpFormatBegin = 
        ' <span class="body">';
    if(this.HelpFormatEnd == null) this.HelpFormatEnd = 
        '</span></td>';
    if(this.ButtonFormatBegin == null) this.ButtonFormatBegin = 
        '<td align="right"';
    if(this.ButtonFormatMid == null) this.ButtonFormatMid = 
        '><span class="body">';
    if(this.ButtonFormatEnd == null) this.ButtonFormatEnd = 
        '</span></td>';
		}

function ShowElement(withHelp, TotalColumns){
    this.SetFormats();
    if (this.type == 'text'){
        document.write(
'       ' + this.LabelFormatBegin + '\n',
'           ', this.label, '\n',
'       ' + this.LabelFormatEnd + '\n',
'       ' + this.ValueFormatBegin + '\n',
'           <input type="text' +
                '" name="'  + this.value_name +
                '" size="'  + this.size  +
                '" value="' + this.value +
                '" onChange="' + this.name + '.Validate(this.value);">',
            this.ValueFormatEnd,
            this.HelpFormatBegin);
        if (withHelp){
            if (this.help != null && this.help.length > 0){
                document.write('<input type="button' +
                    '" name="'     + this.help_name +
                    '" value=" ? ' +
                    '" onClick="' + this.name + '.HelpScreen();" class="qmark">\n');
            }else{
                document.write('&nbsp;\n');
            }
        }
        document.write(
'       ' + this.HelpFormatEnd + '\n');
    }else{
        document.write(
'       ' + this.ButtonFormatBegin);
        if (TotalColumns > 0){
            document.write(' colspan="', TotalColumns, '"');
        }
        document.write(this.ButtonFormatMid + '\n',
'           <div style="padding: 4px 15px 0px 0px;"><div style="border: 1px solid #5379A6;width:75px;"><input type="button' +
                '" name="'    + this.value_name  +
                '" value="'   + this.label +
                '" onClick="' + this.type +
                '" class="gobutton"></div></div>\n',
'       ' + this.ButtonFormatEnd + '\n');
    }
}

function HelpScreen(){
    alert(this.help);
    return true;
}

function ShowDecimals(){
    if (this.decimals == null
        || parseFloat(this.value).toString().length 
            < this.value.toString().length)
            return this.value;
    var factr = 1;
    for (var i = 0; i < this.decimals; i++){
        factr *= 10;
    }
	var outputStr = Math.round(factr * this.value).toString();
    while (outputStr.length - this.decimals < 1){
        outputStr = '0' + outputStr;
    }
    if (this.decimals == 0)
        return outputStr;
    var pos = outputStr.length - this.decimals;
	return outputStr.substring(0, pos) + '.' + 
                outputStr.substring(pos);
}

function Validate(val){
    if (parseFloat(val).toString().length 
            < val.toString().length){
       alert('You have entered an invalid value for ' + this.label);
        return false;
    }   
    if (this.max_value != null && val > this.max_value){
       alert('The value of ' + this.label 
            + ' must not be greater than ' + this.max_value + '.');
        return false;
    }   
    if (this.min_value != null && val < this.min_value){
       alert('The value of ' + this.label 
            + ' must not be less than ' + this.min_value + '.');
        return false;
    }   
    return true;
}

//  The following is a demo implementation of the above classes 
//  which can be uncommented and placed between script tags in an 
//  HTML page after including these classes.
/*
    var TextBoxSize    = 7;
    // New Calculator object
    var Demo           = new Calculator('DemoCalculator', 
                                        'Demo Calculator', true);
    // First element used in calculator
    var A              = new CalculatorElement('text', 'A', 'A');
    // Some properties of the first element
        A.size         = TextBoxSize;
        A.help         = 'Value for A.';
        A.max_value    = 110;
        A.min_value    = -1234;
    // Second element used in calculator
    var B              = new CalculatorElement('text', 'B', 'B');
    // Some properties of the second element
        B.size         = TextBoxSize;
        B.help         = 'Value for B.';
        B.min_value    = 0;
    // Third element used in calculator
    var C              = new CalculatorElement('text', 'C', 
                                                'C = A + B');
    // Some properties of the third element
        C.decimals     = 2;
        C.size         = TextBoxSize;
        C.help         = 'The demo calculation is simply for C ' +
                            '= A + B.';
    // The command element
    var CommandElement = new CalculatorElement('Demo.Calculate()', 
                                    'commandElement', 'Calculate');
    // Add the elements to the calculator
    Demo.AddElement(A);
    Demo.AddElement(B);
    Demo.AddElement(C);
    Demo.AddElement(CommandElement);
    // Define the operation(s) that will be done using the elements 
    function OperateOnValues(){
        this.C.value = this.A.value + this.B.value;
    }
    // Add this operation to the calculator
    Demo.OperateOnValues = OperateOnValues;
    // -->
    // Display the calculator
    Demo.ShowCalculator();
*/  
