/**
 * Bird.java
 * Handles bird's state and actions
 *
 * @author  Paul Krishnamurthy
 */

package com.example.flappybird;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.Random;

public class Bird extends HasPosition {

	// Bird attributes
	public String color;
	private boolean isAlive = true;
	
	// Bird constants
	private int FLOAT_MULTIPLIER = -1;
	public final int BIRD_WIDTH = 44;
	public final int BIRD_HEIGHT = 31;
	private final int BASE_COLLISION = 521 - BIRD_HEIGHT - 5;

    // Physics variables
	private double velocity = 0;
	private final double gravity = .41;
	private double delay = 0;

    // Bird sprites
	private final BufferedImage[] sprites;

	// Track current frame
	private static double currentFrame = 0;

	public Bird (int x, int y) {
		super(x, y);

		Random rand = new Random();
		String[] birds = new String[] {
				"yellow",
				"blue",
				"red"
		};

		// Random bird color
		String randomBird = birds[rand.nextInt(3)];
		this.color = randomBird;
		this.sprites = new BufferedImage[] {
				FlappyBird.textures.get(randomBird + "Bird1").getImage(),
				FlappyBird.textures.get(randomBird + "Bird2").getImage(),
				FlappyBird.textures.get(randomBird + "Bird3").getImage()
		};
	}

	/**
	 * @return If bird is alive
	 */
	public boolean isAlive() {
		return isAlive;
	}

	/**
	 * Kills bird
	 */
	public void killBird() {
		isAlive = false;
	}

	/**
	 * Set new coordinates when starting game
	 */
	public void setGameStartPos () {
        x = 90;
        y = 343;
	}

	/**
	 * Floating bird effect on menu screen
	 */
	public void menuFloat () {
		y += FLOAT_MULTIPLIER;

		// Change direction within floating range
		if (y < 220) {
			FLOAT_MULTIPLIER *= -1;
		} else if (y > 280) {
			FLOAT_MULTIPLIER *= -1;
		}

	}

	/**
	 * Bird jump
	 */
	public void jump () {
		if (delay < 1) {
            int SHIFT = 10;
            velocity = -SHIFT;
			delay = SHIFT;
		}
	}

	/**
	 * Bird movement during the game
	 */
	public void moveBird() {
		// Change and velocity
		velocity += gravity;

		// Lower delay if possible
		if (delay > 0) { delay--; }

		// Add rounded velocity to y-coordinate
		y += (int) velocity;
	}

	public boolean collidesWithBase() {
		return y >= BASE_COLLISION;
	}

	/**
	 * Renders bird
	 */
	public void paintBird(Graphics g) {
		// Calculate angle to rotate bird based on y-velocity
        double rotation = ((90 * (velocity + 25) / 25) - 90) * Math.PI / 180;
		
		// Divide for clean jump
		rotation /= 2;

		// Handle rotation offset
		rotation = Math.min(rotation, Math.PI / 2);

		if (!isAlive()) {

			// Drop bird on death
			if (y < BASE_COLLISION - 10) {
				velocity += gravity;
				y += (int) velocity;
			}

		}

		// Create bird animation and pass in rotation angle
		animateBird(g, rotation);
	}

	private void animateBird(Graphics g, double angle) {
		Graphics2D g2d = (Graphics2D) g;
		AffineTransform trans = g2d.getTransform();
		AffineTransform at = new AffineTransform();

		// Number of frames
		int count = sprites.length;

		// Rotate the image
		at.rotate(angle, x + 25, y + 25);
		g2d.transform(at);

		// Draw the current rotated frame
		g2d.drawImage(sprites[(int) (Math.round(currentFrame))], x, y, null);

		g2d.setTransform(trans);

		// Switch animation frames
		if (currentFrame >= count - 1) {
			currentFrame = 0;
		}
		else {
			currentFrame += 0.09;
		}
	}
}
