//==============================================================================
// 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 styles;

//==============================================================================
//Import statements
//------------------------------------------------------------------------------
import implementation.SimulationUserPanel;

import java.awt.Color;
import java.awt.Font;
import agents.Person;
import repast.simphony.visualizationOGL2D.StyleOGL2D;
import resources.Constants.PlanTag;
import saf.v3d.ShapeFactory2D;
import saf.v3d.scene.Position;
import saf.v3d.scene.VSpatial;


public class PersonStyle implements StyleOGL2D<Person>
{
    private ShapeFactory2D shapeFactory;

//==============================================================================
// Method: These first methods implement the label methods of StyleOGL2D.
//------------------------------------------------------------------------------
    @Override
    public String getLabel(Person person)
    {
        boolean labelSwitch = SimulationUserPanel.isPersonLabels();  
        if (labelSwitch == true) return person.getPersonIDString();
        else return ""; 
    }

    @Override
    public Font getLabelFont(Person person)
    {
        return new Font("sansserif", Font.BOLD, 12);
    }

    @Override
    public float getLabelXOffset(Person person)
    {
        return 0;
    }

    @Override
    public float getLabelYOffset(Person person)
    {
        return 0;
    }

    @Override
    public Position getLabelPosition(Person person)
    {
        return Position.SOUTH;
    }

    @Override
    public Color getLabelColor(Person person)
    {
        return new Color (0, 0, 0); //Black
    }
//==============================================================================


//==============================================================================
// This method sets the shape of the icon representing the Person to a circle.
//------------------------------------------------------------------------------
    @Override
    public VSpatial getVSpatial(Person person, VSpatial spatial)
    {
        
         return shapeFactory.createCircle(5, 100);
    }

//==============================================================================
// This method sets the color of the disk representing the Person.
// The color is given by the triplet (Red, Green, Blue),
// where Red, Green, and Blue are integers between 0 and 255.
// Colors for Repast are represented in the standard Red/Green/Blue format.
//------------------------------------------------------------------------------
    @Override
    public Color getColor(Person person)
    {

        if (person.getCurrentDiseaseStatus() >= 10.0)
            return new Color (0, 0, 0); //Black
        else
        {        

            // Because the eye does not easily differentiate between reds at the
            // high end of the red spectrum, the shades are logarithmic with a 
            // base of 1.5.
            int greenBlue = (int) (Math.round((Math.pow(1.5,10.0) - Math.pow(1.5, person.getCurrentDiseaseStatus()))*(255.0/Math.pow(1.5, 10))));
            return new Color (255, greenBlue, greenBlue); //Shades of red

        }//end else
    }

//==============================================================================
// This method sets the size of the disk representing the Person.
// The higher the Person's income, the larger the disk.
//------------------------------------------------------------------------------
    @Override
    public float getScale(Person person)
    {
        double alpha = SimulationUserPanel.getMaximumIncome()/5.0;
        return (float) (0.50 + (person.getCurrentNetIncome()/alpha));
    }


//==============================================================================
// These methods set the disk border representing the Person.
// If the person is participating in the Exchange, the border is blue.
//------------------------------------------------------------------------------
    @Override
    public int getBorderSize(Person person)
    {
        if (person.isCurrentExchangeParticipationStatus() == true)
            return 5;
        else
        {
            return 2;
        }//end else
    }

    @Override
    public Color getBorderColor(Person person)
    {

        if (person.getCurrentPlanChosen() == PlanTag.PlanA1)
            return new Color (58, 102, 156); //Dark blue

        else if (person.getCurrentPlanChosen() == PlanTag.PlanA2)
            return new Color (58, 102, 156); //Dark blue

        else if (person.getCurrentPlanChosen() == PlanTag.PlanB1)
            return new Color (184, 88, 8); //Dark orange

        else if (person.getCurrentPlanChosen() == PlanTag.PlanB2)
            return new Color (245, 128, 31); //Dark orange

        else return new Color (120, 120, 120);   //Light grey
    }

//==============================================================================
// Method: These are general methods implementing StyleOGL2D.
//------------------------------------------------------------------------------
    @Override
    public void init(ShapeFactory2D shapeFactory)
    {
        this.shapeFactory = shapeFactory;
    }

    @Override
    public float getRotation(Person person)
    {
        return 0;
    }
    
}//end PersonStyle class