// IkariCalc 0.6.0
//      copyright (c) 2008 nikitakit
// License: GNU GPL v3 <http://www.gnu.org/licenses/gpl.html>
// Source code avaible upon request to dmcadmin@gmail.com

// ==================== UTILS ====================


//constants
var townMax = new Array(60,96,143,200,263,333,410,492,580,672,769,871,977,1087,1201,1320,1441,1567,1696,1828,1964,2103,2246,2391);

var wineAmt = new Array(0,4,8,13,18,24,30,37,44,51,60,68,78,88,99,110,122,136,150,165,180,197,216,235,255);

var hColor = "21A121";

//convert bool to int
function toInt(i) {
  if (i) {
    return 1;
  }
  return 0;
}

//checks if an item is in the given array
function inList(array,item) {
  if (item==0) {return false;}
  
    for (var i=0; i < array.length; i++)
    {
      if (i in array &&
          array[i] == item)
        return true;
    }
    return false;
}

//convert time from hours to HMS string
function toTime(hours) {
  var sec = 3600*hours
  
  var s = sec%60;
  var m = (sec%3600-s)/60;
  var h = (sec-60*m-s)/3600;
  
  var s = s.toFixed(0);
  var m = m.toFixed(0);
  var h = h.toFixed(0);
  
  var str="";
  
  if (h<10) {str += "0";} 
  str += h.toString() + ":";
  
  if (m<10) {str += "0";} 
  str += m.toString() + ":";
  
  if (s<10) {str += "0";}
  str += s.toString();
  
  return str;
}

// ==================== OUTPUT FUNCTIONS ====================
//table cell from string
function tCell(str,color) {
  var returnData = "";
  if (color) {
    returnData += "<td style=\"background-color:#" + color +  ";\">";
  } else {
    returnData += "<td>";
  }
  returnData += str;
  returnData += "</td>";
  

  return returnData;
}



// ==================== VALUE CALCULATIONS ====================

function efficiency() {
  if (document.getElementById("capital").value == "1") {return 1;}

  var eff = (parseInt(document.getElementById("govres").value) + 1) / (parseInt(document.getElementById("colonies").value)  + 1);
  if (eff > 1) {return 1;}
  return eff;
}

function satisfaction(population, useWine) {
  //base satisfaction
  var s = 196;

  //research
  var sci = parseInt(document.getElementById("rScience").value);
  var eco = parseInt(document.getElementById("rEconomy").value);
  if (document.getElementById("capital").value=="1") {
    s += 50 * toInt(sci >= 1) + 200 * toInt(eco >= 17);
  }
  s +=  25 * toInt(eco >= 11) ;

  //museum
  s += 20 * parseInt(document.getElementById("museum").value) + 50 * parseInt(document.getElementById("cgoods").value);

  //tavern
  s += 12 * parseInt(document.getElementById("tavern").value) + useWine * 60 * parseInt(document.getElementById("wine").value);

  //corruption and dissatisfaction from population
  return (s*efficiency() - population);
}
  
function maxPopulation() {
  //base population
  var p =  townMax[parseInt(document.getElementById("town").value)-1];

  //research
  var sci = parseInt(document.getElementById("rScience").value);
  var eco = parseInt(document.getElementById("rEconomy").value);
  if (document.getElementById("capital").value=="1") {
    p += 200 * toInt(eco >= 17)
  }
  p +=  50 * toInt(eco >= 11) + 50 * toInt(sci >= 1)

  return p;

}

/* 
// UNUSED
function sciBonus() {
  var r = parseInt(document.getElementById("rScience").value);
  if (r>=14) {
    return 1-0.16;
  }
  if (r>=9) {
    return 1-0.14;
  }
  if (r>=5) {
    return 1-0.06;
  }
  if (r>=2) {
    return 1-0.02;
  }
  return 1;
}

function buildBonus() {
  var r = parseInt(document.getElementById("rEconomy").value);
  if (r>=13) {
    return 1-0.16;
  }
  if (r>=10) {
    return 1-0.14;
  }
  if (r>=6) {
    return 1-0.06;
  }
  if (r>=2) {
    return 1-0.02;
  }
  return 1;
}
*/

// ==================== INDIVIDUAL TIME CALCULATIONS ====================

function tPopulation(start, useWine, stop) {
  var t = start;
  var population=parseInt(document.getElementById("population").value);

  var a = new Array();
  var g = 0.02*satisfaction(population, useWine);

  while ((population<maxPopulation()) && (g>0) && t<=stop) {
    a.push(t);
 
    t += 1/g;
    population+=1;
    g -= 0.02; //g=0.02*satisfaction(population, useWine);
    
  }
  
  if (t<= stop) {a.push(t);}

  return a;

}




function tResources(aRes,wRes,gRes,aLux,wLux,gLux,spendLux) {
  var a = new Array();
  var i;

  if (wRes>0) {
    for (i=0; i<gRes.length; i++) {
      a.push((gRes[i]-aRes)/(wRes*efficiency()));	
    }
  }

  //if Lux. spending is more than income, do not calculate
  if ((wLux*efficiency()/2-spendLux)<=0) {
    return a;
  }

  if (wLux>0) {
    for (i=0; i<gLux.length; i++) {
      a.push((gLux[i]-aLux)/(wLux*efficiency()/2-spendLux));	
    }
  }
  return a;
}

function tTimes() {
  return document.getElementById("times").value.split(",");
}


// ==================== COMPLETE CALCULATION ====================

function start() {
  oResult.innerHTML = calculate();
}

function calculate() {
  //variables
  var a1 = new Array(); var a2 = new Array();

  var cP = document.getElementById("calcPopulation").checked;
  var cR = document.getElementById("calcResources").checked;

  var incomeWin = 0;

  //Nothing to calculate
  if (!cP && !cR) {
    return "Nothing to calculate.<br /><br />Please check either <br /> \"Calculate Population\",<br /> \"Calculate Resources\", or both options.";
  }

  
  //Times from resources
  if (cR) {
    var rL = document.getElementById("resLux").value;

    var aRes = parseInt(document.getElementById("aRes_").value);
    var wRes = parseInt(document.getElementById("wRes_").value);
    var gRes = document.getElementById("gRes_").value.split(",");

    var aMar = parseInt(document.getElementById("aMar_").value);
    var aCry = parseInt(document.getElementById("aCry_").value);
    var aSul = parseInt(document.getElementById("aSul_").value);
    var aWin = parseInt(document.getElementById("aWin_").value);

    var wLux = parseInt(document.getElementById("wLux_").value)*2;
    var gLux = document.getElementById("gLux_").value.split(",");

    switch (rL) {
    case "Marble":
      var aLux = aMar;
      break;
    case "Crystal":
      var aLux = aCry;
      break;
    case "Sulphur":
      var aLux = aSul;
      break;
    default:
      var aLux = aWin;
      incomeWin = -wineAmt[document.getElementById("wine").value];
    }
    
    a1 = tResources(aRes,wRes,gRes,aLux,wLux,gLux,-incomeWin);

    if (rL=="Wine") {
      incomeWin += (wLux*efficiency()/2);
    } else {
      incomeWin = -wineAmt[document.getElementById("wine").value];
    }
  }


  //Times from population
  if (cP && !cR) {
    a2 = tPopulation(0,1,168); //Limit time to 1 week. Assume sufficient wine
  } 

  if (cP && cR) {
    if (incomeWin>=0) {
      a2 = tPopulation(0,1,168); //Limit time to 1 week. Wine is sufficient.
    } else {
      a2 = tPopulation(0,1,aWin/-incomeWin); //until wine runs out
      a2 = a2.concat(tPopulation(aWin/-incomeWin,0,168)); //Calculate the rest
    }
  }

  //Times from input
  var a3 = tTimes();

  //combine times into one array
  var a_ = new Array();
  a_=a_.concat(a1,a2,a3);

  //sort the times
  a_.sort( function (a,b) { return a-b });

  //remove duplicate entries from the array. Also remove negative times
  var a = new Array();
  
  for (var i=0; i<a_.length; i++) {
    if (a_[i]!=a[a.length-1] && a_[i]>=0) {
      a.push(a_[i]);
    }
  }


  //BEGIN CALCULATION

  //Header
  var results = "<table><tr><td>Time</td><td></td>"
  if (cR) {
    results+="<td>Wood</td><td>Marble</td><td>Wine</td><td>Crystal</td><td>Sulphur</td>";
  }
  if (cP && cR) {results+="<td></td>";}
  if (cP) {
    results+="<td>Population</td><td>Growth</td>";
  }
  results += "</tr>";


  var pop=parseInt(document.getElementById("population").value);
  var res; var resWin; 
  var cell;

  for (i=0; i<a.length; i++) {
    results += "<tr>";
    if (inList(a3,a[i])) {
      results += tCell(toTime(a[i]),hColor);
    } else {
      results += tCell(toTime(a[i]));
    }
    
    results+=tCell("");

    if (cR) {
      res=aRes+(a[i]*wRes*efficiency());
      if (inList(gRes, res)) {
        results += tCell(res,hColor);
      } else {
        results += tCell(res.toFixed(0));
      }

      resWin = (aWin+incomeWin*a[i]).toFixed(0);
      if (resWin<0) {resWin = 0;}
      if (rL == "Wine") {
        res = resWin;
      } else {
        res = aLux+(a[i]*wLux*efficiency()/2);
      }

      if (inList(gLux, res)) {
        cell = tCell(res,hColor);
      } else {
        cell = tCell(res);
      }

      switch (rL) {
      case "Marble":
        results += cell + tCell(resWin) + tCell(aCry) + tCell(aSul);
        break;
      case "Crystal":
        results += tCell(aMar) + tCell(resWin) + cell + tCell(aSul);
        break;
      case "Sulphur":
        results += tCell(aMar) + tCell(resWin) + tCell(aCry) + cell;
        break;
      default:
        results += tCell(aMar) + cell + tCell(aCry) +  tCell(aSul);
      }


    }

    if (cP && cR) {results+=tCell("");}

    if (cP) {
      if (inList(a2,a[i])) {
        results += tCell(++pop,hColor);
      } else {
        results += tCell(pop);
      }
      if (cR) {
        results += tCell((0.02*satisfaction(pop,toInt(resWin>0))).toFixed(2));
      } else {
        results += tCell((0.02*satisfaction(pop,1)).toFixed(2));
      }
    }

    results += "</tr>";

  }
  results+="<tr><td colspan=\"10\" style=\"text-align:center;border: 1px #B0A16D solid;\">Simulation complete</td></tr>";
  results+="</table>";


  return results;
}
