/*******************************************************************************
 * Copyright © 2010 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.common.model.financials;

import gov.va.med.fw.model.AbstractKeyedEntity;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.time.DateUtils;

/**
 * Represents an income year paired with a percentage to be used in Financial
 * calculations for veterans.
 * 
 * @author DNS   barryc
 */
public class RelaxationPercentage extends AbstractKeyedEntity {
    private static final long serialVersionUID = -3985020019182988848L;

    // ----------------------------------------- Fields

    /**
     * The percentage from 1-100 (see getDisplayValue() for display and
     * getMultiplicand() for calculations)
     */
    private BigDecimal value;

    /**
     * The four-digit income year (must be greater than or equal to
     * MINIMUM_INCOME_YEAR)
     */
    private int incomeYear;

    /**
     * The first day of the incomeYear, for reference
     */
    private Date referenceStartDate;

    /**
     * The last day of the incomeYear, for reference
     */
    private Date referenceEndDate;

    // ----------------------------------------- Constructors

    /**
     * Default constructor, package-protected only for use by ORM
     */
    RelaxationPercentage() {
    }

    /**
     * Field-based constructor.
     * 
     * @param value
     *            The percentage value, which may not be negative or greater
     *            than MAXIMUM_VALUE
     * @param incomeYear
     *            The four-digit income year, which may not be less than
     *            MINIMUM_INCOME_YEAR
     */
    public RelaxationPercentage(BigDecimal value, int incomeYear) {
        this.value = value;
        this.incomeYear = incomeYear;
        resetReferenceDatesBasedOnIncomeYear();
    }

    // ----------------------------------------- Business Methods

    private void resetReferenceDatesBasedOnIncomeYear() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, incomeYear + 1);
        c.set(Calendar.DAY_OF_YEAR, c.getActualMinimum(Calendar.DAY_OF_YEAR));
        c = DateUtils.truncate(c, Calendar.DATE);
        referenceStartDate = c.getTime();
        c.set(Calendar.DAY_OF_YEAR, c.getActualMaximum(Calendar.DAY_OF_YEAR));
        c = DateUtils.truncate(c, Calendar.DATE);
        referenceEndDate = c.getTime();
    }

    /**
     * @return The "value" field appended with a percent sign
     */
    public String getValueForDisplay() {
        return value.toString() + "%";
    }

    /**
     * The "value" field of the parent class contains the percentage (such as
     * 14.56%). To use this number in a calculation, one must first divide it by
     * 100. This method does that with no loss of precision.
     * 
     * @return The stored value divided by 100 for use in calculations
     */
    public BigDecimal getMultiplicand() {
        return value.movePointLeft(2);
    }

    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.fw.model.AbstractKeyedEntity#buildToString(org.apache.commons.lang.builder.ToStringBuilder)
     */
    protected void buildToString(ToStringBuilder builder) {
        builder.append("incomeYear", incomeYear).append("value",
                getValueForDisplay()).append("referenceStartDate",
                referenceStartDate)
                .append("referenceEndDate", referenceEndDate);
    }

    // ----------------------------------------- Accessor Methods

    public int getIncomeYear() {
        return incomeYear;
    }

    public void setIncomeYear(int incomeYear) {
        this.incomeYear = incomeYear;
        resetReferenceDatesBasedOnIncomeYear();
    }

    public Date getReferenceEndDate() {
        return referenceEndDate;
    }

    protected void setReferenceEndDate(Date referenceEndDate) {
        this.referenceEndDate = referenceEndDate;
    }

    public Date getReferenceStartDate() {
        return referenceStartDate;
    }

    protected void setReferenceStartDate(Date referenceStartDate) {
        this.referenceStartDate = referenceStartDate;
    }

    public BigDecimal getValue() {
        return value;
    }

    public void setValue(BigDecimal value) {
        this.value = value;
    }

}