/**
 * @fileoverview
 * Specialised Object Functions
 * $Log: tongueAndGroove.js,v $
 * Revision 1.3  2006/03/01 23:23:45  mikeb
 * Minor Fixes
 *
 * Revision 1.2  2006/02/13 21:25:56  mikeb
 * First official release
 *
 * Revision 1.2  2006/01/26 22:58:00  mikeb
 * First commit
 *
 * @author &copy; Copyright Mike Brockington 2004 - 2006 All rights reserved.
 * @version $Revision: 1.3 $
 * This version, Copyright: $Date: 2006/03/01 23:23:45 $
 */


/**
 * Construct an object to handle calculations using discrete objects, rather than continuous numbers
 * @class
 * Concrete class - subclass of simpleCalculator(), with details of required fields and calculations added
 * @constructor
 * @return  Nothing
 */
function tongueAndGroove()
{
    /** @type Integer */
    this.numberOfCalcs = 0;

    /**  @type defaultDataObject   */
    this.arrCalculations = [new defaultDataObject()];

// Methods:
    this.doNewCalc          = doTongueAndGrooveCalc;
    this.showFormOutput     = showTongueAndGrooveOutput;
    this.displayPrintOutput = displayTG_PrintOutput;
}

/**
 * Construct an object to store calculations using discrete objects, rather than continuous numbers
 * @class
 * Concrete class - subclass of simpleDataObject(), with details of required fields and calculations added
 * @constructor
 * @return  Nothing
 */
function tongueAndGrooveData()
{
// Methods:
    this.getFormOutput = getTG_DataFormOutput;
    this.getHTMLOutput = getTG_HTMLOutput;

    /** @type String Array  */
    this.arrErrorMsg = new Array();

    /**Converted to SI units
     * @type Number
     */
   this.intLength = getValue("Length") * getMultiplier("Length");

    /**
     * Converted to SI units
     * @type Number
     */
    this.intWidth  = getValue("Width")  * getMultiplier("Width");

    /**
     * For display purposes
     * @type String
     */
    this.strLength = getValue("Length") + getDimension("Length");

    /**
     * For display purposes
     * @type String
     */
    this.strWidth  = getValue("Width")  + getDimension("Width");

    /**
     * Encoded array
     * @type String
     */
    this.strBoardSize = getOption("BoardSize");

    /**
     * For display purposes
     * @type String
     */
    this.charCurrencySymbol = getSelectValue("Currency");


    /**
     * For display purposes
     * @type String
     */
    this.strBoardDimensions = getSelectValue("BoardSize");
    var tempArray = this.strBoardDimensions.split("x");
    /** @type Number   */
    this.intBoardLength = tempArray[0];
    if(tempArray[1])
    {
        /** @type Number   */
        this.intBoardWidth = tempArray[1];
        this.arrErrorMsg.push("Board size okay.");
        // this.calcPossible = true;
    }else{
        // this.calcPossible = false;
        this.arrErrorMsg.push("Please choose a different board size.");
        this.intBoardWidth = Number.NaN;     // Need to put something in to keep the array elements in sync.
    }
    /**
     * False if 'board type' is 'tongueAndGroove'
     * @type Boolean
     */
    this.boolReuseHalfBoards = getRadioBoolean("radioPlain");

    /**
     * Possible float
     * @type Number
     */
    this.intBoardsAcross   = this.intWidth / this.intBoardLength;

    /**
     * Possible float
     * @type Number
     */
    this.intBoardsAlong    = this.intLength / this.intBoardWidth;

    /**
     * Possible float
     * @type Number
     */
    this.intTotalBoards    = calcTotalBoards(this.intBoardsAcross, this.intBoardsAlong, this.boolReuseHalfBoards);

    /**
     * Possible float
     * @type Number
     */
    this.intAdjustedTotal  = Math.ceil(this.intTotalBoards * 1.1);  // add 10% and round up

    /**
     * True if pack price is greater than price of individual items
     * @type Boolean
     */
    this.boolIgnorePackPrice  = getSelectBoolean("slctPackSize", "None");

    /**  @type packPriceObject   */
    this.objPackPriceObject = null;
    if(this.boolIgnorePackPrice)
    {
        // this.objPackPriceObject = new Object();
    }else{
        this.objPackPriceObject = new packPriceObject(this.intAdjustedTotal, getValue("UnitPrice"), getSelectValue("PackSize"), getValue("PackPrice"));
    }
    // if(thisCalculator.calcPossible)
    if(true)
    {
    }else{
        alert(thisCalculator.arrErrorMsg);
    }

}

   /**
    * @param {float} fltBoardsAcross The number of boards that fits across the given area
    * @param {float} fltBoardsAlong The number of boards that fits along the given area
    * @param {boolean} boolReuseHalfBoards  Can boards be split lengthwise (if space permits)?
    * @returns {Number} totalBoards (possible float)
    */
function calcTotalBoards(fltBoardsAcross, fltBoardsAlong, boolReuseHalfBoards)
{
    var intBoardsAlong = 0;
    if(boolReuseHalfBoards)
    {
        intBoardsAlong = (Math.ceil(fltBoardsAlong * 2) /2);  // round up to nearest half board
    }else{
        intBoardsAlong = Math.ceil(fltBoardsAlong);
    }
    var totalBoards = intBoardsAlong * fltBoardsAcross;
    return totalBoards;
}


// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
// Methods:
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
   /**
    * Carry out the base calculation.
    * @type Function
    * @returns Nothing
    */
function doTongueAndGrooveCalc()
{
    // alert("tongueAndGroove.js:doTongueAndGrooveCalc()");
    this.numberOfCalcs++;
    this.arrCalculations.push(new tongueAndGrooveData() );
}


   /**
    * Populate the on-page text area.
    * @type Function
    * @returns Nothing
    */
function showTongueAndGrooveOutput()
{
    // alert("tongueAndGroove.js:showTongueAndGrooveOutput()");
    var outArea = document.getElementById("txtOutput");
    if(this.numberOfCalcs > 1)
    {
        outArea.value = "Results for "+this.numberOfCalcs+" calculations: \n";
    }else{
        outArea.value = "Results for this calculation: \n";
    }
    for(i=1; i <= this.numberOfCalcs; i++)  // The object at index 0 is a default placeholder, not to be used in this context.
    {
        outArea.value += this.arrCalculations[i].getFormOutput(i);
    }
    if(this.numberOfCalcs > 1)
    {
        if(this.allCurrenciesMatch() )
        {
            outArea.value += "Grand Total: ";
            var temp = this.getGrandTotal() - 0;
            outArea.value += temp.toCurrency(this.arrCalculations[1].charCurrencySymbol);
        }else{
            outArea.value += "(Unable to calculate 'Grand Total', as differing currencies have been used.)";
        }
    }
}


/**
* Populate the HTML pop-up results window .
* @type Function
* @returns Nothing
*/
function displayTG_PrintOutput()
{
    // alert("tongueAndGroove.js:displayTG_PrintOutput()");
    var outHTML = "";
    if(this.numberOfCalcs > 1)
    {
        outHTML = "<H2>Results for "+this.numberOfCalcs+" calculations</H2>";
    }else{
        outHTML = "<H2>Results for this calculation</H2>";
    }
    for(i=1; i <= this.numberOfCalcs; i++)  // The object at index 0 is a default placeholder, not to be used in this context.
    {
        outHTML += this.arrCalculations[i].getHTMLOutput(i);
    }
    if(this.numberOfCalcs > 1)
    {
        if(this.allCurrenciesMatch() )
        {
            outHTML += "<H3>Grand Total:";
            var temp = this.getGrandTotal() - 0;
            outHTML += temp.toCurrency(this.arrCalculations[1].charCurrencySymbol.escapeHTML() ) + "</H3>";
        }else{
            outHTML += "<H3>(Unable to calculate 'Grand Total', as differing currencies have been used.)</H3>";
        }
    }
    displayPrintOutputArea(outHTML)
}


/**
* Create content for the HTML pop-up results window.
* @type Function
* @returns Nothing
*/
function getTG_HTMLOutput(intCalcNumber)
{
    var returnHTML  = "<div class='outputSection'>";
    returnHTML +=   "<H3>Calculation " + intCalcNumber + "</H3>\n";
    returnHTML +=   "<div>Area to be covered: " + this.intLength.toPrecision(4) + "metres by " + this.intWidth.toPrecision(4) + "metres </div>\n";
    returnHTML +=   "<div>For a Board size of " + this.strBoardSize + ",\n    ";
    returnHTML +=   this.intBoardsAcross.toPrecision(4) + " boards will fit Across, and ";
    returnHTML +=   this.intBoardsAlong.toPrecision(4)  + " boards will fit Along. </div>\n    ";
    returnHTML +=   "<div>The minimum number of Boards required is: " + this.intTotalBoards.toFixed(1) + "</div>\n";
    returnHTML +=   "<hr>\n";
    returnHTML +=   "<div>" + this.intAdjustedTotal + " boards will be required, allowing for 10% wasteage. </div>\n";
    returnHTML +=   "<div>Cost for area " + intCalcNumber + ": " + this.objPackPriceObject.bestPrice.toCurrency(this.charCurrencySymbol).escapeHTML() + " for:</div>\n";
    returnHTML +=   "<div>" + this.objPackPriceObject.packsRequired + " packs, (" + this.objPackPriceObject.finalPackCost.toCurrency(this.charCurrencySymbol).escapeHTML()   + ") plus ";
    returnHTML +=   this.objPackPriceObject.unitsRequired + " single boards (" + this.objPackPriceObject.boardCost.toCurrency(this.charCurrencySymbol).escapeHTML() + "). </div>\n";
    returnHTML +=   "</div>\n";
  return returnHTML;
}


/**
 * Get data summary formatted as plain text.
 * @param Integer Current calculation number.
 * @type Function
 * @returns String: Formatted plain text.
 */
function getTG_DataFormOutput(intCalcNumber)
{
    // alert("tongueAndGroove.js:getTG_DataFormOutput()");
    var returnText  = "    ";
    returnText +=   "Area to be covered: " + this.intLength.toPrecision(4) + "metres by " + this.intWidth.toPrecision(4) + "metres \n    ";
    returnText +=   "For a Board size of " + this.strBoardSize + ",\n    ";
    returnText +=   this.intBoardsAcross.toPrecision(4) + " boards will fit Across, and ";
    returnText +=   this.intBoardsAlong.toPrecision(4)  + " boards will fit Along. \n    ";
    returnText +=   "The minimum number of Boards required is: " + this.intTotalBoards.toFixed(1) + "\n";
    returnText +=   "- - - - - - - - - - - - - - - - - - - - - - - - - - -\n";
    returnText +=   this.intAdjustedTotal + " boards will be required, allowing for 10% wasteage. \n";
    returnText +=   "Cost for area " + intCalcNumber + ": " + this.objPackPriceObject.bestPrice.toCurrency(this.charCurrencySymbol) + " for:\n";
    returnText +=   "   " + this.objPackPriceObject.packsRequired + " packs, (" + this.objPackPriceObject.finalPackCost.toCurrency(this.charCurrencySymbol)   + ") plus ";
    returnText +=   this.objPackPriceObject.unitsRequired + " single boards (" + this.objPackPriceObject.boardCost.toCurrency(this.charCurrencySymbol) + ") \n";
    returnText +=   "- - - - - - - - - - - - - - - - - - - - - - - - - - -\n\n";
  return returnText;
}




// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
/**
 * Calculate sum of costs of individual calculations
 * @type Function
 * @returns Float
 */
tongueAndGroove.prototype.getGrandTotal = function()
{
    // alert("tongueAndGroove.js:getGrandTotal()");
    var numberGrandTotal = 0;
    for(i=1; i <= this.numberOfCalcs; i++)  // The object at index 0 is a default, not to be used.
    {
        numberGrandTotal += this.arrCalculations[i].objPackPriceObject.bestPrice;
    }
    return numberGrandTotal;
}

/**
 * Check whether all calculations use the same currency - can't add them up otherwise.
 * @type Function
 * @returns Boolean
 */
tongueAndGroove.prototype.allCurrenciesMatch = function()
{
    // alert("tongueAndGroove.js:getGrandTotal()");
    if(this.numberOfCalcs < 2)
    {
        return true;
    }
    var firstCurrencySymbol = this.arrCalculations[1].charCurrencySymbol;
    var boolSymbolsMatch = true;
    for(i=2; i <= this.numberOfCalcs; i++)  // The object at index 0 is a default, not to be used.
    {
        boolSymbolsMatch = ( firstCurrencySymbol == this.arrCalculations[i].charCurrencySymbol );
    }
    return boolSymbolsMatch;
}




