import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;

import javax.imageio.ImageIO;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class Projectile {
	int x;
	int y;
	int dx;
	int dy;

	Point centerOffset;
	int radius;

	byte currentAction;

	AudioInputStream audioIn; 
	Clip clip = null;

	final static byte MOVING = 2;

	BufferedImage projectileBufferedImage = null;
	byte frame_i = 0;
	long animationStartTime = 0;
	long frameYTranslationStartTime = 0;
	long frameXTranslationStartTime = 0;

	// moving
	long movingFrameDurationMillis = 50;
	final static byte movingFrames_n = 4;
	BufferedImage[] animationMovingFrames = null;

	static String SPRITE_SHEET_FILENAME = null;
	static String SOUND_FILENAME = null;

	BufferedImage projectileSheetBufferedImage;

	boolean destroyed = false;

	public Projectile (int x, int y, boolean direction, String sprite_sheet_filename, String sound_filename) {
		dx = direction ? -5 : 5;
		dy = 5;
		this.x = x;
		this.y = y;

		SPRITE_SHEET_FILENAME = sprite_sheet_filename;
		SOUND_FILENAME = sound_filename;

		Image projectileSheet = null;
		try {
			projectileSheet = ImageIO.read(new File(SPRITE_SHEET_FILENAME));
		} 
		catch (IOException e) {
			e.printStackTrace();
		}

		projectileSheetBufferedImage = (BufferedImage)projectileSheet;

		currentAction = MOVING;
		if (AnimalTestG.AUDIO) {
			File f = new File(SOUND_FILENAME);
			try {
				audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL());  
				clip = AudioSystem.getClip();
				clip.open(audioIn);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (UnsupportedAudioFileException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (LineUnavailableException e) {
				e.printStackTrace();
			}
			playSound();
		}
	}

	void playSound() {   
		clip.start();
		clip.setFramePosition(0);
	}

	public void move() {
		if (currentAction == MOVING) {
			long animationElapsedTime = System.currentTimeMillis() - animationStartTime;
			if (animationElapsedTime > movingFrameDurationMillis) {
				animationStartTime = System.currentTimeMillis();
				frame_i++;
			}
			if (frame_i == movingFrames_n) frame_i = 0;
			projectileBufferedImage = animationMovingFrames[frame_i];
			x += dx;
			if (radius < 8) radius++;
			if (x < -projectileBufferedImage.getWidth() || x > AnimalTestG.W) {
				destroyed = true;
			}
			Point center = new Point(x + centerOffset.x, y + centerOffset.y);
			for (Projectile p : AnimalTestG.projectiles) {
				if (p == this) continue;
				Point pCenter = new Point(p.x + p.centerOffset.x, p.y + p.centerOffset.y);
				if (distance(center, pCenter) <= p.radius + this.radius) {
					destroyed = true;
					p.destroyed = true;
				}
			}
		}
	}

	public void draw(Graphics g) {
		g.drawImage(projectileBufferedImage.getScaledInstance(64, -1, Image.SCALE_DEFAULT), x, y, null);
		//		g.setColor(Color.RED);
		//		g.drawOval(x + (int)centerOffset.x - radius, y + (int)centerOffset.y - radius, radius * 2, radius * 2);
	}

	protected BufferedImage flipImageOverVertical(BufferedImage image) {
		AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
		tx.translate(-image.getWidth(null), 0);
		AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
		BufferedImage flippedImage = op.filter(image, null);
		return flippedImage;
	}

	void drawString(Graphics g, int x, int y) {
		g.drawString("x: " + this.x, x, y += g.getFontMetrics().getHeight());
		g.drawString("y: " + this.y, x, y += g.getFontMetrics().getHeight());
		g.drawString("currentAction: " + currentAction, x, y += g.getFontMetrics().getHeight());
	}

	int distance(Point a, Point b) {
		return (int)(Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));
	}
	//
	//////////////////////////////////////
}