package com.fp.common.helper;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Enumeracion que maneja las distintas bases de calculo que maneja la aplicacion.<br>
 * El numerador representa los dias mes ejeplo si la base es 360/xxx indica que los meses son de 3o dias, 
 * si la base es 365/*** indica que los meses son calendario. <br>
 * El denominador indica el numero de dias que se paga intereses en el anio. 
 * Ejemplo 360/360,  360/365, 365/360, 365/365. <br>
 * @author Jorge Vaca
 * @version 2.1
 */
public enum CalculationBase {
	B360360(360,360, 30,"360/360"), B360365(360,365, 30,"360/365"), B365360(365,360, 1,"365/360"),B365365(365,365, 1,"365/365");
	/**Numero de dias anio de la base de calculo denomindor. */
	private int yearBase;
	/** Numerador de la base de calculo.  */
	private int monthBase; 
	/** Numero de dias por mes de la base de calculo, si es 1 indica que son meses calendario.  */
	private int days;
	/** Codigo de base de calculo.   */
	private String baseCode="";
  
	/**
	 * Crea una enumeracion de la base de calculo. 
	 * @param pMonth	Numerador de la base de calculo.
	 * @param pYearbase	Denominador de la base de calculo. 
	 * @param pDays		Dias de la base de calculo, si es 1 son dias calendario. 
	 * @param pBase		Codigo de la base de calculo. 
	 */
	private CalculationBase(int pMonth,int pYearbase, int pDays,String pBaseCode) {
		this.yearBase = pYearbase;
		this.monthBase=pMonth;
		this.days = pDays;
		this.baseCode=pBaseCode;
	}

	public int getYearBase() {
		return yearBase;
	}

  /**
   * Entrega el numero de dias de un mes y anio dado los dias mes del numerador de la base de calculo.
   * @param pMonth  Mes a obtener el numero de dias.
   * @param pYear  Anio a  obtener el numero de dias.
   * @return
   * @throws Exception
   */
	public int getMonthDays(int pMonth, int pYear) throws Exception {
		if (this.days == 1) {
			GregorianCalendar cal = new GregorianCalendar();
			cal.setTime(new Date());
			cal.set(Calendar.YEAR, pYear);
			cal.set(Calendar.MONTH, pMonth);
			cal.set(Calendar.DATE, 1);
			return cal.getMaximum(Calendar.DATE);
		} else {
			return this.days;
		}
	}
	
  /**
   * Entrega el  numero de dias de una anio.
   * @param pYear 
   * @return
   * @throws Exception
   */
	public int getYearDays(int pYear) throws Exception {
		if (this.days == -1) {
			GregorianCalendar cal = new GregorianCalendar();
			cal.setTime(new Date());
			cal.set(Calendar.YEAR, pYear);
			cal.set(Calendar.MONTH, Calendar.JANUARY);
			cal.set(Calendar.DATE, 1);
			return cal.getMaximum(Calendar.DAY_OF_YEAR);
		} else {
			return this.days;
		}
	}
  
  /**
   * Entrega el codigo de la base de calculo.
   * @return	String
   * @throws Exception
   */
	public String getBaseCode() throws Exception{
		return this.baseCode;
	}
  
  /**
   * Entrega los dias mes de la base de calculo.
   * @return  int
   * @throws Exception
   */
	public int getMonthBase() throws Exception{
	  return this.monthBase;
	}
  
  /**
   * Entrega el numero de dias de la base de calculo. Si la base mes es 365 entrega 1.
   * @return this.days
   * @throws Exception
   */
  public int getDay() throws Exception{
    return days;
  }
  
  /**
   * Entrega CalculationBase dada la base de calculo.
   * @param pBase   Base de calculo 360/360,  360/365,  365/360,  365/365.
   * @return  CalculationBase
   * @throws Exception
   */
  public static CalculationBase getCalculationBase(String pBaseCode) throws Exception{
    CalculationBase [] ct = null; 
    ct = CalculationBase.values();
    CalculationBase  ctype = null; 
    for(CalculationBase obj : ct){
      if(obj.baseCode.compareTo(pBaseCode) == 0){
        ctype =  obj;
      }
    }
    return ctype;    
  }

}
