package Sprites;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;


public abstract class Sprite {
	protected BufferedImage bImage;
	protected int imageWidth, imageHeight; // image dimensions
    protected URL imagePath;
	protected int locX, locY;
	protected int acceleration;
	protected int pWidth, pHeight;  // panel's dimensions
	protected int sWidth, sHeight;

	protected double angle;


	public Sprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight)
	{
		this.imagePath = getClass().getResource("/Images/"+imgName);
        this.sWidth = sWidth;
		this.sHeight = sHeight;
		locX = x;
		locY = y;
		acceleration = acc;
		pWidth = w;
		pHeight = h;
		this.angle = angle;

		//load image from source files
		try {
			bImage = ImageIO.read(imagePath);
		}catch (IOException pin){
			pin.printStackTrace();
			bImage = null;
		}

		setImageDimensions();
	}


	/*
	 * resizes image to a set size
	 */
	protected void setImageDimensions()
	{
		Image tmp = bImage.getScaledInstance(sWidth, sHeight, Image.SCALE_SMOOTH);
		BufferedImage bi = new BufferedImage(sWidth, sHeight, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2d = bi.createGraphics();
		g2d.drawImage(tmp,0,0,null);
		g2d.dispose();	
		bImage = toCompatibleImage(bi);
	}
	
	/**
	 * Abstract method to update sprite.
	 */
	public abstract void update();

	/**
	 * returns sprite x position
	 * @return
	 * double
	 */
	public double getLocX() {return locX;}
	
	/**
	 * returns sprite y position
	 * @return
	 * double
	 */
	public double getLocY() {return locY;}

	/**
	 * returns sprite image width
	 * @return
	 * int
	 */
	public int getSWidth() {return sWidth;}

	/**
	 * returns sprite image height
	 * @return
	 * int
	 */
	public int getsHeight() {return sHeight;}

	/**
	 * returns sprite acceleration
	 * @return
	 * int
	 */
	public int getAcceleration() {return acceleration;}
	
	/**
	 * returns sprite size
	 * @return
	 * int
	 */
	public BufferedImage getbImage() {return bImage;}
	
	/**
	 * returns image width
	 * @return
	 * int
	 */
	public int getImageWidth() {return imageWidth;}
	
	/**
	 * returns image height
	 * @return
	 * int
	 */
	public int getImageHeight() {return imageHeight;}
	
	/**
	 * returns sprite angle
	 * @return
	 * double
	 */
	public double getAngle() {return angle;}
	

	
	/**
	 * returns shape location and dimensions as a Rectangle.
	 * @return
	 * Rectangle
	 */
	public Rectangle getBounds() {
		return new Rectangle((int)locX, (int)locY, sWidth, sHeight);
		}

	
	/**
	 * its not a bug it's  a feature. actually it just moves a shape that goes beyond the screen to the other side.
	 */
//	protected void outOfScreeFix(){
//		if(locX < 0 - sWidth)
//			locX = pWidth;
//		else if (locX > pWidth+sWidth)
//			locX = 0-sWidth;
//
//		if(locY < 0 - sHeight)
//			locY = pHeight;
//		else if(locY > pHeight+sHeight)
//			locY = 0-sHeight ;
//	}

	/**
	 * abstract method for drawing sprite.
	 * @param g
	 * @param p
	 */
	public void drawSprite(Graphics g, JPanel p){
		Graphics2D g2d = (Graphics2D)g;
		g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth()/2), locY + (bImage.getHeight()/2));
		g.drawImage(bImage, locX, locY, p);
		g2d.rotate(-1*Math.toRadians(angle), locX + (bImage.getWidth()/2), locY + (bImage.getHeight()/2));

	}

	private BufferedImage toCompatibleImage(BufferedImage image)
	{
		// obtain the current system graphical settings
		GraphicsConfiguration gfx_config = GraphicsEnvironment.
				getLocalGraphicsEnvironment().getDefaultScreenDevice().
				getDefaultConfiguration();

	/*
	 * if image is already compatible and optimized for current system
	 * settings, simply return it
	 */
		if (image.getColorModel().equals(gfx_config.getColorModel()))
			return image;

		// image is not optimized, so create a new image that is
		BufferedImage new_image = gfx_config.createCompatibleImage(
				image.getWidth(), image.getHeight(), image.getTransparency());

		// get the graphics context of the new image to draw the old image on
		Graphics2D g2d = (Graphics2D) new_image.getGraphics();

		// actually draw the image and dispose of context no longer needed
		g2d.drawImage(image, 0, 0, null);
		g2d.dispose();

		// return the new optimized image
		return new_image;
	}

}
