package com.example.flappybird; /**
 * Bird.java
 * Handles bird's state and actions
 *
 * @author  Paul Krishnamurthy
 */

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

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;
	private final int SHIFT           = 10;
	private final int STARTING_BIRD_X = 90;
	private final int STARTING_BIRD_Y = 343;
	
	// Physics variables
	private double velocity           = 0;
	private double gravity            = .41;
	private double delay              = 0;
	private double rotation           = 0;

	// Bird sprites
	private BufferedImage[] sprites;

	private static double currentFrame = 0;


	public Bird (String color, int x, int y, BufferedImage[] s) {
		super(x, y);
		this.color = color;
		this.sprites = s;
	}

	/**
	 * @return     Bird's x-coordinate
	 */
	public int getX () {
		return x;
	}

	/**
	 * @return     Bird's y-coordinate
	 */
	public int getY () {
		return y;
	}

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

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

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

	/**
	 * 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) {
			velocity = -SHIFT;
			delay = SHIFT;
		}

	}

	/**
	 * Bird movement during the game
	 */
	public void inGame () {

		// If the bird did not hit the base, lower it
		if (y < BASE_COLLISION) {

			// Change and velocity
			velocity += gravity;

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

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

		} else {

			// Play audio and set state to dead
			GamePanel.audio.hit();
			isAlive = false;
		}

	}

	/**
	 * Renders bird
	 */
	public void renderBird (Graphics g) {

		// Calculate angle to rotate bird based on y-velocity
		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;

	}
}
