/*
 * Star.java
 *
 * This is a passive model, and this model does very little by itself. The
 * CollisionController does most of the hard work.
 *
 * Based on the original Optimization Lab by Don Holden, 2007
 *
 * @author: Walker M. White
 * @version: 2/2/2025
 */
package edu.cornell.cis3152.optimization.entity;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.JsonValue;
import edu.cornell.gdiac.graphics.*;
import edu.cornell.gdiac.util.RandomGenerator;

/**
 * Model class for stars caused by shell explosions.
 */
public class Star extends GameObject {
    /// CONSTANTS (defined by the JSON file)
    /** Mean life-expectancy of a star */
    private static int meanAge;
    /** The variance in life-expectancy */
    private static int ageRange;

    /** The minimum velocity offset (+ shell velocity) of a newly created star */
    private static float minOffset;
    /** The maximum velocity offset (+ shell velocity) of a newly created star */
    private static float maxOffset;
    /** The minimum velocity factor (x shell velocity) of a newly created star */
    private static float minFactor;
    /** The maximum velocity factor (x shell velocity) of a newly created star */
    private static float maxFactor;

    // ATTRIBUTES (per object)
    /** Current age of star.  Deleted when reach 0. */
    private int age;
    /** Current angle of star, as they can rotate */
    private float angle;

    /**
     * Returns the type of this object.
     *
     * We use this instead of runtime-typing for performance reasons.
     *
     * @return the type of this object.
     */
    public ObjectType getType() {
        return ObjectType.STAR;
    }

    /**
     * Returns the current angle of this star
     *
     * @return the current angle of this star
     */
    public float getAngle() {
        return angle;
    }

    /**
     * Defines the constants for this class.
     *
     * Constants are values shared across all instances. Instead of defining
     * them above, we define them a JSON file. This static method initializes
     * the value from this file.
     *
     * @param constants The JSON value with constants
     */
    public static void setConstants(JsonValue constants) {
        meanAge = constants.getInt("mean age", 0);
        ageRange = constants.getInt("age range", 0);
        JsonValue offsets = constants.get("offset range");
        JsonValue factors = constants.get("factor range");

        minOffset = offsets.getFloat(0);
        maxOffset = offsets.getFloat(1);
        minFactor = factors.getFloat(0);
        maxFactor = factors.getFloat(1);
    }

    /**
     * Creates a star with the given starting position.
     *
     * Any parameters other than position should be derived from the JSON
     * value of constants. See {@link #setConstants}.
     *
     * @param x The x-coordinate of the object
     * @param y The y-coordinate of the object
     */
    public Star(float x, float y) {
        super(x,y);

        // Stars die over time
        age = RandomGenerator.getInt(meanAge - ageRange, meanAge + ageRange);
    }

    /**
     * Initializes the velocity of this star relative to another object
     *
     * Stars are created on destruction of another object. We use the velocity
     * of that object to define the velocity of a star.
     *
     * @param vx    The x-component of the velocity seed
     * @param vy    The y-component of the velocity seed
     */
    public void initVelocity(float vx, float vy) {
        // Set a velocity with some random noise
        vx = vx * RandomGenerator.getFloat(minFactor,maxFactor)
            + RandomGenerator.getFloat(minOffset,maxOffset);
        vy = vy * RandomGenerator.getFloat(minFactor,maxFactor)
            + RandomGenerator.getFloat(minOffset,maxOffset);
        velocity.set(vx,vy);
    }

    /**
     * Updates the age and angle of this star.
     *
     * @param delta Number of seconds since last animation frame
     */
    public void update(float delta) {
        // Call superclass's update
        super.update(delta);

        // Decrease time until death; die if it's time
        if (--age == 0) {
            destroyed = true;
        }

        // Compute a new angle of rotation.
        angle = (float)(delta*1000 % (8 * Math.PI)); // MAGIC NUMBERS
    }


    /**
     * Draws this shell to the sprite batch
     *
     * There is only one drawing pass in this application, so you can draw the
     * objects in any order.
     *
     * @param batch The sprite batch
     */
    @Override
    public void draw(SpriteBatch batch) {
        SpriteBatch.computeTransform(transform, origin.x, origin.y,
            position.x, position.y, angle, 1.0f, 1.0f);

        batch.setColor( Color.WHITE );
        batch.draw(animator, transform);
    }

}
