package com.fitbank.installment;

import java.math.BigDecimal;

import com.fitbank.common.helper.Constant;

public class AdvanceSpecialGradualInstallment extends SpecialGradualInstallment{



	/* (non-Javadoc)
	 * @see com.fitbank.installment.AbstractQuota#calculate(com.fitbank.installment.InstallmentTable)
	 */
	public void calculate(InstallmentTable pQuotaTable) throws Exception {
		this.quotaTable = pQuotaTable;
		this.quotanumber = pQuotaTable.getBegincalculationperiod();      
		this.reducedcapital = pQuotaTable.getAmount();
		isAdvancedInterest = true;
		fillCapitalQuotas();
		generateTable();    
	}
		
	
	/**
	 * Metodo que genera la tabla de pagos desde la ultima cuota hasta la primera. 
	 * @throws Exception
	 */
	private void generateTable() throws Exception {
		this.calculatePaymentDays();
		BigDecimal capitalZero = Constant.BD_ZERO;
		int quotaCounter = 0;
		int capitalQuotaCounter = 0;
		boolean first = true;
		boolean end = false;
		reducedcapital = Constant.BD_ZERO;
		for (int i = quotanumber; i >= quotaTable.getBegincalculationperiod(); i--) {	
			quotaCounter = quotaCounter + 1;
			if( isCapitalQuota(quotaCounter,first)) {
				capitalQuotaCounter = capitalQuotaCounter + 1;
				if(capitalQuotaCounter == this.capitalPeriod){
					end = true;
				}
				if(originalInicialDate == null ){
					this.calculateCuota(quotaCapital,end,i);
					quotaCounter = 0;				
				}else if(originalInicialDate.compareTo(super.getNextpaydate()) == 0){
					this.calculateCuota(quotaCapital,end,i);
					quotaCounter = 0;	
					originalInicialDate = null;
				}else{
					this.calculateCuota(capitalZero,end,i);	
				}
				
			} else {			
				this.calculateCuota(capitalZero,end,i);
			}
			super.processByCategory(quotaTable.isCalculatePresentValue());
			first = false;
		}//end for	 
		//super.updateQuota(quotaTable.getBegincalculationperiod(), reducedcapital, Constant.BD_ZERO);
		super.updateQuota(0, reducedcapital, Constant.BD_ZERO);
	}
	
	private boolean isCapitalQuota(Integer pQuotaCounter, boolean pFirst) throws Exception {
		return this.capitalPeriod == pQuotaCounter || pFirst || (originalInicialDate != null && originalInicialDate.compareTo(super.getNextpaydate()) == 0);
	}
	
		
	/**
	 * Calcula tabla de pago dado una cuota fija.
	 * @throws Exception
	 */
	private void calculateCuota(BigDecimal pCapital, boolean pEnd,Integer pQuotaNumber) throws Exception{
		// Obtiene los valores de interes y comision para cada categoria
		// Obtiene el valor de interes y comision de la cuota
		// Si se trata de la ultima cuota
		BigDecimal capital = pCapital;
		if(pEnd){
			// Carga todo el capital reducido al capital de la cuota
			capital = quotaTable.getAmount().subtract(reducedcapital); 
		}
		this.reducedcapital = this.reducedcapital.add(capital);
		super.updateQuota(pQuotaNumber, reducedcapital.subtract(capital), capital);
		super.globalIntrest = Constant.BD_ZERO;				
	}
	



	/**
	 * Metodo que llena crea las el nuemro de cuota con su fecha de pago. 
	 * @throws Exception
	 */
	private void calculatePaymentDays() throws Exception {
		this.calculateFistpaymentdate(quotaTable);
		super.addOnePayMetDay(quotaTable);
		super.addQuota(0,this.reducedcapital,Constant.BD_ZERO,false);
		//quotanumber++;
		for (int i = this.quotaTable.getBegincalculationperiod(); i <= totalInterestPeriod ; i++) {
			super.globalIntrest = Constant.BD_ZERO;
			super.calculatePayDate(quotaTable);
			super.addQuota(this.quotanumber,this.reducedcapital,Constant.BD_ZERO,true);
			quotanumber++;
		}
		quotanumber--;
	}
	
	
	
}
