// Calculator Functions

// Shape types
var SH_STANDARD = 0;        // Square/Rectangle/Irregular shapes (uses L/W)
var SH_CIRCLE = 1;
var SH_TRIANGLE = 2;
var SH_HEXAGON = 3;
var SH_OCTOGON = 4;

function calcObject()
{
    // Fields
    this.length = null;
    this.width = null;
    this.height = null;
    this.diameter = null;
    this.thickness = null;
    this.shape = null;

    // Fields that aren't used for everything
    this.tileSize = null;
    this.zones = new Array();
    this.price = null;
    this.lumberType = null;
    this.pitch = null;
    this.roofArea = null;

    // Helper Methods
    this.getArea        = calcObject_getArea;                                                   
    this.negateArea		= calcObject_negateArea; 	 // Some values are to be subtracted, not added. This is to handle those values
    this.roundHalf      = calcObject_roundHalf;     // Round a number to the nearest half
    this.toString       = calcObject_toString;      // Overload the default JavaScript toString() Method to give us some useful information
    this.getShapeName   = calcObject_getShapeName;  // Returns the name of the object shape type

    // Calculator Methods
    this.getCarpet      = calcObject_carpetCalc;
    this.getConcrete    = calcObject_concreteCalc;
    this.getCeramicTile = calcObject_ceramicTileCalc;
    this.getDrywall     = calcObject_drywallCalc;
    this.getLumber      = calcObject_lumberCalc;
    this.getPaint       = calcObject_paintCalc;
    this.getResTile     = calcObject_resiliantTileCalc;
    this.getRoof        = calcObject_roofCalc;
    this.getRArea       = calcObject_roofArea;
    this.getVinyl       = calcObject_vinylCalc;
    this.getWallpaper   = calcObject_wallpaperCalc;

    // Getters and Setter Methods
    this.getLength      = calcObject_getLength;
    this.setLength      = calcObject_setLength;
    this.getWidth       = calcObject_getWidth;
    this.setWidth       = calcObject_setWidth;
    this.getHeight      = calcObject_getHeight;
    this.setHeight      = calcObject_setHeight;
    this.getDiameter    = calcObject_getDiameter;
    this.setDiameter    = calcObject_setDiameter;
    this.getThickness   = calcObject_getThickness;
    this.setThickness   = calcObject_setThickness;
    this.getShape       = calcObject_getShape;
    this.setShape       = calcObject_setShape;
    this.setTileSize    = calcObject_setTileSize;
    this.getTileSize    = calcObject_getTileSize;
    this.getZones       = calcObject_getZones;
    this.setPrice       = calcObject_setPrice;
    this.getPrice       = calcObject_getPrice;
    this.setLumberType  = calcObject_setLumberType;
    this.getLumberType  = calcObject_getLumberType;
    this.setPitch       = calcObject_setPitch;
    this.getPitch       = calcObject_getPitch;
    this.getRoofArea    = calcObject_getRoofArea;
    this.setRoofArea    = calcObject_setRoofArea;
}

// Helper Methods
function calcObject_getArea()
{
    if (this.zones[0] != null)
    {
        var totalArea = 0;
        for (var idx = 0; idx < this.zones.length; idx ++)
        {
            totalArea += this.zones[idx];
        }
        return totalArea;
    }
    return this.getLength() * this.getWidth();
}  

function calcObject_negateArea(index)
{
	if (this.zones[index] != null || this.zones[index] > 0)
	{
		this.zones[index] -= (this.zones[index] * 2);
	}
	else 
	{
	 	alert("Calculator Exception: Cannot negate a null value or 0 value.");
	}
}

function calcObject_toString()
{
    var values = "";
    if (this.getLength() != null) values += "\nLength: " + this.getLength();
    if (this.getWidth() != null) values += "\nWidth: " + this.getWidth();
    if (this.getHeight() != null) values += "\nHeight: " + this.getHeight();
    if (this.getDiameter() != null) values += "\nDiameter: " + this.getDiameter();
    if (this.getThickness() != null) values += "\nThickness: " + this.getThickness();
    if (this.getShape() != null) values += "\nShape: " + this.getShapeName();
    if (this.tileSize != null) values += "\nTile Size: " + this.getTileSize() + "x" + this.getTileSize();
    if (this.zones.length > 0)
    {
        for (var idx = 0; idx < this.zones.length; idx ++)
        {
            values += "\nZone " + idx + " Area: " + this.zones[idx] + " sq. ft.";
        }
    }
    if (this.getLumberType() != null) values += "\nBoard Measurement: " + this.getLumberType();
    if (this.getPrice() != null) values += "\nLumber Price: " + this.getPrice();
    return values;
}

function calcObject_getShapeName()
{
    switch (this.shape)
    {
        case SH_STANDARD:
            return "Square/Rectangle/Irregular";
        case SH_CIRCLE:
            return "Circle";
        case SH_TRIANGLE:
            return "Triangle";
        case SH_HEXAGON:
            return "Hexagon";
        case SH_OCTOGON:
            return "Octogon";
        case null:
            return "No Shape";
        default:
            return "Invalid Shape Type";
    }
    return 0;
}

function calcObject_roundHalf(num)
{
    var ceiling = Math.ceil(num);
    var remainder = num % .5;
    if (remainder > 0) num = num - remainder + .5;
    return num;
}

// Carpet Calculator
function calcObject_carpetCalc ()
{
    if (this.zones[0] != null && this.zones[1] != null && this.zones[2] != null && this.zones[3] != null)
    {
        var totalArea = this.zones[0] + this.zones[1] + this.zones[2] + (this.zones[3] * .5);
        return Math.round((totalArea / 9));
    }
    else alert("Calculator Exception: All zones must be set\n\rZone 0: " + this.zones[0] + "\n\rZone 1: " + this.zones[1] + "\n\rZone 2: " + this.zones[2] + "\n\rZone 3: " + this.zones[3]);
    return 0;
}

// Ceramic Tile Calculator
function calcObject_ceramicTileCalc()
{
    if (this.getArea() != null && this.getTileSize() != null)
    {
        return Math.round(this.getArea() * 144 * 1.1 / Math.pow(this.getTileSize(),2));
    }
    else alert("Calculator Exception: Area and TileSize must be set");
    return 0;
}

// Concrete Calculator
function calcObject_concreteCalc ( )
{
    switch (this.getShape())
    {
        case SH_STANDARD:
            return this.roundHalf((this.getLength() * this.getWidth() * this.getThickness() / 12 / 27));
        case SH_CIRCLE:
            return this.roundHalf((this.getDiameter() * this.getThickness() * .5 * Math.PI / 12 / 27));
        case SH_TRIANGLE:
            return this.roundHalf((this.getLength() * this.getHeight() * this.getThickness()  / 2 / 12 / 27));
        case SH_HEXAGON:
            return this.roundHalf(((Math.pow(this.getDiameter(), 2)) * this.getThickness() * .866 / 12 / 27));
        case SH_OCTOGON:
            return this.roundHalf(((Math.pow(this.getDiameter(), 2)) * this.getThickness() * .828 / 12 / 27));
        default:
            alert("Calculator Exception: Improper shape type set in dimObject()");
            break;
    }
    return 0;
}

// Drywall Calculator
function calcObject_drywallCalc()
{
    if (this.zones[0] != null && this.zones[1] != null && this.zones[2] != null && this.zones[3] != null)
    {
        // Zone 1: wallArea, Zone 2: excludedArea, Zone 3: ceilingArea, Zone 4: addArea
        var totalArea = this.zones[0] + this.zones[1] + this.zones[2] + (this.zones[3] * .5);
        return this.roundHalf((totalArea * 1.1 /32));
    }
    else alert("Calculator Exception: All zones must be set\n\rZone 0: " + this.zones[0] + "\n\rZone 1: " + this.zones[1] + "\n\rZone 2: " + this.zones[2] + "\n\rZone 3: " + this.zones[3]);
    return 0;
}

// Lumber Calculator
function calcObject_lumberCalc()
{
    if (this.getLength() != 0 && this.getPrice() != 0)
    {
        return (this.getPrice() * this.getLength());
    }
    else alert("Calculator Exception: Price and Length must both be set.");
    return 0;
}

// Paint Calculator
function calcObject_paintCalc()
{
    if (this.zones[0] != null && this.zones[1] != null && this.zones[2] != null)
    {
        var wallArea = this.zones[0];
        var ceilingArea = this.zones[1];
        var slopeArea = this.zones[2];
        var totalArea = wallArea + ceilingArea + slopeArea;
        var totalPaint = totalArea * 1.1 / 400;
        return this.roundHalf(totalPaint);
    }
    else alert("Calculator Exception: All zones must be set\n\rZone 0: " + this.zones[0] + "\n\rZone 1: " + this.zones[1] + "\n\rZone 2: " + this.zones[2]);
    return 0;
}

// Resiliant Tile Calculator
function calcObject_resiliantTileCalc()
{
    if (this.zones[0] != null && this.zones[1] != null && this.zones[2] != null)
    {
        var totalArea = this.zones[0] + this.zones[1] + this.zones[2];
        var numTiles = Math.pow((totalArea / this.getTileSize()),2);
        return this.roundHalf(numTiles);
    }
    else alert("Calculator Exception: All zones must be set and Tilesize must be set\n\rZone 0: " + this.zones[0] + "\n\rZone 1: " + this.zones[1] + "\n\rZone 2: " + this.zones[2]);
    return 0;
}

// Roofing Calculator
function calcObject_roofCalc()
{
    if (this.getRoofArea() != null && this.getPitch != null)
    {
        return this.roundHalf((this.getRoofArea() * this.getPitch()) * 1.1 / 100);
    }
    else alert("Calculator Exception: Area, and Pitch must be set");
    return 0;
}

function calcObject_roofArea()
{
    if (this.getRoofArea() != null && this.getPitch != null)
    {
        return this.roundHalf((this.getRoofArea() * this.getPitch()));
    }
    else alert("Calculator Exception: Area, and Pitch must be set");
    return 0;
}

// Sheet Vinyl Calculator
function calcObject_vinylCalc()
{
    if (this.zones.length == 4)
    {
        return this.roundHalf(this.getArea() / 9);
    }
    else alert("Calculator Exception: All zones must be set\n\rZone 0: " + this.zones[0] + "\n\rZone 1: " + this.zones[1] + "\n\rZone 2: " + this.zones[2] + "\n\rZone 3: " + this.zones[3]);
    return 0;
}

// Wallpaper Calculator
function calcObject_wallpaperCalc()
{
    if (this.zones.length == 4)
    {
        return this.roundHalf(this.getArea() / 27);
    }
    else alert("Calculator Exception: All zones must be set\n\rZone 0: " + this.zones[0] + "\n\rZone 1: " + this.zones[1] + "\n\rZone 2: " + this.zones[2]);
    return 0;
}

// Getter and Setter Methods
function calcObject_getLength() { return this.length; }
function calcObject_getWidth() { return this.width; }
function calcObject_getHeight() { return this.height; }
function calcObject_getDiameter() { return this.diameter; }
function calcObject_getThickness() { return this.thickness; }
function calcObject_getShape() { return this.shape; }
function calcObject_getTileSize() { return this.tileSize; }
function calcObject_setLength( length ) { this.length = length; }
function calcObject_setWidth( width ) { this.width = width; }
function calcObject_setHeight( height ) { this.height = height; }
function calcObject_setDiameter( diameter ) { this.diameter = diameter; }
function calcObject_setThickness( thickness ) { this.thickness = thickness; }
function calcObject_setShape( shape ) { this.shape = shape; }
function calcObject_setTileSize( tileSize ) { this.tileSize = tileSize; }
function calcObject_getZones() { return this.zones; }
function calcObject_setPrice( price ) { this.price = price; }
function calcObject_getPrice() { return this.price; }
function calcObject_setLumberType( type ) { this.lumberType = type; }
function calcObject_getLumberType() { return this.lumberType; }
function calcObject_setPitch( pitch ) { this.pitch = pitch; }
function calcObject_getPitch() { return this.pitch; }
function calcObject_getRoofArea() { return this.roofArea; }
function calcObject_setRoofArea( area ) { this.roofArea = area; }