

function PlanTacner() {
 // todos los atributos son cambiables
 this.interesAnual = 0.59; // tna, en tanto por uno, sin iva incluido (eg: 0.49) 
 this.tasaSeguro = 0.0; // tasa anual,en tanto por uno, sin iva incluido (eg: 0.0408) (DEJAR EN 0.0 SI NO ESTA ASEGURADO) 
 this.iva = 0.21; // (eg: 0.21)
 this.gastoCuota = 1.39; // gastos de pago de cuota, sin iva
 this.gastoTransferencia = 6.10; // costo de transferencia, sin iva
 this.diasEnAnio = 365.0; // 365 o 360 ? 
 this.dias = 30; // dias entre cuotas; 30 o 365.0/12.0 (tambien desde saldo inciial hasta primera cuota)
 this.maxCap = 10000.0; // limite de credito maximo
 this.maxNc = 18; // cantidad maxima de cuotas
 // los que siguen son 'vivos'
 this.nc = 18; // cantidad de cuotas
 this.capital = 0.0; // capital inicial: usar transferir() para setearla
 this.gasto0 = 0.0; // gasto  inicial (iva incluido)

 this.reset = function() {
   this.capital = 0.0;
   this.gasto0 = 0.0;
   this.nc = this.maxNc;
   this.contratarSeguro(false);
   this.contratarEnvioCarta(false);
 } 

 this.isEmpty = function() {
    return this.nc <= 0 || this.capital < 10.00;
 }

 this.contratarSeguro =function(flag) {
    if(flag) this.tasaSeguro = 0.0408;
    else     this.tasaSeguro = 0.0;
 }

 this.contratarEnvioCarta = function(flag) {
    if(flag) this.gastoCuota = 1.39 + 4.9;
    else     this.gastoCuota = 1.39;
 }

 /** maximo monto que puede solicitar transferir */
 this.getMaxTransfer = function() {
   var t =  this.maxCap -  this.capital;
   return Math.round(t*100)/100;
 }

 // esto acumula el saldo de gasto y capital ; llamar a reset antes si no queremos continuar un plan anterior
 this.transferir = function(m) {
   this.gasto0 += this.gastoTransferencia * (1.0 + this.iva);
   this.capital += m;
 } 

 // calcula el monto de la cuota (sin formatear) . solucion explicita, no iterativa
 this.solve = function() {
  if(this.isEmpty()) return 0.0;
  var dt = this.dias * (this.interesAnual + this.tasaSeguro) * (1.0 + this.iva) / this.diasEnAnio; // tasa nominal "mensual"
  var g = this.gastoCuota * (1.0 + this.iva); // gasto total, iva incluido, por cuota
  var alfa = dt + 1.0; 
  var beta = Math.pow(alfa, this.nc - 1.0);
  var cuota = (beta * (this.gasto0  * dt + alfa * (g + this.capital * dt)) - g) / (beta * alfa - 1.0);
  return cuota;
 }
   
 // calcula la tasa CFT anual, sin formatear . solucion iterativa
 this.solveCFT = function()  {
  if(this.isEmpty()) return this.interesAnual+ this.tasaSeguro;
  var cuota = this.solve();
  var r = this.capital/cuota;
  var x1 = (this.nc/r - 1.0)/(this.nc+1);
  if (x1< 0) x1 = 0;
  var x2 = 1.0/r;
  var x = (x1+x2)*0.5;
  var x0 = x1;
  var y = 1000.0;
  var cont = 0;
  while( Math.abs(x-x0)>0.000001) { // busq. bin.
   if(cont++ >1000) return 0; // error
   x0 = x;
   y = Math.pow(1+x, this.nc) * (1 - r * x)-1.0;
   if(y >0) { x = (x0 + x2)*0.5;  x1 = x0;}
   else     { x = (x0 + x1)*0.5;  x2 = x0;} 
  }
  return this.diasEnAnio * x / this.dias;
 }

 /* devuelve el monto pagado */
 this.pagarCuota = function() {
  if(this.isEmpty()) return;
  var cuota = this.solve();
  cuota = Math.round(cuota*100)/100;
  var dt = this.dias * (this.interesAnual + this.tasaSeguro) * (1.0 + this.iva) / this.diasEnAnio; // tasa nominal "mensual"
  var g = this.gastoCuota * (1.0 + this.iva); // gasto total, iva incluido, por cuota
  var iig = this.gasto0 + g + dt * this.capital; // iig antes de pagar
  if(iig < cuota) { // casi siempre
   this.gasto0 = 0;
   this.capital = this.capital + iig - cuota; 
  } else {
   this.gasto0 = this.gasto0 - cuota;
  }
  this.nc = this.nc -1;
  if(this.nc == 0) this.reset();
  return cuota;
 }   

 this.formatMonto = function(m) {
  return "$ " + this.formatMontoNS(m);
 }

 this.formatMontoNS = function(m) {
  if (m.toFixed) m = m.toFixed(2);  // IE 5.5 and above
  else m = Math.round(m*100)/100;
  return m + "";
 }

 this.formatPorc = function(m) {
  m = m * 100;
  if (m.toFixed) m = m.toFixed(2); // IE 5.5 and above
  else m = Math.round(m*100)/100;
  return m + "%";
 }

 // dado interes y gasto (iva incluido) abre en  (interes sin iva,gasto sin iva,iva) 
 this.ivaExtract = function(i,g) {
    i = i / (1.0 + this.iva);
    g = g / (1.0 + this.iva);
    return [  i,g,(i+g) * this.iva ];
 }

 /*
Devuelve string con marcha del plan, formato html. Estilo sugerido:
 div.plantacner {width:480px;text-align:left; font-size:11px;font-family:Arial;}
 div.plantacner table  {background-color:#444;} div.plantacner table caption {font-size:12px}
 div.plantacner table td {background-color:#fff;padding:2px;font-size:11px;font-family:Arial;text-align:right;}
 div.plantacner table thead td { text-align:center;background-color:#eee}
*/
 this.outputPlan = function() {
  if(this.isEmpty() ) return "No hay plan de cuotas. Elija capital inicial y cantidad de cuotas.";
  var cuota = this.solve();
  cuota = Math.round(cuota*100)/100;
  var out = "<div class='plantacner'><table cellspacing='1' width='100%'><caption>Marcha del plan</caption><thead><tr><td>Cuota</td><td>Monto cuota</td><td>Intereses</td><td>Gastos <br>+seguro</td><td>IVA</td><td>Cuota Capital</td><td>Saldo capital</td></tr></thead>";
  out += "<tbody><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>";
  var igt = this.ivaExtract(0,this.gasto0);
  out += "<td>" + this.formatMontoNS(igt[1]) + "</td><td>" + this.formatMontoNS(igt[2]) + "</td><td>&nbsp;</td><td>" + this.formatMontoNS(this.capital) + "</td></tr>";
  var dt = this.dias * this.interesAnual * (1.0 + this.iva) / this.diasEnAnio; // tasa nominal "mensual" de interes 
  var dts = this.dias * this.tasaSeguro * (1.0 + this.iva) / this.diasEnAnio; // tasa nominal "mensual" de seguro

  var gpc = this.gastoCuota * (1.0 + this.iva); // gasto total, iva incluido, por cuota
  var cap = this.capital;
  var gasto = this.gasto0; // saldo de gasto, iva incluido
  var interes = 0.0; // saldo interes, iva incluido
  var cuotac = cuota; // cuota corregida
  var capAnt=0.0; // capital anterior
  var gastoDev=0.0; 
  var interesDev=0.0; 
  for (var c = 1; c <= this.nc; c ++) {
      gastoDev = this.gastoCuota * (1.0 + this.iva) + dts*cap;
      interesDev = dt * cap; // 
      gasto   += gastoDev ; 
      interes += interesDev;
      capAnt = cap;
      cuotac = cuota;
      if(gasto+interes < cuota) { // casi siempre
        cap -= (cuotac-(gasto+interes)); 
        gasto = 0.0;
        interes = 0.0;
      } else {
        interes -= (cuotac-gasto);
        gasto = 0.0;
      }
      if(c == this.nc) { // fuerzo saldo final a 0
          cuotac += cap;
          cap =0;
      }
     out += "<tr><td>" + c + "</td><td>" + this.formatMontoNS(cuotac) + "</td>";
     var igt = this.ivaExtract(interesDev,gastoDev);
     out += "<td>" + this.formatMontoNS(igt[0]) + "</td><td>" + this.formatMontoNS(igt[1]) + "</td><td>" + this.formatMontoNS(igt[2]) + "</td>";
     out += "<td>" + this.formatMontoNS(capAnt-cap) +"</td><td>" + this.formatMontoNS(cap) + "</td></tr>";
  }
  out += "</tbody></table><br>" + this.formatMonto(this.capital) + " en " + this.nc + " cuotas de " + this.formatMonto(cuota) +". ";
  out += " Plan calculado con el tarifario vigente: TNA: " + this.formatPorc(this.interesAnual) + ", CFT: " + this.formatPorc(this.solveCFT()) + ". Montos en pesos. ";
  out += " Las cuotas son fijas, totales e incluyen <b>todos</b> los gastos, impuestos y tasas. Nunca se capitalizan intereses, impuestos, o gastos. ";
  return out;
 }

   /** funcion auxiliar rebuild de select list de montos a transferir ; no toca el elemento 0 */
  this.rebuildTransferSelectList = function(elementid) {
       var maxval = this.getMaxTransfer();
       var s = document.getElementById(elementid);
       retiros=[0,500,1000,1500,2000,3000,4000,5000,7500,10000];
       for (var j=s.length -1; j >= 1 ;j--) s.options[j]=null; 
       if(maxval < 10.0)  { 	    s.options[1] = new Option("No hay disponible","");return; }
       var i=1;
       for ( i=1;retiros[i]<maxval && i < retiros.length;i++) {
	    s.options[i] = new Option(this.formatMonto(retiros[i]),retiros[i]);
       }
      s.options[i++] = new Option(this.formatMonto(maxval),maxval);
      s.options[i++] = new Option("Ingresar monto manual",-100);
      
      s.options[0].selected = true;
   }
}

