var graphKey;

Event.observe(window, 'load', function() {
  $$('.loancalc').each(function(el) {
    el.observe('click', addPopupLoanCalc);
  });

  // http://robcos.com/onresize-event-and-prototype/
  Event.observe(document.onresize ? document : window, "resize", function() {
    $$('.prototip').each(function(el) {
      try {
        if(el.visible())
          centerTip(el);
      } catch(e) {
      }
    });
  });
});

// {{{ addPopupLoanCalc(ev)
var fixprice_inited = 0;
function addPopupLoanCalc(ev) {
  var el = ev.element ? Event.element(ev) : ev;
  if(!el) return;
  if(ev.element) ev.stop();

  if(!fixprice_inited) {
    fixprice_init();
    fixprice_inited = 1;
  }

  var price = el.rel.replace(/^price:/, '')
                    .replace(/([0-9]).([0-9]+),([0-9]+)$/, '$1$2.$3')
                    .replace(/[^0-9.]/g, '');
  if(!price)
    return alert('Non-numeric price used. Cannot calculate loan');

  var templatetype = el.hasClassName('mortgage') ? 'mortgage' : 'loan';
  var rmother      = el.hasClassName('mortgage') ? 'loantemplate'
                                                 : 'mortgagetemplate';

  if($(rmother)) {
    Element.remove($(rmother).parentNode.parentNode);
  }

  var tip = showTip(el, drawPopup(templatetype, price));
  var tipClosure = function() { centerTip(tip.wrapper); };
  setTimeout(tipClosure, 3);

  // With it drawn, start hooking:
  setTimeout(initCalcHooks, 5);
  setTimeout(doSum, 5);
} // }}}

// {{{ initCalcHooks()
function initCalcHooks() {
  if($('apr')) {
    var apr = $('apr');
    apr.observe('change', function() {
      if($('capr')) {
        $('capr').value = $F('apr');
      }
    });
    apr.focus();
  }

  $w('period periodtype').each(function(id) {
    var el = $(id);
    if(el) {
      el.observe('change', tidyPeriod);
      el.observe('keyup', tidyPeriod);
    }
  });

  tidyPeriod($('period'));


  $w('otax oinsurance ctax cinsurance cprincipal caprincipal apr capr ' +
     'period periodtype').each(function(id) {
    var el = $(id);
    if(el) {
      el.observe('change', doSum);
      if(el.type == 'text') {
        el.observe('keyup', doSum);
      }
    }
  });
}  // }}}

// {{{ tidyPeriod(ev)
function tidyPeriod(ev) {
  var el = ev.element ? Event.element(ev) : ev;
  if(!el) return;

  var id = el.id.replace(/type$/, '');

  var period     = $F(id);
  var periodtype = $F(id + 'type');

  if(period > 12 && periodtype == 'month') {
    var vmod = period % 12;

    // Only if exactly divisible by 12:
    if(vmod == 0) {
      $(id + 'type').value = 'year';
      $(id).value = parseInt(period/12);
    }
  }
} // }}}


// {{{ doSum(ev)
function doSum(ev){
  if(ev) {
   var ignoreKeyFlag = 0;

   [Event.KEY_BACKSPACE, Event.KEY_TAB,  Event.KEY_RETURN, Event.KEY_ESC,
    Event.KEY_LEFT,      Event.KEY_UP,   Event.KEY_RIGHT,  Event.KEY_DOWN,
    Event.KEY_DELETE,    Event.KEY_HOME, Event.KEY_END,    Event.KEY_PAGEUP,
    Event.KEY_PAGEDOWN,  Event.KEY_INSERT].each(function(kv) {
     if(ev.keyCode == kv) {
       ignoreKeyFlag = 1;
       throw $break;
     }
   });

   if(ignoreKeyFlag)
    return;
 }

 // {{{ Fetch form data to JS vars and check if updated needed.
 var oPrice = $w('principal apr period periodtype').map(function(id) {
   return $(id) ? $F(id) : 0;
 });

 // Convert period to months:
 if(oPrice[3] == 'year') { oPrice[2] *= 12; }
 var cPrice = $w('cprincipal capr period periodtype').map(function(id) {
   return $(id) ? $F(id) : 0;
 });

 // Convert period to months:
 if(cPrice[3] == 'year') { cPrice[2] *= 12; }

 var aprincipal = from_money($F('caprincipal') || 0);

 var newKey = oPrice.join(',') + cPrice.join(',') + aprincipal;

 if($('otax'))       newKey += ';' + $F('otax');
 if($('ctax'))       newKey += ';' + $F('ctax');
 if($('oinsurance')) newKey += ';' + $F('oinsurance');
 if($('cinsurance')) newKey += ';' + $F('cinsurance');

 // No update needed:
 if(graphKey && newKey == graphKey)
   return;

 graphKey = newKey;
 // }}}


 var am = new Amortize();

 // {{{ For fixed monthly fee:
 var savings  = am.getSavingsPayingAdditional(oPrice[0], oPrice[1],
                                              oPrice[2], 0);
 var updates = [
  ['omonthlybase', savings['oldMonthlyPayment'], 1],
  ['total',        savings['oldTotalPayment'],   1],
  ['payperiod',    savings['oldPaymentPeriod'],  0]
 ];

 var monthlyBase = (1*savings['oldMonthlyPayment']);
 if($('otax')) {
   var val = parseFloat($F('otax') || 0)/12;
   updates.push(['omonthlytax', val, 1]);
   monthlyBase += (1*val);
 }

 if($('oinsurance')) {
   var val = parseFloat($F('oinsurance') || 0)/12;
   updates.push(['omonthlyinsurance', val, 1]);
   monthlyBase += (1*val);
 }
 updates.push(['monthly', monthlyBase, 1]);

 updates.each(function(kvp) {
   var val = kvp[1];
       val = kvp[2] ? fixprice(val, cSymbol) : fixMonths(val);

   if($(kvp[0]))
     $(kvp[0]).update(val);
 });
 // }}}

 // {{{ For fixed monthly fee + additional:
 var csavings  = am.getSavingsPayingAdditional(cPrice[0], cPrice[1],
                                               cPrice[2], aprincipal);

 updates = [
  ['cmonthlyextra', csavings['monthlyPaymentDifference'], 1],
  ['ctotal',        csavings['newTotalPayment'],          1],
  ['ctotalsavings', csavings['paymentDifference'],        1],
  ['cmonthlybase',  csavings['newMonthlyPayment'],        1],
  ['cpayperiod',    csavings['newPaymentPeriod'],         0],
  ['ctimesavings',  csavings['periodSaving'],             0]
 ];

 monthlyBase = (1*csavings['newMonthlyPayment']);
 if($('ctax')) {
   var val = parseFloat($F('ctax') || 0)/12;
   updates.push(['cmonthlytax', val, 1]);
   monthlyBase += (1*val);
 }

 if($('cinsurance')) {
   var val = parseFloat($F('cinsurance') || 0)/12;
   updates.push(['cmonthlyinsurance', val, 1]);
   monthlyBase += (1*val);
 }
 updates.push(['cmonthly',  monthlyBase, 1]);

 updates.each(function(kvp) {
   var val = kvp[1];
       val = kvp[2] ? fixprice(val, cSymbol) : fixMonths(val);

   if($(kvp[0]))
     $(kvp[0]).update(val);
 });
 // }}}

 var isYear = $F('periodtype') == 'year';
 var period = parseInt($F('period') || 0);
 if(isYear) period *= 12;

 var oMonPay = (1*savings['oldMonthlyPayment']);
 var cMonPay = (1*csavings['newMonthlyPayment']);

 var oPrincipal = (1*oPrice[0]);
 var oResidual  = (1*oPrincipal);

 var cPrincipal = (1*cPrice[0]) + (1*aprincipal);
 var cResidual = cPrincipal;

 var oPeriod = csavings['oldPaymentPeriod'];
 var cPeriod = csavings['newPaymentPeriod'];

 var data = getChartData(oPrincipal, oResidual, oMonPay, oPrice[1], oPeriod,
                         cPrincipal, cResidual, cMonPay, cPrice[1], cPeriod,
                         aprincipal);

 initGraph({
   ds : data,
   isyear      : isYear,
   period      : oPrice[2],
   colorscheme : {
    'Loan' : '#6d1d1d',
    'Pay Addt. Monthly' : '#224565'
   }
 });
} // }}}


// {{{ initGraph(ds)
function initGraph(data) {
 var ds     = data['ds'];
 var mons   = data['period'];
 var isYear = data['isyear'];
 var colors = data['colorscheme'] || 'red';

 var xticks = new Array();
 if(isYear) mons *= 12;

 if(!mons) return;

 var incr = parseInt(mons);
 if(incr < 6) incr = 6;
 incr = parseInt(incr/6);
 var i=0; var c=0;

 var ptype = mons > 36 ? 'yrs' : 'mons';
 var pdiv  = mons > 36 ? 12 : 1;

 for(i=0; i<=(mons+incr); i+=incr){
   if(i>=(c*incr)){
     xticks.push({v:i, label:(i/pdiv) + ptype});
     c++
   }
 }

 try {
  var payparent = $('payments').parentNode;
  var children =  $A(payparent.childNodes);
  children.each(function(c){
    if(c.nodeName == 'DIV')
      payparent.removeChild(c);
  });

  var graph = new Plotr.LineChart('payments', {
   shouldFill: false,
   colorScheme: colors,
/*
   xAxis  : [0, mons],
   yAxis  : [0, 100],
   xTicks : xticks,
*/
   backgroundLineColor: 'gray',
   axisLineColor: 'black',
   axisLabelColor: 'black',
   sweetRender: true,
   drawXAxis: true,
   drawYAxis: true
  });

  graph.addDataset(ds);
  graph.render();

  // IE (7?) fix:
  $$('#payments div').each(function(div) {
    try {
      div.style.overflow = 'visible';
    } catch(e) { }
  });

  // Fix up amounts with currency:
  $A(payparent.childNodes).each(function(c){
    if(c.nodeName == 'DIV' && c.childNodes.length == 1){
      var fc = c.childNodes[0];
      if(fc.nodeType != 3) return;
      if(fc.nodeValue == '0mons' ||
         fc.nodeValue == '0yrs') throw $break;

      // Fix up DIV:
      var ctop = c.getStyle('top');
      var cleft = c.getStyle('left');
      c.setAttribute('class', 'yaxis');
      c.setAttribute('style', 'top: '+ ctop +'; left: '+cleft);

      // Fix up value being displayed:
      var newval = fc.nodeValue.replace(/\.[0-9]+$/, '');
      c.childNodes[0].nodeValue = newval +'%';
    }
  });
 } catch(e){
alert(e);
 }
} // }}}

// {{{ showTip(data)
function showTip(el, data, className) {
  var tip = new Tip(el, data, {
    fixed: true,
    closeButton: true,
    delay: false,
    showOn: 'click',
    className: 'loancalc',
    hideOn: false,
    offset: {x:el.getWidth() - 2, y: -1 * el.getHeight()},
    title: el.hasClassName('mortgage')
           ? 'Mortgage Calculator' : 'Loan Calculator',
    viewport: true
  });
  tip.showDelayed();

  if(className) {
    $$('.prototip .default').each(function(el) {
      el.addClassName(className);
    });
  }
  return tip;
} // }}}

// {{{ prefixSymbol(el, chld)
function prefixSymbol(el, chld) {
  if(cSymbolPrefix) {
    el.appendChild(document.createTextNode(cSymbol));
    el.appendChild(chld);
  } else {
    el.appendChild(chld);
    el.appendChild(document.createTextNode(cSymbol));
  }
} // }}}

// {{{ centerTip(tip)
function centerTip(tip) {
  var vportDim = document.viewport.getDimensions(); // {width, height}
  var vportScroll = document.viewport.getScrollOffsets(); // [top,left]
  var tipDim = tip.getDimensions();

  // Center vertically:
  if(tipDim['height'] < vportDim['height']) {
    var diff = parseInt((vportDim['height'] - tipDim['height'])/2);
        diff += vportScroll['top'];
    tip.style.top = diff + 'px';
  }

  // Center horizontally:
  if(tipDim['width'] < vportDim['width']) {
    var diff = parseInt((vportDim['width'] - tipDim['width'])/2);
        diff += vportScroll['left'];
    tip.style.left = diff + 'px';
  }
} // }}}

var $E = function(type, params) { return new Element(type, params); }

// {{{ drawPopup(templatetype, price)
function drawPopup(templatetype, price) {

  // form input elements must be within a form:
  var frm = $E('form', {action:'', method:'POST', style: 'width: 343px'});
  frm.observe('submit', function(ev) { ev.stop(); doSum(); });

  if(typeof(record_singular_uc) == 'undefined')
    record_singular_uc = 'Ad';

  frm.appendChild(drawLoanDetails(templatetype, price));
  frm.appendChild(drawPaymentInfo(templatetype, price));

  var data = $E('div', {id: templatetype + 'template'});
  data.appendChild(frm);
  data.appendChild(drawGraphCanvas(templatetype));

  setTimeout(fixprice_init, 10);

  return data;
} // }}}

// {{{ drawLoanDetails(templatetype, price)
function drawLoanDetails(templatetype, price) {
  var row; var th; var td; var input;

  // Fieldset:
  var label = $E('legend').update((templatetype == 'loan'
                               ? 'Loan' : 'Mortgage') + ' Details');
  var fieldset = $E('fieldset', {className: 'payfield loaninput'});

  var tbl   = $E('table');
  var tbody = $E('tbody');

  // Append in reverse order:
  fieldset.appendChild(label);
  fieldset.appendChild(tbl);
  tbl.appendChild(tbody);

  // {{{ Header:
  row = $E('tr');
  row.appendChild($E('th', {className:'labelwidth'}));
  row.appendChild($E('th').update(record_singular_uc +' Price'));
  row.appendChild($E('th').update('Custom Price'));

  var thead = $E('thead');
  thead.appendChild(row);
  tbl.appendChild(thead);
  // }}}

  // {{{ Amount row:
  row = $E('tr');
  th = $E('th');
  th.appendChild($E('label', {'for': 'cprincipal'})
                     .update(templatetype.capitalize() + ' Amount:'));
  row.appendChild(th);

  price = price ? from_money(price) : 0;
  td = $E('td');
  prefixSymbol(td, document.createTextNode(price));

  input = $E('input', {type: 'hidden', name: 'principal', id: 'principal',
                      value: price, className: 'number currency sout'});
  td.appendChild(input);
  row.appendChild(td);

  input = $E('input', {type: 'text', name: 'cprincipal',
                                  id:'cprincipal', value: price, size: 10,
                           maxlength: 10, className: 'number currency sout'});
  td = $E('td');
  prefixSymbol(td, input);

  row.appendChild(td);
  tbody.appendChild(row);
  // }}}

  // {{{ Additional row:
  row = $E('tr');
  th = $E('th');
  th.appendChild($E('label', {'for': 'caprincipal'})
                     .update('Addt. Per Month:'));
  row.appendChild(th);

  td = $E('td').update('n/a');
  row.appendChild(td);

  input = $E('input', {type: 'text', name: 'caprincipal', id:'caprincipal',
                      value: '0.00', size: 10, maxlength: 10,
                       className: 'number currency sout'});
  td = $E('td');
  prefixSymbol(td, input);

  row.appendChild(td);
  tbody.appendChild(row);
  // }}}

  // {{{ APR row:
  row = $E('tr', {className: 'aprrow'});
  th = $E('th');
  var abbr = $E('abbr', {title:'Annual Percentage Rate'})
                         .update('APR');
  label = $E('label', {'for': 'apr'});
  label.appendChild(document.createTextNode('Enter '));
  label.appendChild(abbr);
  label.appendChild(document.createTextNode(':'));
  th.appendChild(label);
  row.appendChild(th);

  input = $E('input', {type: 'text', maxlength: 5, name: 'apr', id: 'apr',
                       value: default_interest_rate,
                       size: 5, className: 'number currency allowpc pcout'});
  td = $E('td');
  td.appendChild(input);
  td.appendChild(document.createTextNode('%'));
  row.appendChild(td);

  input = $E('input', {type: 'text', maxlength: 5, name: 'capr', id: 'capr',
                       value: default_interest_rate,
                       size: 5, className: 'number currency allowpc pcout'});

  td = $E('td');
  td.appendChild(input);
  td.appendChild(document.createTextNode('%'));
  row.appendChild(td);

  tbody.appendChild(row);
  // }}}

  // {{{ Extra fields for mortgages:
  if(templatetype == 'mortgage') {

    // {{{ Yearly Tax:
    row = $E('tr');
    th = $E('th');
    label = $E('label', {'for': 'otax'}).update('Annual Property Tax');
    th.appendChild(label);
    row.appendChild(th);

    input = $E('input', {type: 'text', maxlength: 10, name: 'otax', id: 'otax',
                         value: default_yearly_tax,
                         size: 10, className: 'number currency sout'});
    td = $E('td');
    prefixSymbol(td, input);
    td.appendChild(input);
    row.appendChild(td);

    input = $E('input', {type: 'text', maxlength: 10, name: 'ctax', id: 'ctax',
                         value: default_yearly_tax,
                         size: 10, className: 'number currency sout'});
    td = $E('td');
    prefixSymbol(td, input);
    td.appendChild(input);
    row.appendChild(td);

    tbody.appendChild(row);
    // }}}

    // {{{ Yearly Insurance
    row = $E('tr');
    th = $E('th');
    label = $E('label', {'for': 'oinsurance'}).update('Annual Insurance');
    th.appendChild(label);
    row.appendChild(th);

    input = $E('input', {type: 'text', maxlength: 10, name: 'oinsurance', id: 'oinsurance',
                         value: default_yearly_insurance,
                         size: 10, className: 'number currency sout'});
    td = $E('td');
    prefixSymbol(td, input);
    td.appendChild(input);
    row.appendChild(td);

    input = $E('input', {type: 'text', maxlength: 10, name: 'cinsurance', id: 'cinsurance',
                         value: default_yearly_insurance,
                         size: 10, className: 'number currency sout'});
    td = $E('td');
    prefixSymbol(td, input);
    td.appendChild(input);
    row.appendChild(td);

    tbody.appendChild(row);
    // }}}
  } // }}}

  // {{{ Payment period:
  row = $E('tr');
  th = $E('th');
  label = $E('label', {'for': 'period'}).update('Payment Period:');
  th.appendChild(label);
  row.appendChild(th);

  // {{{ Period + Period Type:
  var pval = templatetype == 'loan' ? default_loan_months
                                    : default_mortgage_years;
  input = $E('input', {type: 'text', size: 3, maxlength: 3, name: 'period',
                         id: 'period', value: pval, className:'number'});
  td = $E('td', {colspan: 2, style: 'padding-right: 25px'});
  td.appendChild(input);

  var ptval = templatetype == 'loan' ? 'month' : 'year';
  input = $E('select', {name: 'periodtype', id: 'periodtype'});
  [ ['month', 'Months' ],
    ['year',  'Years'  ] ].each(function(kvp) {
    var opt = new Element('option', {value: kvp[0]}).update(kvp[1]);
    if(opt.value == ptval) {
      opt.selected = 'selected';
    }
    input.appendChild(opt);
  });
  td.appendChild(input);
  row.appendChild(td);
  // }}}

  row.appendChild(td);
  tbody.appendChild(row);
  // }}}

  return fieldset;
} // }}}

// {{{ drawPaymentInfo(templatetype, price)
function drawPaymentInfo(templatetype, price) {
  var row; var th; var td; var input;

  // Second Fieldset:
  var label = $E('legend').update('Payment Information');
  var fieldset = $E('fieldset', {className: 'payfield loanoutput'});

  // New Fieldset:
  var tbl   = $E('table');
  var tbody = $E('tbody');
  var v = 0;

  // Append in reverse order:
  fieldset.appendChild(label);
  fieldset.appendChild(tbl);
  tbl.appendChild(tbody);

  // {{{ Monthly Payment results:
  row = $E('tr');
  th = $E('th');
  th.appendChild($E('label', {'for': 'monthly'})
                     .update('Monthly Payment:'));
  row.appendChild(th);

  row.appendChild($E('td', {id: 'monthly'}).update('n/a'));
  row.appendChild($E('td', {id: 'cmonthly'}).update('n/a'));
  tbody.appendChild(row);
  // }}}

  // {{{ Mortgage only fields:
  if(templatetype == 'mortgage ') {

    // {{{ Base Monthly:
    row = $E('tr');
    th = $E('th', {className: 'savings'});
    th.appendChild($E('label', {'for': 'cmonthlybase'})
                       .update('Mortgage Fee Per Month:'));
    row.appendChild(th);

    row.appendChild($E('td', {id: 'omonthlybase'})
                    .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));

    row.appendChild($E('td', {id: 'cmonthlybase'})
                    .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));
    tbody.appendChild(row);
    // }}}

    // {{{ Tax Monthly
    row = $E('tr');
    th = $E('th', {className: 'savings'});
    th.appendChild($E('label', {'for': 'cmonthlytax'})
                       .update('Tax (Per Month):'));
    row.appendChild(th);

    row.appendChild($E('td', {id: 'omonthlytax'})
                    .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));

    row.appendChild($E('td', {id: 'cmonthlytax'})
                    .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));
    tbody.appendChild(row);
    // }}}

    // {{{ Insurance Monthly
    row = $E('tr');
    th = $E('th', {className: 'savings'});
    th.appendChild($E('label', {'for': 'cmonthlyinsurance'})
                       .update('Insurance (Per Month):'));
    row.appendChild(th);

    row.appendChild($E('td', {id: 'omonthlyinsurance'})
                    .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));

    row.appendChild($E('td', {id: 'cmonthlyinsurance'})
                    .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));
    tbody.appendChild(row);
    // }}}

  } // }}}

  // {{{ Monthly Extra:
  row = $E('tr');
  th = $E('th', {className: 'savings', colspan:2});
  th.appendChild($E('label', {'for': 'cmonthlyextra'})
                     .update('Extra Payment Per Month:'));
  row.appendChild(th);

  row.appendChild($E('td', {id: 'cmonthlyextra'})
                  .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));
  tbody.appendChild(row);
  // }}}

  // {{{ Total Payment results:
  row = $E('tr');
  th = $E('th');
  th.appendChild($E('label', {'for': 'total'})
                     .update('Total Payments:'));
  row.appendChild(th);

  row.appendChild($E('td', {id: 'total'}).update('n/a'));
  row.appendChild($E('td', {id: 'ctotal'}).update('n/a'));
  tbody.appendChild(row);
  // }}}

  // {{{ Total Savings:
  row = $E('tr');
  th = $E('th', {className: 'savings', colspan: 2});
  th.appendChild($E('label', {'for': 'ctotalsavings'})
                     .update('Total Savings:'));
  row.appendChild(th);

  row.appendChild($E('td', {id: 'ctotalsavings'})
                  .update(cSymbolPrefix ? cSymbol + v : v + cSymbol));
  tbody.appendChild(row);
  // }}}

  // {{{ Pay for results:
  row = $E('tr');
  th = $E('th');
  th.appendChild($E('label', {'for': 'payperiod'})
                     .update('Payment Period:'));
  row.appendChild(th);

  pval = templatetype == 'loan' ? default_loan_months
                                : default_mortgage_years;
  ptval = templatetype == 'loan' ? 'Month' : 'Year';
  if(pval != 1) ptval += 's';

  row.appendChild($E('td', {id: 'payperiod'}).update(pval + ' ' + ptval));
  row.appendChild($E('td', {id: 'cpayperiod'}).update(pval + ' ' + ptval));
  tbody.appendChild(row);
  // }}}

  // {{{ Period Savings:
  row = $E('tr');
  th = $E('th', {className: 'savings', colspan: 2});
  th.appendChild($E('label', {'for': 'ctimesavings'})
                     .update('Paid Off Sooner By:'));
  row.appendChild(th);

  row.appendChild($E('td', {id: 'ctimesavings'}).update('0'));
  tbody.appendChild(row);
  // }}}

  // {{{ Submit button:
  row = $E('tr');
  input = $E('input', { type: 'submit', id: 'updategraph',
                       value: 'Show Payment Information'});
  td = $E('td', {colspan: 3, style: 'text-align: center'});
  td.appendChild(input);
  row.appendChild(td);
  tbody.appendChild(row);
  // }}}

  return fieldset;
} // }}}

// {{{ drawGraphCanvas(templatetype)
function drawGraphCanvas(templatetype) {
  var fieldset = $E('fieldset', {className: 'payfield loangraph'});
  var label    = $E('legend').update('Repayment Schedule');
  var canvas   = $E('canvas', {id: 'payments', height: '300', width: '340'});
  var div      = $E('div', {id: 'canvasframe'});
  var yLabel   = $E('div', {id: 'ylabel', className: 'axislabel'})
                           .update('Amount (' + cSymbol + ')');
  var xLabel   = $E('div', {id: 'xlabel', className: 'axislabel'})
                           .update('Time (Months)');


  div.appendChild(canvas);
  fieldset.appendChild(label);
  fieldset.appendChild(yLabel);
  fieldset.appendChild(div);
  fieldset.appendChild(xLabel);
  return fieldset;
} // }}}

// {{{ getChartData(oPrincipal, oResidual, oMonPay, oAPR, oPeriod, cPrincipal, cResidual, cMonPay, cAPR, cPeriod, aprincipal)
function getChartData(oPrincipal, oResidual, oMonPay, oAPR, oPeriod,
                      cPrincipal, cResidual, cMonPay, cAPR, cPeriod,
                      aprincipal) {
 var oLoan = [];
 var cLoan = [];
 var samevalues = ([oPrincipal, oResidual, oMonPay, oAPR].join(',') ==
                   [cPrincipal, cResidual, cMonPay, cAPR].join(','))
               && (!aprincipal || aprincipal == '0.00');

 var period = oPeriod > cPeriod ? oPeriod : cPeriod;

 for(var i=0;i<period+1;i++){
  if(oResidual < 0 && oLoan[oLoan.length-1][1] != 0) {
    oLoan.push([oPeriod, 0]);
  } else {
    oLoan.push([i, oResidual]);
  }

  var oInterest = oResidual * oAPR/1200;
  oResidual += (1*oInterest) - oMonPay;

  if(!samevalues) {
    if(cResidual < 0 && cLoan[cLoan.length-1][1] != 0) {
      cLoan.push([cPeriod, 0]);
    } else {
      cLoan.push([i, cResidual]);
    }

    var cInterest = cResidual * cAPR/1200;
    cResidual += (1*cInterest) - cMonPay;
  }
 }

 var data = { 'Loan' : oLoan };

 if(cLoan.length) {
   data = Object.extend(data, {'Pay Addt. Monthly' : cLoan});
 }
 return data;
} // }}}

// {{{ fixMonths(val)
function fixMonths(val) {
  if(val < 0.0005) val = 0;
  val = floatAsDP(val, 2);

  if(val > 12 && $F('periodtype') == 'year') {
    var yval = floatAsDP(val/12, 2);
    if(new String(yval).match(/\.[0-9][1-9]$/)) {
      yval = yval.replace(/0$/, '').replace(/\.0$/, '');
      val = yval + ' Year' + (yval == 1 ? '' : 's');
    } else {
      val += ' Month' + (val == 1 ? '' : 's');
    }
  } else {
    val += ' Month' + (val == 1 ? '' : 's');
  }

  return val;
} // }}}
