package helowars;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

/**
 * For animating objects such as explosions, smoke, propellers etc
 * @author Adarshkumar Pavani
 */

public class Animation {

    //image width and height
    private int frameWidth, frameHeight;

    //animation image
    private BufferedImage animImage;

    // Number of frames in the animation image
    private int numberOfFrames;

    // duration of once frame in millisecs
    private long frameTime;

    // time of displaying the starting frame
    private long startingFrameTime;

    // time to show next frame
    private long timeForNextFrame;

    // current frame number.
    private int currentFrameNumber;

    // if animation has to be kept looping
    private boolean loop;

    //x and y screen coordinates to render animation
    public int x, y;


    // starting and ending x coordinate of the current frame in the animation image.
    private int startingXOfFrameInImage, endingXOfFrameInImage;

    // flag to check end of animation
    public boolean active;
    
    // delay between start and rendering of animation AND time of creation
    private long showDelay, timeOfAnimationCreation;

    /**
     * Constructor for animation.
     * 
     * @param animImage Image of animation.
     * @param frameWidth Width of the animation frame
     * @param frameHeight Height of the animation frame
     * @param numberOfFrames Number of frames in the animation image.
     * @param frameTime duration of displaying each frame (in millisecs)
     * @param loop true if the animation has to be looped around, false otherwise
     * @param x x coordinate of the animation to be rendered on the screen
     * @param y y coordinate of the animation to be rendered on the screen
     * @param showDelay time (in millisecs) after which the animation should begin
     */
    public Animation(BufferedImage animImage, int frameWidth, int frameHeight, int numberOfFrames, long frameTime, boolean loop, int x, int y, long showDelay)
    {
        this.animImage = animImage;
        this.frameWidth = frameWidth;
        this.frameHeight = frameHeight;
        this.numberOfFrames = numberOfFrames;
        this.frameTime = frameTime;
        this.loop = loop;

        this.x = x;
        this.y = y;
        
        this.showDelay = showDelay;
        
        timeOfAnimationCreation = System.currentTimeMillis();

        startingXOfFrameInImage = 0;
        endingXOfFrameInImage = frameWidth;

        startingFrameTime = System.currentTimeMillis() + showDelay;
        timeForNextFrame = startingFrameTime + this.frameTime;
        currentFrameNumber = 0;
        active = true;
    }


    /**
     * To check if it's time to show next frame of the animation or if the animation is finished
     */
    private void Update()
    {
        if(timeForNextFrame <= System.currentTimeMillis())
        {
            // Next frame.
            currentFrameNumber++;

            //resetting the current frame to zero to restart the animation
            if(currentFrameNumber >= numberOfFrames)
            {
                currentFrameNumber = 0;

                // setting active to false if the animation is not in the loop
                if(!loop)
                    active = false;
            }

            // getting thr required frame from the animation image
            startingXOfFrameInImage = currentFrameNumber * frameWidth;
            endingXOfFrameInImage = startingXOfFrameInImage + frameWidth;

            // Set time for the next frame.
            startingFrameTime = System.currentTimeMillis();
            timeForNextFrame = startingFrameTime + frameTime;
        }
    }
    
    /**
     * to change the x & y coordinates of the animation
     */
    public void changeCoordinates(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    /**
     * to render current frame of the animation.
     * @param g2d Graphics2D
     */
    public void Draw(Graphics2D g2d)
    {
        this.Update();
        
        // checking if delay is over.
        if(this.timeOfAnimationCreation + this.showDelay <= System.currentTimeMillis())
            g2d.drawImage(animImage, x, y, x + frameWidth, y + frameHeight, startingXOfFrameInImage, 0, endingXOfFrameInImage, frameHeight, null);
    }
}