package ps1;

import java.util.Vector;
import java.awt.Point;
import java.awt.Image;

class Background extends Sprite {
	Vector theSprites;

	//----------------------------------- Constructors -----------------------------------
	public Background () {
		/**	Requires:	nothing
			Modifies:	nothing
			Effects:	creates a new instance of <this>
		*/
		super();
		theSprites = new Vector();
	}

	public Background (Image background) {
		/**	Requires:	nothing
			Modifies:	nothing
			Effects:	creates a new instance of <this> with background image <background>
		*/
		super(background);
		theSprites = new Vector();
	}

	//-------------------------------------- Methods -------------------------------------
	public void addSprite (Sprite sprite) {
		/**	Requires:	nothing
			Modifies:	<this>
			Effects:	adds <sprite> to be animated in <this>
		*/
		theSprites.addElement(sprite);
		sprite.draw(this);
	}

	public void draw () {
		/**	Requires:	nothing
			Modifies:	<this>
			Effects:	draws all sprites contained in <this>, with the first added
						sprites drawn first (and all others overlap on top)
		*/
		//The sprites are drawn from first added to last added
		//clean off the background
		Raster myCleanSelf = getCleanCopyOfSelf();
		for (int i = 0; i < myCleanSelf.getWidth() * myCleanSelf.getHeight(); i++)	//this is completely clean
			this.pixel[i] = myCleanSelf.pixel[i];
		
		for (int i = 0; i < theSprites.size(); i++) {
			Object o = theSprites.elementAt(i);

			if (o instanceof AnimatedSprite)
				((AnimatedSprite)theSprites.elementAt(i)).draw(this);
			else
			if (o instanceof Sprite)
				((Sprite)theSprites.elementAt(i)).draw(this);
		}
	}

	public void drawAnimated () {
		/**	Requires:	nothing
			Modifies:	<this>
			Effects:	draws all sprites contained in <this>, with the first added
						sprites drawn first (and all others overlap on top)
		*/
		//clean off the background
		Raster myCleanSelf = getCleanCopyOfSelf();
		for (int i = 0; i < myCleanSelf.getWidth() * myCleanSelf.getHeight(); i++)	//this is completely clean
			this.pixel[i] = myCleanSelf.pixel[i];
				
		//The sprites are drawn from first added to last added
		for (int i = 0; i < theSprites.size(); i++) {
			Object o = theSprites.elementAt(i);

			//any animation happens here.
			if (o instanceof AnimatedSprite)
				((AnimatedSprite)theSprites.elementAt(i)).selfAnimate();
			else
			if (o instanceof Sprite)
				((Sprite)theSprites.elementAt(i)).draw(this);
		}
	}

	public Sprite getSpriteAtLocation (Point pt) 
		throws NoSpriteLocatableException {
		/**	Requires:	nothing
			Modifies:	nothing
			Effects:	if a sprite on <this> is not transparent at <pt> and within <this>,
						return the sprite.  Else, throw NoSpriteLocatableException.
		*/
		for (int i = theSprites.size(); i > 0; i--) {
			Sprite sprite = (Sprite)theSprites.elementAt(i - 1);
			
			Point spriteLocation = sprite.getLocation();
			
			try {
				int x = pt.x - spriteLocation.x;
				int y = pt.y - spriteLocation.y;

				if (!sprite.getTransparency(new Point(x, y)))
					return (sprite);	//returns the LAST sprite that is drawn on a location
			} catch (NoSpriteLocatableException e) {
			}
		}

		throw new NoSpriteLocatableException();
	}

	public void toTopOfZOrder (Sprite activatedSprite) {
		/**	Requires:	nothing
			Modifies:	<this>
			Effects:	if <activatedSprite> is located in this, make it the top of the
						ZOrder (so it's drawn on top of everyone else).  Else, does nothing

		*/
		int topLocation = theSprites.indexOf(activatedSprite);
		
		if (topLocation == -1)
			return;	//do nothing
		
		Sprite tempSprite = activatedSprite;
		theSprites.removeElementAt(topLocation);
		theSprites.addElement(tempSprite);
	}
}

class NoSpriteLocatableException extends Exception {
	public NoSpriteLocatableException () {super();}
	public NoSpriteLocatableException (String s) {super(s);}
}
