//==============================================================================
//The Society of Actuaries (SOA) makes this computer model and its computer
//code available to its members for educational purposes. The model and its
//code may be modified and redistributed without prior authorization from the
//SOA. The SOA distributes this computer model and its computer code in the
//hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
//implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//PURPOSE.
//==============================================================================

package agents;

import repast.simphony.context.Context;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.parameter.Parameter;
import repast.simphony.ui.probe.ProbeID;
import resources.AgentID;
import resources.Constants;
import agents.Agent;

@SuppressWarnings("unused")
public class PremiumRateLimitAgency extends Agent
{

//==============================================================================
// Attribute variables
// These variables do not change during the agent's life (unless the user
// changes an attribute parameter during a simulation).
//------------------------------------------------------------------------------
    private double profitPercentageMaximum;

//==============================================================================


//==============================================================================
// Memory variables
// These variables can change during an agent's life.
// There are two types of memory variables:
// 1. Currently updated variables:  Variables that the agent updates during the
//    period to which they apply.
// 2. Previously updated variables:  Variables that the agent updates during the
//    period prior to the period in which they apply.
//------------------------------------------------------------------------------

    //Currently updated memory variables
    // 1. Variables from p1_SetPremiumIncreaseLimit()
    private double currentPremiumIncreaseLimit_PlanA1;
    private double currentPremiumIncreaseLimit_PlanA2;
    private double currentPremiumIncreaseLimit_PlanB1;
    private double currentPremiumIncreaseLimit_PlanB2;

    // 2. Previously updated memory variables
    private double nextCurrentPremiumIncreaseLimit_PlanA1;
    private double nextCurrentPremiumIncreaseLimit_PlanA2;
    private double nextCurrentPremiumIncreaseLimit_PlanB1;
    private double nextCurrentPremiumIncreaseLimit_PlanB2;

//==============================================================================


//==============================================================================
// Other variables
// These are other variables used in the class, or required by other classes.
//------------------------------------------------------------------------------
    private Context<Object> simulationContext;
    private double tickCount;

//==============================================================================


//==============================================================================
// Method:  PremiumRateLimitAgency() constructor
//------------------------------------------------------------------------------

    public PremiumRateLimitAgency(Context<Object> pContext, AgentID pPremiumRateLimitAgencyID)
    {

        setAgentID(pPremiumRateLimitAgencyID);
        simulationContext = pContext;

        init_InitializeVariables_Constructor();

    }//end PremiumRateLimitAgency()

//==============================================================================


//==============================================================================
// Methods: Initialization methods for the agent. These are used in
//          the agent's constructor method or at the beginning of each
//          simulation period.
//==============================================================================

//==============================================================================
// Method:  init_InitializeVariables_Constructor()
// The constructor does the following:
// 1. Initializes variables that remain constant throughout
//    an agent's life (unless the user changes parameters).
//    These are the agent's "attribute" variables.
// 2. Initializes the value of all other variables.
// This method gives a valid (non-null) value to all the agent's variables.
//------------------------------------------------------------------------------
    private void init_InitializeVariables_Constructor()
    {

        // 1. Initialize "attribute" variables.
        profitPercentageMaximum = Environment.getPremiumRateLimitAgency_ProfitPercentageMaximum();

        // 2. Provide the first-period "current" values for variables that
        // the agent does not set.
        // None

        // 2. Initialize the value of all other variables.
        currentPremiumIncreaseLimit_PlanA1 = 0.0;
        currentPremiumIncreaseLimit_PlanA2 = 0.0;
        currentPremiumIncreaseLimit_PlanB1 = 0.0;
        currentPremiumIncreaseLimit_PlanB2 = 0.0;

        nextCurrentPremiumIncreaseLimit_PlanA1 = 0.0;
        nextCurrentPremiumIncreaseLimit_PlanA2 = 0.0;
        nextCurrentPremiumIncreaseLimit_PlanB1 = 0.0;
        nextCurrentPremiumIncreaseLimit_PlanB2 = 0.0;

    }//end init_InitializeVariables_Constructor()
//------------------------------------------------------------------------------

//==============================================================================
// Method:  init_InitializeVariables_BOP() (beginning of period)
// This method does the following:
// 1. Updates attribute variables. If the user changes an attribute parameter
//    during a simulation, these may change.
// 2. Updates the prior period values of all variables (after the first period).
// 3. Provides "current" values for certain variables that the agent
//    does not set at the beginning of the period with a separate behavior.
//    This is done for those variables will be needed by behaviors of this agent
//    or by other agents during the period.
// 4. Re-initialize all CURRENT (NOT PRIOR) variables (except those that would cause
//    display or chart problems (flickering, etc.).
// 5. removes agents that have died.
//------------------------------------------------------------------------------
    public void init_InitializeVariables_BOP()
    {

        // 1. Update attribute variables.
        profitPercentageMaximum = Environment.getPremiumRateLimitAgency_ProfitPercentageMaximum();

        // 2. Update prior period values of all variables (after the first period).
        // None

        // 3. Provide "current" values for certain variables that the agent does not set at the
        //    beginning of the period with a separate behavior.
        tickCount = RunEnvironment.getInstance().getCurrentSchedule().getTickCount();
        if (tickCount < 1.0)
        {
            currentPremiumIncreaseLimit_PlanA1 = profitPercentageMaximum;
            currentPremiumIncreaseLimit_PlanA2 = profitPercentageMaximum;
            currentPremiumIncreaseLimit_PlanB1 = profitPercentageMaximum;
            currentPremiumIncreaseLimit_PlanB2 = profitPercentageMaximum;
        }//end if
        else
        {
            currentPremiumIncreaseLimit_PlanA1 = nextCurrentPremiumIncreaseLimit_PlanA1;
            currentPremiumIncreaseLimit_PlanA2 = nextCurrentPremiumIncreaseLimit_PlanA2;
            currentPremiumIncreaseLimit_PlanB1 = nextCurrentPremiumIncreaseLimit_PlanB1;
            currentPremiumIncreaseLimit_PlanB2 = nextCurrentPremiumIncreaseLimit_PlanB2;
        }//end if

        // 4. Re-initialize all CURRENT (NOT PRIOR) variables (except those that would cause
        //    display or chart problems (flickering, etc.).
        // currentPremiumIncreaseLimit_PlanA1 is initialized above
        // currentPremiumIncreaseLimit_PlanA2 is initialized above
        // currentPremiumIncreaseLimit_PlanB1 is initialized above
        // currentPremiumIncreaseLimit_PlanB2 is initialized above

        nextCurrentPremiumIncreaseLimit_PlanA1 = 0.0;
        nextCurrentPremiumIncreaseLimit_PlanA2 = 0.0;
        nextCurrentPremiumIncreaseLimit_PlanB1 = 0.0;
        nextCurrentPremiumIncreaseLimit_PlanB2 = 0.0;

        // 5. Remove agents that have died
        // None

    }//end init_InitializeVariables_BOP()
//------------------------------------------------------------------------------

//==============================================================================


//==============================================================================
// Methods:  "Input" methods for the agent. These are described in the
// detailed description of the model. Each method is preceded by "i#".
//==============================================================================

// None

//==============================================================================


//==============================================================================
// Methods:  "Process" methods for the agent. These are described in the
// detailed description of the model. Each method is preceded by "p#"
// to indicate its number according to the numbering scheme used in the
// detailed description.
//==============================================================================

//==============================================================================
// Method:  p1_SetPremiumIncreaseLimit()

//------------------------------------------------------------------------------
    public void p1_SetPremiumIncreaseLimit()
    {

        r1_DeterminePremiumIncreaseLimit();

    }//end p1_SetPremiumIncreaseLimit()
//------------------------------------------------------------------------------

//==============================================================================


//==============================================================================
// Methods:  "Rule" methods for the agent. These are described in the
// detailed description of the model. Each method is preceded by "r#"
// to indicate its number according to the numbering scheme used in the
// detailed description.
//==============================================================================

//==============================================================================
// Method:  r1_DeterminePremiumIncreaseLimit()
//------------------------------------------------------------------------------
    private void r1_DeterminePremiumIncreaseLimit()
    {
        if (Environment.getHealthInsuranceCompanyList().get(Constants.HEALTH_INSURANCE_COMPANY_A)
                .getCurrentProfitPercentage_Plan1() > profitPercentageMaximum)
        {
            nextCurrentPremiumIncreaseLimit_PlanA1 = 0.0;
        }//end if
        else nextCurrentPremiumIncreaseLimit_PlanA1 = profitPercentageMaximum;

        if (Environment.getHealthInsuranceCompanyList().get(Constants.HEALTH_INSURANCE_COMPANY_A)
                .getCurrentProfitPercentage_Plan2() > profitPercentageMaximum)
        {
            nextCurrentPremiumIncreaseLimit_PlanA2 = 0.0;
        }//end if
        else nextCurrentPremiumIncreaseLimit_PlanA2 = profitPercentageMaximum;

        if (Environment.getHealthInsuranceCompanyList().get(Constants.HEALTH_INSURANCE_COMPANY_B)
                .getCurrentProfitPercentage_Plan1() > profitPercentageMaximum)
        {
            nextCurrentPremiumIncreaseLimit_PlanB1 = 0.0;
        }//end if
        else nextCurrentPremiumIncreaseLimit_PlanB1 = profitPercentageMaximum;

        if (Environment.getHealthInsuranceCompanyList().get(Constants.HEALTH_INSURANCE_COMPANY_B)
                .getCurrentProfitPercentage_Plan1() > profitPercentageMaximum)
        {
            nextCurrentPremiumIncreaseLimit_PlanB2 = 0.0;
        }//end if
        else nextCurrentPremiumIncreaseLimit_PlanB2 = profitPercentageMaximum;

    }//end r1_DeterminePremiumIncreaseLimit()
//------------------------------------------------------------------------------

//==============================================================================


//==============================================================================
// Methods:  General methods for the agent.
//==============================================================================


//==============================================================================


//==============================================================================
//Methods: "Probe" methods for the model user to probe the agent's data.
//Note:    As a simulation runs, the model user can probe an agent by
//	       double-clicking on its icon in the display. For more information
//	       about probes, see the Repast Simphony reference documentation.
//==============================================================================

// The "ProbeID" annotation provides the probe ID
    @ProbeID
    public String getName()
    {
        return getAgentName();
    }

    @Parameter (usageName="profitPercentageMaximum", displayName="A1. Profit percentage maximum")
    public double getProfitPercentageMaximum()
    {
        return profitPercentageMaximum;
    }

    @Parameter (usageName="nextCurrentPremiumIncreaseLimit_PlanA1", displayName="B1. Next period premium increase limit - Plan A1")
    public double getNextCurrentPremiumIncreaseLimit_PlanA1()
    {
        return nextCurrentPremiumIncreaseLimit_PlanA1;
    }

    @Parameter (usageName="currentPremiumIncreaseLimit_PlanA1", displayName="B2. Current premium increase limit - Plan A1")
    public double getCurrentPremiumIncreaseLimit_PlanA1()
    {
        return currentPremiumIncreaseLimit_PlanA1;
    }

    @Parameter (usageName="nextCurrentPremiumIncreaseLimit_PlanA2", displayName="B3. Next period premium increase limit - Plan A2")
    public double getNextCurrentPremiumIncreaseLimit_PlanA2()
    {
        return nextCurrentPremiumIncreaseLimit_PlanA2;
    }

    @Parameter (usageName="currentPremiumIncreaseLimit_PlanA2", displayName="B4. Current premium increase limit - Plan A2")
    public double getCurrentPremiumIncreaseLimit_PlanA2()
    {
        return currentPremiumIncreaseLimit_PlanA2;
    }

    @Parameter (usageName="nextCurrentPremiumIncreaseLimit_PlanB1", displayName="B5. Next period premium increase limit - Plan B1")
    public double getNextCurrentPremiumIncreaseLimit_PlanB1()
    {
        return nextCurrentPremiumIncreaseLimit_PlanB1;
    }

    @Parameter (usageName="currentPremiumIncreaseLimit_PlanB1", displayName="B6. Current premium increase limit - Plan B1")
    public double getCurrentPremiumIncreaseLimit_PlanB1()
    {
        return currentPremiumIncreaseLimit_PlanB1;
    }

    @Parameter (usageName="nextCurrentPremiumIncreaseLimit_PlanB2", displayName="B7. Next period premium increase limit - Plan B2")
    public double getNextCurrentPremiumIncreaseLimit_PlanB2()
    {
        return nextCurrentPremiumIncreaseLimit_PlanB2;
    }

    @Parameter (usageName="currentPremiumIncreaseLimit_PlanB2", displayName="B8. Current premium increase limit - Plan B2")
    public double getCurrentPremiumIncreaseLimit_PlanB2()
    {
        return currentPremiumIncreaseLimit_PlanB2;
    }



//==============================================================================


//==============================================================================
// Methods:  "Analysis" methods to support simulation charts and graphs.
//==============================================================================

// None

//==============================================================================


//==============================================================================
// Methods:  getter and setter methods
//------------------------------------------------------------------------------


//==============================================================================


}//end PremiumRateLimitAgency class