// Deck Cost Calculator
// (c) Mike Gempe, mike-at-gempe.com
// Please retain Original author credits with any modifications

/* Turnkey Cost Factor */
var turnkey_cost_factor = 0.75;
var permit_amount = 400.00;

/* stair calculations */
var calc_stair_width = 4.0;
var calc_stair_height = 7.5;
var calc_stair_landing_area = (calc_stair_width * calc_stair_width);

/* Pressure Treated Values */
var pt_deck_labor_to_frame = 6.75;
var pt_deck_labor_to_build = 10.00;
var pt_deck_material_cost = 8.00;
var pt_deck_labor_to_frame_total = pt_deck_labor_to_frame + pt_deck_material_cost;
var pt_deck_labor_to_build_total = pt_deck_labor_to_build + pt_deck_material_cost;

var pt_stairs_labor_to_frame = 9.00;
var pt_stairs_labor_to_build = 13.00;
var pt_stairs_material_cost = 10.00;
var pt_stairs_labor_to_frame_total = pt_stairs_labor_to_frame + pt_stairs_material_cost;
var pt_stairs_labor_to_build_total = pt_stairs_labor_to_build + pt_stairs_material_cost;

/* Composite Values */
var cmp_deck_labor_to_frame = 7.70;
var cmp_deck_labor_to_build = 11.00;
var cmp_deck_material_cost = 14.55;
var cmp_deck_labor_to_frame_total = cmp_deck_labor_to_frame + cmp_deck_material_cost;
var cmp_deck_labor_to_build_total = cmp_deck_labor_to_build + cmp_deck_material_cost;

var cmp_stairs_labor_to_frame = 9.80;
var cmp_stairs_labor_to_build = 14.00;
var cmp_stairs_material_cost = 18.00;
var cmp_stairs_labor_to_frame_total = cmp_stairs_labor_to_frame + cmp_stairs_material_cost;
var cmp_stairs_labor_to_build_total = cmp_stairs_labor_to_build + cmp_stairs_material_cost;

/* Ipe Values */
var ipe_deck_labor_to_frame = 6.75;
var ipe_deck_labor_to_build = 14.00;
var ipe_deck_material_cost = 14.00;
var ipe_deck_labor_to_frame_total = ipe_deck_labor_to_frame + ipe_deck_material_cost;
var ipe_deck_labor_to_build_total = ipe_deck_labor_to_build + ipe_deck_material_cost;

var ipe_stairs_labor_to_frame = 9.00;
var ipe_stairs_labor_to_build = 17.00;
var ipe_stairs_material_cost = 17.00;
var ipe_stairs_labor_to_frame_total = ipe_stairs_labor_to_frame + ipe_stairs_material_cost;
var ipe_stairs_labor_to_build_total = ipe_stairs_labor_to_build + ipe_stairs_material_cost;

/* Fiber Rail Values */
var fibre_labor_to_frame = 0.00;
var fibre_labor_to_build = 16.00;
var fibre_material_cost = 27.57;
var fibre_labor_to_frame_total = fibre_labor_to_frame + fibre_material_cost;
var fibre_labor_to_build_total = fibre_labor_to_build + fibre_material_cost;

// return string as $ per SF (square foot)
function getSFString(total) {
 var s = valToMoney(total) + "/SF"
 return s;
}

function getHeightString(total) {
 var s = valToMoney(total) + "/SF"
 return s;
}

// area = area of deck (SF)
// height = height of deck in inches
function calculateDeckCost(area, height, numLandings)
{
 if (height > 0) {
  if (numLandings > 0) {
   setCellText( "dc_l2f", "Deck Cost, Labor to Frame (area " + area +" sq ft, stairs " + height + " inches, Landings " + numLandings + ")" );
   setCellText( "dc_l2b", "Deck Cost, Labor to Build (area " + area +" sq ft, stairs " + height + " inches, Landings " + numLandings + ")" );
  } else {
   setCellText( "dc_l2f", "Deck Cost, Labor to Frame (area " + area +" sq ft, stairs " + height + " inches)" );
   setCellText( "dc_l2b", "Deck Cost, Labor to Build (area " + area +" sq ft, stairs " + height + " inches)" );
  }
 } else {
  if (numLandings > 0) {
   setCellText( "dc_l2f", "Deck Cost, Labor to Frame (area " + area +" sq ft, Landings " + numLandings + ")" );
   setCellText( "dc_l2b", "Deck Cost, Labor to Build (area " + area +" sq ft, Landings " + numLandings + ")" );
  } else {
   setCellText( "dc_l2f", "Deck Cost, Labor to Frame (area " + area +" sq ft)" );
   setCellText( "dc_l2b", "Deck Cost, Labor to Build (area " + area +" sq ft)" );
  }
 }

 displaySFTotals( "pt1_l2f", "pt2_l2f", "pt3_l2f", area, height, numLandings, pt_deck_labor_to_frame, pt_stairs_labor_to_frame );
 displaySFTotals( "pt1_l2f_material_cost", "pt2_l2f_material_cost", "pt3_l2f_material_cost", 
                  area, height, numLandings, pt_deck_material_cost, pt_stairs_material_cost );
 displaySFTotals( "pt1_l2f_total", "pt2_l2f_total", "pt3_l2f_total", 
                  area, height, numLandings, pt_deck_labor_to_frame_total, pt_stairs_labor_to_frame_total );
 displayTurnkeyTotals( "pt1_l2f_turnkey", "pt2_l2f_turnkey", "pt3_l2f_turnkey",
                        area, height, numLandings, pt_deck_labor_to_build_total, pt_stairs_labor_to_build_total );
 displaySavingsTotals( "pt1_l2f_savings", "pt2_l2f_savings", "pt3_l2f_savings", area, height, numLandings,  
                        pt_deck_labor_to_frame_total, pt_stairs_labor_to_frame_total,
                        pt_deck_labor_to_build_total, pt_stairs_labor_to_build_total );

 displaySFTotals( "cmp1_l2f", "cmp2_l2f", "cmp3_l2f", area, height, numLandings, cmp_deck_labor_to_frame, cmp_stairs_labor_to_frame );
 displaySFTotals( "cmp1_l2f_material_cost", "cmp2_l2f_material_cost", "cmp3_l2f_material_cost", 
                  area, height, numLandings, cmp_deck_material_cost, cmp_stairs_material_cost );
 displaySFTotals( "cmp1_l2f_total", "cmp2_l2f_total", "cmp3_l2f_total", 
                  area, height, numLandings, cmp_deck_labor_to_frame_total, cmp_stairs_labor_to_frame_total );
 displayTurnkeyTotals( "cmp1_l2f_turnkey", "cmp2_l2f_turnkey", "cmp3_l2f_turnkey",
                        area, height, numLandings, cmp_deck_labor_to_build_total, cmp_stairs_labor_to_build_total );
 displaySavingsTotals( "cmp1_l2f_savings", "cmp2_l2f_savings", "cmp3_l2f_savings", area, height, numLandings, 
                        cmp_deck_labor_to_frame_total, cmp_stairs_labor_to_frame_total,
                        cmp_deck_labor_to_build_total, cmp_stairs_labor_to_build_total );


 displaySFTotals( "ipe1_l2f", "ipe2_l2f", "ipe3_l2f", area, height, numLandings, ipe_deck_labor_to_frame, ipe_stairs_labor_to_frame );
 displaySFTotals( "ipe1_l2f_material_cost", "ipe2_l2f_material_cost", "ipe3_l2f_material_cost", 
                  area, height, numLandings, ipe_deck_material_cost, ipe_stairs_material_cost );
 displaySFTotals( "ipe1_l2f_total", "ipe2_l2f_total", "ipe3_l2f_total", 
                  area, height, numLandings, ipe_deck_labor_to_frame_total, ipe_stairs_labor_to_frame_total );
 displayTurnkeyTotals( "ipe1_l2f_turnkey", "ipe2_l2f_turnkey", "ipe3_l2f_turnkey",
                        area, height, numLandings, ipe_deck_labor_to_build_total, ipe_stairs_labor_to_build_total );
 displaySavingsTotals( "ipe1_l2f_savings", "ipe2_l2f_savings", "ipe3_l2f_savings", area, height, numLandings,  
                        ipe_deck_labor_to_frame_total, ipe_stairs_labor_to_frame_total,
                        ipe_deck_labor_to_build_total, ipe_stairs_labor_to_build_total );

 displaySFTotals( "pt1_l2b", "pt2_l2b", "pt3_l2b", area, height, numLandings, pt_deck_labor_to_build, pt_stairs_labor_to_build );
 displaySFTotals( "pt1_l2b_material_cost", "pt2_l2b_material_cost", "pt3_l2b_material_cost", 
                  area, height, numLandings, pt_deck_material_cost, pt_stairs_material_cost );
 displaySFTotals( "pt1_l2b_total", "pt2_l2b_total", "pt3_l2b_total", 
                  area, height, numLandings, pt_deck_labor_to_build_total, pt_stairs_labor_to_build_total );
 displayTurnkeyTotals( "pt1_l2b_turnkey", "pt2_l2b_turnkey", "pt3_l2b_turnkey",
                        area, height, numLandings, pt_deck_labor_to_build_total, pt_stairs_labor_to_build_total );
 displaySavingsTotals( "pt1_l2b_savings", "pt2_l2b_savings", "pt3_l2b_savings", area, height, numLandings,  
                        pt_deck_labor_to_build_total, pt_stairs_labor_to_build_total,
                        pt_deck_labor_to_build_total, pt_stairs_labor_to_build_total );

 displaySFTotals( "cmp1_l2b", "cmp2_l2b", "cmp3_l2b", area, height, numLandings, cmp_deck_labor_to_build, cmp_stairs_labor_to_build );
 displaySFTotals( "cmp1_l2b_material_cost", "cmp2_l2b_material_cost", "cmp3_l2b_material_cost", 
                  area, height, numLandings, cmp_deck_material_cost, cmp_stairs_material_cost );
 displaySFTotals( "cmp1_l2b_total", "cmp2_l2b_total", "cmp3_l2b_total", 
                  area, height, numLandings, cmp_deck_labor_to_build_total, cmp_stairs_labor_to_build_total );
 displayTurnkeyTotals( "cmp1_l2b_turnkey", "cmp2_l2b_turnkey", "cmp3_l2b_turnkey",
                        area, height, numLandings, cmp_deck_labor_to_build_total, cmp_stairs_labor_to_build_total );
 displaySavingsTotals( "cmp1_l2b_savings", "cmp2_l2b_savings", "cmp3_l2b_savings", area, height, numLandings,  
                        cmp_deck_labor_to_build_total, cmp_stairs_labor_to_build_total,
                        cmp_deck_labor_to_build_total, cmp_stairs_labor_to_build_total );

 displaySFTotals( "ipe1_l2b", "ipe2_l2b", "ipe3_l2b", area, height, numLandings, ipe_deck_labor_to_build, ipe_stairs_labor_to_build );
 displaySFTotals( "ipe1_l2b_material_cost", "ipe2_l2b_material_cost", "ipe3_l2b_material_cost", 
                  area, height, numLandings, ipe_deck_material_cost, ipe_stairs_material_cost );
 displaySFTotals( "ipe1_l2b_total", "ipe2_l2b_total", "ipe3_l2b_total", 
                  area, height, numLandings, ipe_deck_labor_to_build_total, ipe_stairs_labor_to_build_total );
 displayTurnkeyTotals( "ipe1_l2b_turnkey", "ipe2_l2b_turnkey", "ipe3_l2b_turnkey",
                        area, height, numLandings, ipe_deck_labor_to_build_total, ipe_stairs_labor_to_build_total );
 displaySavingsTotals( "ipe1_l2b_savings", "ipe2_l2b_savings", "ipe3_l2b_savings", area, height, numLandings, 
                        ipe_deck_labor_to_build_total, ipe_stairs_labor_to_build_total,
                        ipe_deck_labor_to_build_total, ipe_stairs_labor_to_build_total );

 displayFibreRail();
}

// convert float to money string, if bTrunc then don't display decimals
function valToMoney( dValue, bTrunc ) {
 var sValue = "$" + dValue;
 var sMoney = "";
 var bDecimal = false;
 var iCount = 0;

 if (bTrunc == null) bTrunc = false;

 for (i = 0; i < sValue.length; i++)
 {   
  if (sValue.charAt(i) == '.') {
   if( bTrunc ) break;
   bDecimal = true;
  } else if (bDecimal) {
   iCount++;
  }
  sMoney = sMoney + sValue.charAt(i);
  if (iCount == 2) break;
 }

 if (bTrunc == false) {
  if (bDecimal) {
   if (iCount == 0) {
    sMoney = sMoney + "00";
   } else if (iCount == 1) {
    sMoney = sMoney + "0";
   }
  } else {
   sMoney = sMoney + ".00";
  }
 }

 return sMoney;
}

//
// total is the square foot cost 
// height is in inches
function calcStairCost(total, height, numLandings)
{
 var num_stairs;
 var stair_cost;

 num_stairs = Math.round((height/calc_stair_height)-0.5); // subtract .5 so the value is truncated
 stair_cost = ( (calc_stair_width * num_stairs) + (calc_stair_landing_area * numLandings) ) * total;

 return stair_cost;
}

// total is the square foot cost 
// area is SF of deck
// if bAddPermit, add in cost of permit to total
function calcTurnkey( total, area, bAddPermit ) {
 var turnkey = (total / turnkey_cost_factor) * area;
 if (bAddPermit) turnkey = turnkey + permit_amount;
 return turnkey;
}

// total is the SF cost 
// height is INCHES
function calcTurnkeyStairs( total, height, numLandings ) {
 var turnkey = calcStairCost(total / turnkey_cost_factor, height, numLandings)
 return turnkey;
}

// set the text of specified cell
function setCellText(sElem, sValue) {
 var cell = new getObj(sElem);
 cell.obj.innerHTML = sValue;
}

function displaySFTotals( deckElem, stairElem, totalElem, area, height, numLandings, deck_labor, stairs_labor ) {
 var deck_cost = area * deck_labor;
 var stair_cost = calcStairCost(stairs_labor, height, numLandings); /* height * stairs_labor; */
 var sDeck = "<div class='dc_calc'>[" + getSFString(deck_labor) + "]</div>";
 var sStair = "<div class='dc_calc'>[" + getHeightString(stairs_labor) + "]</div>";
 var sTotal = "";

 if( area > 0 ) {
  sDeck = "<div class='dc_total'>" + valToMoney(deck_cost, true) + "<br/>" + sDeck + "</div>" ;
 } else {
  sDeck = "<div class='dc_total'>" + "N/A" + "<br/>" + sDeck + "</div>" ;
 }
 if( height > 0 ) {
  sStair = "<div class='dc_total'>" + valToMoney(stair_cost, true) + "<br/>" + sStair + "</div>";
 } else {
  sStair = "<div class='dc_total'>" + "N/A" + "<br/>" + sStair + "</div>" ;
 }

 if( (deck_cost + stair_cost) > 0 ) {
  sTotal = "<div class='dc_total'>" + valToMoney(deck_cost + stair_cost, true) + "</div>";
 } else {
  sTotal = "<div class='dc_total'>" + "N/A" + "</div>";
 }

 setCellText(deckElem, sDeck);
 setCellText(stairElem, sStair);
 setCellText(totalElem, sTotal);
}

function displayTurnkeyTotals( deckElem, stairElem, totalElem, area, height, numLandings, deck_labor, stairs_labor ) {
 var deck_cost = calcTurnkey( deck_labor, area, true );
 var stair_cost = calcTurnkeyStairs(stairs_labor, height, numLandings);
 var sDeck = "<div class='dc_calc'>[" + getSFString(deck_labor / turnkey_cost_factor) + " + " + valToMoney(permit_amount, true) + "]</div>";
 var sStair = "<div class='dc_calc'>[" + getHeightString(stairs_labor / turnkey_cost_factor) + "]</div>";
 var sTotal = "N/A";

 if( area > 0 ) {
  sDeck = "<div class='dc_total'>" + valToMoney(deck_cost, true) + "<br/>" + sDeck + "</div>";
 } else {
  sDeck = "<div class='dc_total'>" + "N/A" + "<br/>" + sDeck + "</div>";
 }
 if( height > 0 ) {
  sStair = "<div class='dc_total'>" + valToMoney(stair_cost, true) + "<br/>" + sStair + "</div>";
 } else {
  sStair = "<div class='dc_total'>" + "N/A" + "<br/>" + sStair + "</div>";
 }

 if( (deck_cost + stair_cost) > 0 ) {
  sTotal = "<div class='dc_total'>" + valToMoney(deck_cost + stair_cost, true) + "</div>";
 } else {
  sTotal = "<div class='dc_total'>" + "N/A" + "</div>";
 }

 setCellText(deckElem, sDeck);
 setCellText(stairElem, sStair);
 setCellText(totalElem, sTotal);
}

function displaySavingsTotals( deckElem, stairElem, totalElem, area, height, numLandings, deck_l2f, stairs_l2f, deck_l2b, stairs_l2b ) {
 var deck_savings = calcTurnkey( deck_l2b, area, true ) - (area * deck_l2f);
 var stair_savings = calcTurnkeyStairs( stairs_l2b, height, numLandings ) - calcStairCost(stairs_l2f, height, numLandings);
 var sDeck = "N/A";
 var sStair = "N/A";
 var sTotal = "N/A";

 if( area > 0 ) {
  sDeck = "<div class='dc_total'>" + valToMoney(deck_savings, true) + "</div>";
 } else {
  sDeck = "<div class='dc_total'>" + "N/A" + "</div>";
 }
 if( height > 0 ) {
  sStair = "<div class='dc_total'>" + valToMoney(stair_savings, true) + "</div>";
 } else {
  sStair = "<div class='dc_total'>" + "N/A" + "</div>";
 }

 if( (deck_savings + stair_savings) > 0 ) {
  sTotal = "<div class='dc_total'>" + valToMoney(deck_savings + stair_savings, true) + "</div>";
 } else {
  sTotal = "<div class='dc_total'>" + "N/A" + "</div>";
 }

 setCellText(deckElem, sDeck);
 setCellText(stairElem, sStair);
 setCellText(totalElem, sTotal);
}

function displayFibreRail()
{
 var turnkey = calcTurnkey( fibre_labor_to_build_total, 1, false );

 setCellText("fbr1_l2f", "N/A");
 setCellText("fbr1_l2f_material_cost", valToMoney(fibre_material_cost) + "/LF");
 setCellText("fbr1_l2f_total", valToMoney(fibre_labor_to_frame_total) + "/LF");
 setCellText("fbr1_l2f_turnkey", valToMoney(turnkey) + "/LF" );
 setCellText("fbr1_l2f_savings", valToMoney(turnkey-fibre_labor_to_frame_total) + "/LF" );

 setCellText("fbr1_l2b", valToMoney(fibre_labor_to_build) + "/LF");
 setCellText("fbr1_l2b_material_cost", valToMoney(fibre_material_cost) + "/LF");
 setCellText("fbr1_l2b_total", valToMoney(fibre_labor_to_build_total) + "/LF");
 setCellText("fbr1_l2b_turnkey", valToMoney(turnkey) + "/LF" );
 setCellText("fbr1_l2b_savings", valToMoney(turnkey-fibre_labor_to_build_total) + "/LF" );

}

function getObj(name) {
 if (document.getElementById) {
  this.obj = document.getElementById(name);
  this.style = document.getElementById(name).style;
 } else if (document.all) {
  this.obj = document.all[name];
  this.style = document.all[name].style;
 } else if (document.layers) {
  this.obj = document.layers[name];
  this.style = document.layers[name];
 }
}

function supportsDHTML() {
 var isDHTMLEnabled = false;
 if (document.getElementById || document.all || document.layers) {
  isDHTMLEnabled = true;
 }
 return isDHTMLEnabled;
}

function getValidInteger( elemID ) {
 var field = new getObj(elemID);
 var sNum = field.obj.value;

 sNum = stripCharsNotInBag(sNum, "0123456789");
 if( isEmpty(sNum) ) {
  sNum = "0";
 }

 field.obj.value = sNum;

 return( eval(sNum) );
}

function isEmpty(s) {
 return ((s == null) || (s.length == 0));
}

function stripCharsNotInBag(s, bag){
 var i;
 var sRet = "";
 for (i = 0; i < s.length; i++)
 {
  var c = s.charAt(i);
  if (bag.indexOf(c) != -1) sRet += c;
 }
 return sRet;
}
