package com.AndroidInvaders2;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.graphics.*;
import android.content.*;
import java.util.*;
import android.util.Log;
import android.media.*;

// to do

// destroy startButton, etc. at end
// get actual buttons for this
// do shields
// list of highest scores and names
// teleport ???
// spray fire

public class AndroidInvaders2 extends Activity implements Runnable {
	// do NOT declare your game variables here!  Declare them in the View class
	MyView theView;
	Thread myThread;
	int threadDelay;
	boolean doLogging = false;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.main);
        threadDelay = 10;
        theView = new MyView(this);
        setContentView(theView); // R.layout.main);

        myThread = new Thread(this);
        myThread.start();

    } // end of method  public void onCreate(Bundle savedInstanceState) 

    public void onStop()
    {
    	super.onStop();
    	if (doLogging)
    		Log.i("tag","onStop is called");
    	myThread.stop();
    	myThread = null;
    	
    	// save the locations of all objects, level, etc. so that we can recreate the game

    }  // end of method public void onStop()
    
    public void run()
    {
    	while (true)
    	{
    		try
    		{
    			Thread.sleep(threadDelay);
    			//theView.invalidate(); don't use this unless you are on the main thread
    			theView.postInvalidate();
    			//theView.removeUnusedMusicPlayers();
    		}
    		catch (Exception e)
    		{
    			break;
    		}

    	}
    	theView.removeUnusedMusicPlayers();
    	if (doLogging)
    		Log.i("tag","run is stopping");

    }  // end of method public void run()

    // ***********************************************************************
    // View class
    // ***********************************************************************
    // declare all of your view objects (ship, aliens, bullets, explosions, etc. here)
    private static class MyView extends View // implements android.media.MediaPlayer.OnCompletionListener
    {   
    	boolean       testing = false;
    	boolean       useExplosions = true;
    	boolean       useMediaPlayersList = false;
    	final int     MAX_MUSIC_PLAYERS = 10;
    	boolean       playSound = true;
    	boolean       doLogging = false;
    	
    	// declare all of your game constants here	
    	final int     beginValueForChanceOfNewAlien = 250;
    	final int     maxLevels = 10;
    	final int     localThreadDelay = 10; // this should be the same as the global variable threadDelay
    	final int     maxTimeAllowedForNewAlien = 2000;
    	final int     shipBeginPointsForAlienHit = 20;
    	final int     shipBeginPointsForAlienOffScreen = -1;
    	final int     explosionTimeOnScreen = 50;
    	final int     alienStartSpeed = 1;
    	final int     alienBulletStartSpeed = 2;

    	
    	// declare all of your game variables here	
    	boolean firstTime; // indicates that this is the beginning of a run 
    	boolean initSetup; // when the game is over and we have to initialize the setup again
    	
    	boolean dragging;
    	float   startMouseDragX;
    	float   startMouseDragY;
    	
    	int     width = 0;  // width of screen   (set inside of onDraw() method)
    	int     height = 0; // height of screen
 
    	int     chanceOfNewAlien;
    	int     timeSinceLastNewAlien;
    	int     chanceOfAlienFiring;
    	
    	int     level;
    	
    	boolean gameOver;
    	boolean gameOverScreen;
    	boolean introScreen;
    	
    	boolean shipCanFire;
    	int     shipPointsForAlienHit;
    	int     shipPointsForAlienOffScreen;
    	int     shipScore;
    	int     shipWins;
    	int     shipLosses;
    	
    	int     shipId;
    	String  shipFilename;
    	int     shipBulletId;
    	String  shipBulletFilename;
    	int     shipBulletSpeed;
    	
    	int     alienId;
    	String  alienFilename;
    	int     alienBulletId;
    	String  alienBulletFilename;
    	boolean alienCanFire;
    	int     alienSpeed;
    	int     alienBulletSpeed; // the speed should always be faster than the alien
    	
    	int     explosionId;
    	String  explosionFilename;
    	    	
    	// declare all your objects here
    	
    	// declare an ArrayList to hold aliens
    	ArrayList <MovableObject> alienList;
    	
    	// declare an ArrayList to hold alien bullets
    	ArrayList <MovableObject> alienBulletList;
    	
    	// declare an ArrayList to hold ship bullets
       	ArrayList <MovableObject> shipBulletList;

       	
    	// declare an ArrayList to hold explosions
       	ArrayList <MovableObject> explosionList;

    	ArrayList <MediaPlayer> mediaPlayers;

    	// this is the ship that you will control
    	MovableObject ship;
    	
    	MovableObject startButton;
    	MovableObject soundButton;
    	MovableObject levelButton;
    	
    	Context thisContext;
    	
    	public MyView(Context context)
    	{
    		super(context);
    		thisContext = context;
    		
    		firstTime = true;
    		initSetup = false;
    	    gameOver = true; 
    	    introScreen = true;
    	    gameOverScreen = false;
    	    shipCanFire = false;
    	    
    	    chanceOfNewAlien = beginValueForChanceOfNewAlien;
    	    timeSinceLastNewAlien = 0;
    	    
    	    level = 0; 

    		// new all of your ArrayList objects
    	    alienList = new ArrayList<MovableObject>(30);
    	    alienBulletList = new ArrayList<MovableObject>(200);
       	    shipBulletList = new ArrayList<MovableObject>(200);
       	    explosionList = new ArrayList<MovableObject>(20);
     	      
       	    mediaPlayers = new ArrayList<MediaPlayer>(20);
       	    
			// create some MediaPlayer objects with the sound
       	    
       	    if (useMediaPlayersList && useExplosions)
       	    {
       	    	for (int i=0; i<MAX_MUSIC_PLAYERS; i++)
       	    	{
       	    		MediaPlayer mp = MediaPlayer.create(thisContext, R.raw.explosion);
       	    		//mp.setLooping(true);
       	    		//mp.
       	    		mediaPlayers.add(mp);       	    	
       	    	}
       	    }

    	    dragging = false;
    	    startMouseDragX = -1;
    	    startMouseDragY = -1;
    	    
    	    // Create all of your beginning objects

    	    shipFilename = "ship.png";
    	    shipId = R.drawable.ship;

    	    shipBulletId = R.drawable.bullet;
        	shipBulletFilename = "bullet.png";
        	shipBulletSpeed = 5;
        	shipPointsForAlienOffScreen = shipBeginPointsForAlienOffScreen;
        	
        	alienId = R.drawable.alien;
        	alienFilename = "alien.png";
        	alienBulletId = R.drawable.bulletgood;
        	alienBulletFilename = "bulletgood.png";
        	alienCanFire = false;
        	alienSpeed = alienStartSpeed;
        	chanceOfAlienFiring = 0;
        	alienBulletSpeed = alienBulletStartSpeed;
        	
        	explosionId = R.drawable.explosion;
        	explosionFilename = "explosion.png";
        	
    	    // create your ship
    	    ship = new MovableObject(shipFilename,shipId,150,200,71,71);
    	    shipScore = 0;
    	    shipPointsForAlienHit = 20;
    	    shipWins = 0;
    	    shipLosses = 0;
    	    // read in values from a file here

    	    
       	    // create your aliens and add them to the alienList
    	    MovableObject alien = new MovableObject(alienFilename,alienId,50,-100,71,71);
    	    alien.setSpeedXY(alienSpeed, alienSpeed);
    	    alienList.add(alien);
    	    
    	    alien = new MovableObject(alienFilename,alienId,250,-100,71,71);
    	    alien.setSpeedXY(alienSpeed, alienSpeed);
    	    alienList.add(alien);
    	    
    	    startButton = new MovableObject("icon.png",R.drawable.icon,50,280,71,71);
    	    soundButton = new MovableObject("icon.png",R.drawable.icon,150,280,71,71);
    	    levelButton = new MovableObject("icon.png",R.drawable.icon,250,280,71,71);
    	    
    	}
    	
    	/*
    	public void onCompletion (MediaPlayer mp)
    	{
    		
    	}
    	*/
    	
    	public void playAvailableMusicPlayer()
    	{
    		if (!playSound)
    			return;
       	    if (useMediaPlayersList  && useExplosions)
       	    {
    		
       	    	for (int i=0; i < mediaPlayers.size(); i++)
       	    	{

       	    		if (!mediaPlayers.get(i).isPlaying())
       	    		{
       	    			//mediaPlayers.get(i).reset(); this causes a problem
       	    			//mediaPlayers.get(i).s
       	    			// nope keeps playing mediaPlayers.get(i).setLooping(true);
       	    			try
       	    			{
       	    				mediaPlayers.get(i).start();
       	    				return;
       	    			}
       	    			catch (Exception ee)
       	    			{
       	  
       	    			}
       	    		}
       	    	}
   			
       	    }	
       	    else if (useExplosions)
       	    {
       	    	try
       	    	{
       	    		MediaPlayer mp = MediaPlayer.create(thisContext, R.raw.explosion);
       	    		//mp.setLooping(true); nope causes error loops forever
       	    		//mp.
       	    		mp.start();
       	    		mediaPlayers.add(mp);
       	    	}
       	    	catch(Exception e)
       	    	{
       	    		
       	    	}
    	    	// mp.isPlaying()
    	    	// mp.reset();
    	    	//mp.setOnCompletionListener(thisContext);
    	    	
    	    	// mediaPlayers.add(mp);
       	    }

    	}

    	public void removeUnusedMusicPlayers()
    	{
    		if (!useMediaPlayersList  && useExplosions)
    		{
     		for (int i=0; i < mediaPlayers.size(); i++)
    		{

    			if (!mediaPlayers.get(i).isPlaying())
    			{
    				try
    				{
    					mediaPlayers.get(i).release();
    					mediaPlayers.remove(i);
    					i--;
    				}
    				catch (Exception e)
    				{
    					
    				}
    			}
    		}
    		}
   		
    	}

        public boolean onTouchEvent(MotionEvent e)
        {
        	float x = e.getX();
        	float y = e.getY();
        	
        	//if (introScreen)
        	//	gameOver = false;
        	//if (gameOverScreen)
        	//	gameOver = false;
        	
        	//e.ACTION_MOVE
        	if (e.getAction() == MotionEvent.ACTION_DOWN) // a finger touches the screen
        	{
        		if (doLogging)
        			Log.i("tag","inside ACTION_DOWN x="+x+"  y="+y);
        		startMouseDragX = x;
    			startMouseDragY = y;
			  	if (ship==null)
  					return true;
    			if (ship.getRect().contains(x,y))
    			{
    				if (doLogging)
    					Log.i("tag","inside ACTION_DOWN contains x and y");
     				dragging = true;
    			}
        	}
        	else if (e.getAction() == MotionEvent.ACTION_MOVE) // the finger is moving
        	{
    			float xPos = e.getX();
    			float yPos = e.getY();
    			if (doLogging)
    				Log.i("tag","inside ACTION_MOVE x="+xPos+"  y="+yPos);
 				if (ship==null)
  					return true;
    
    			boolean allowDragging = true;

    			if (xPos < 0)
    				allowDragging = false;
    			else if (xPos >= width)
    				allowDragging = false;
    			if (yPos < 0)
    				allowDragging = false;
    			else if (yPos >= height)
    				allowDragging = false;
    			if (doLogging)
    				Log.i("tag","inside width="+width+"  height="+height+"  "+allowDragging+dragging);
    			if (doLogging)
    				Log.i("tag","inside ship width="+ship.getWidth()+"  height="+ship.getHeight());
    			if (doLogging)
    				Log.i("tag","inside ship x="+ship.getX()+"  y="+ship.getY());

    			if ( dragging && allowDragging && (ship!=null) && 
    	 			(ship.getX()>-1) && (ship.getX()+ship.getWidth()<width)
    	 			&& (ship.getY() > -1) && (ship.getY()+ship.getHeight()<height)
       				)
    			{
    				if (doLogging)
    					Log.i("tag","inside dragging dragging width="+width+"  height="+height);
    				float distanceX;
    				float distanceY;
    				float newX=ship.getX();
    				float newY=ship.getY();
    				boolean shipMoved = false;

    				if (xPos < startMouseDragX)
    				{
    					distanceX = startMouseDragX - xPos;
    					newX = ship.getX() - distanceX;
    					shipMoved = true;
    				}
    				else if (xPos > startMouseDragX)
    				{
    					distanceX = xPos - startMouseDragX;
    					newX = ship.getX() + distanceX;
    					shipMoved = true;
    				}
 
    				if (yPos < startMouseDragY)
    				{
    					distanceY = startMouseDragY - yPos;
    					newY = ship.getY() - distanceY;
    					shipMoved = true;
    				}
    				else if (yPos > startMouseDragY)
    				{
    					distanceY = yPos - startMouseDragY;
    					newY = ship.getY() + distanceY;
    					shipMoved = true;
    				}
   		
   					if (shipMoved)
   					{
   						if (newX<0)
   							newX = 0;
   						if (newX+ship.getWidth()>=width-1)
   							newX = width-ship.getWidth()-1;
   						if (newY<0)
   							newY = 0;
   						if (newY+ship.getHeight()>=height-1)
   							newY = height-ship.getHeight()-1;
    					ship.setX(newX);
   						ship.setY(newY);
   						startMouseDragX = xPos;
   						startMouseDragY = yPos;
   					} // end of if (shipMoved) 
   		
   				} // end of if (dragging)       		
        		        		        		        	        	        		
        	}
         	
        	else if (e.getAction() == MotionEvent.ACTION_UP) // the finger is lifted
        	{        		
        		dragging = false;
        		startMouseDragX = -1;
    			startMouseDragY = -1;
    			
    			if (startButton.getRect().contains(x,y))
    			{
            		gameOver = false;
                	gameOverScreen = false;
                	
                	doNewGameSetup();
                	startButton.setX(-200);
                	soundButton.setX(-200);
                	levelButton.setX(-200);
                	shipScore = 0; 
                	if (level==0)
                		level++;
                	
    			}
    			
    			if (soundButton.getRect().contains(x,y))
    			{
    				
    				if (playSound)
    					playSound = false;
    				else
    					playSound = true;
    			}

    			if (levelButton.getRect().contains(x,y))
    			{
    				level = 0;
    			}

    			if (ship != null && !gameOver && shipCanFire && ship.getRect().contains(x,y))
    			{
    				MovableObject shipBullet = new MovableObject(shipBulletFilename,shipBulletId,50,-100,71,71);
    				shipBullet.setX(ship.getX()+ship.getWidth()/2 - shipBullet.getWidth()/2);
    				shipBullet.setY(ship.getY() - ship.getHeight() - 2);
    				shipBullet.setSpeedXY(shipBulletSpeed,shipBulletSpeed);
    				shipBulletList.add(shipBullet);
    				
    			}
    			shipCanFire = true;
        		        		        	        	        		
        	}
        		
        	return true;
        }
  
        public boolean isInsideOf(float gx1, float gy1, MovableObject object)
        {
        	if (gx1 >= object.getX() && gx1 <= object.getX() + object.getWidth()  &&
        		gy1 >= object.getY() && gy1 <= object.getY() + object.getHeight())
        		return true;
        	return false;	
        }

        public int getPreferredTextSizeForCentering(int length)
        {
        	int size = 9;

        	if (length >=24 && length <= 28)
        	{
        		for (int i=100; i <= width; i += 25)
        		{
        			if (i >= width)
        				return size;
        			size++;
        		}
        		return size;
        	}
          	
        	size = 8;
        	if (length >=29 && length <= 32)
        	{
        		for (int i=100; i <= width; i += 25)
        		{
        			if (i >= width)
        				return size;
        			size++;
        		}
        		return size;
        	}

        	return size;
        }
        
        public void firstTimeScreen(Canvas canvas)
        {
   	   		// set the background color to black
    		canvas.drawColor(Color.BLACK);

    		// since we do not have access to the canvas in the onCreate event
			// we will grab the screen dimensions here and save them
			width = canvas.getWidth();
			height = canvas.getHeight()-60;

			// remove when finished
			if (testing)
			{
			myDrawText(canvas, "25 ", getPreferredTextSizeForCentering(27), 0, 25, Color.RED, 0);
			myDrawText(canvas, "50 ", getPreferredTextSizeForCentering(27), 0, 50, Color.RED, 0);
			myDrawText(canvas, "75 ", getPreferredTextSizeForCentering(27), 0, 75, Color.RED, 0);

			myDrawText(canvas, ""+(height-75), getPreferredTextSizeForCentering(27), 0, height-75, Color.RED, 0);
			myDrawText(canvas, ""+(height-50), getPreferredTextSizeForCentering(27), 0, height-50, Color.RED, 0);
			myDrawText(canvas, ""+(height-25), getPreferredTextSizeForCentering(27), 0, height-25, Color.RED, 0);
			myDrawText(canvas, ""+height, getPreferredTextSizeForCentering(27), 0, height, Color.RED, 0);
			}

   			myDrawText(canvas, "Welcome to Android Invaders", getPreferredTextSizeForCentering(27), width/2, 100, Color.RED, 1);
			myDrawText(canvas, "Touch the Android to Begin", getPreferredTextSizeForCentering(31), width/2, 125, Color.GREEN,1 );
			myDrawText(canvas, "Tap the Ship to Fire", getPreferredTextSizeForCentering(31), width/2, 150, Color.GREEN,1 );
			myDrawText(canvas, "Drag the Ship to Move", getPreferredTextSizeForCentering(31), width/2, 175, Color.GREEN,1 );
			
			myDrawText(canvas, "Wins: "+shipWins+"  Losses: "+shipLosses, getPreferredTextSizeForCentering(27), width/2, 200, Color.RED, 1);
			
			// set the alien's location
			MovableObject alien = alienList.get(0);
			float tx = (float) (width/4 - .5*alien.getWidth());

			alien.setX(tx);
			alien.setY(alien.getHeight()+ 10);

			alien = alienList.get(1);
			alien.setX((float) (width/4*3 - .5*alien.getWidth()));
			alien.setY(alien.getHeight()+ 10);
			
			// set the ship's location
			ship.setX((float)(width/2.0 - .5*ship.getWidth()));
			ship.setY(height - ship.getHeight()-55);

    		// draw all of your objects
    		ship.draw(canvas);
    		
    		for (int i=0; i < alienList.size(); i++)
    		{
    			alienList.get(i).draw(canvas);
    		}
    		
       		if (levelButton != null)
    		{
        		levelButton.setX(width/4-levelButton.getWidth()/2);
         		levelButton.setY(280);
     			levelButton.draw(canvas);
    		}

    		if (startButton != null)
    		{
        		startButton.setX(width/2-startButton.getWidth()/2);
         		startButton.setY(280);
     			startButton.draw(canvas);
    		}

    		if (soundButton != null)
    		{
        		soundButton.setX(width/4*3-soundButton.getWidth()/2);
         		soundButton.setY(280);
     			soundButton.draw(canvas);
    		}
        	
        }
        
        public void doNewGameSetup()
        {
			// set level parameters
			if (initSetup)
			{
				level++;
				if (level <= 1)
				{
					chanceOfNewAlien = beginValueForChanceOfNewAlien;
					shipPointsForAlienHit = shipBeginPointsForAlienHit;
					alienCanFire = false;
					alienSpeed = alienStartSpeed;
					chanceOfAlienFiring = 0;
					alienBulletSpeed = alienBulletStartSpeed;
				}
				else if (level == 2)
				{
					chanceOfNewAlien -= 5;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring = 350;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 3)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
				}
				else if (level == 4)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 5)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					//chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
				}
				else if (level == 6)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 7)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 8)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 9)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 10)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 11)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 12)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 13)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 14)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 15)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 16)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 17)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 18)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 19)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					//alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					//alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level == 20)
				{
					chanceOfNewAlien -= 10;
					shipPointsForAlienHit -= 1;
					alienSpeed++;
					alienCanFire = true;
					chanceOfAlienFiring -= 10;
					alienBulletSpeed++;
					shipPointsForAlienOffScreen--;
				}
				else if (level > 20)
				{
					level = 1;
					shipPointsForAlienHit = shipBeginPointsForAlienHit;
					chanceOfNewAlien = beginValueForChanceOfNewAlien;
					alienCanFire = false;
					alienSpeed = alienStartSpeed;
					chanceOfAlienFiring = 0;
					alienBulletSpeed = alienBulletStartSpeed;
					shipPointsForAlienOffScreen = shipBeginPointsForAlienOffScreen;
				}
				
				if (shipPointsForAlienHit < 5)
					shipPointsForAlienHit = 5;
				if (chanceOfAlienFiring < 20 && alienCanFire)
					chanceOfAlienFiring = 20;
				if (chanceOfNewAlien < 20)
					chanceOfNewAlien = 20;
				
				// create your ship
				if (ship == null)
					ship = new MovableObject(shipFilename,shipId,150,200,71,71);
				
   				// set the ship's location
				ship.setX((float)(width/2.0 - .5*ship.getWidth()));
				ship.setY(height - ship.getHeight()-55);

				alienList.clear();
			
				// create your aliens
    	    	MovableObject alien = new MovableObject(alienFilename,alienId,50,-100,71,71);
				alien.setY(alien.getHeight()+ 10);
				alien.setSpeedXY(alienSpeed, alienSpeed);
    	    	alienList.add(alien);
    	    
    	    	alien = new MovableObject(alienFilename,alienId,250,-100,71,71);
				alien.setY(alien.getHeight()+ 10);
				alien.setSpeedXY(alienSpeed, alienSpeed);
    	    	alienList.add(alien);
    	    
    	    	shipBulletList.clear();
    	    	alienBulletList.clear();
    	    	explosionList.clear();
    	    	removeUnusedMusicPlayers();
    	    	
    	    	initSetup = false;
			}
        	
        }

        public void gameOverScreen(Canvas canvas)
        {
  	   		// set the background color to black
    		canvas.drawColor(Color.BLACK);

    		// since we do not have access to the canvas in the onCreate event
			// we will grab the screen dimensions here and save them
			width = canvas.getWidth();
			height = canvas.getHeight()-60;

    		// draw all of your objects
			
			// draw the ship
     		if (ship != null)
     			ship.draw(canvas);
 
     		// draw the ship's bullets
      		for (int i=0; i < shipBulletList.size(); i++)
    		{
    			shipBulletList.get(i).draw(canvas);
    		}
     		
     		// draw the aliens
    		for (int i=0; i < alienList.size(); i++)
    		{
    			alienList.get(i).draw(canvas);
    		}
     		
    		// draw the alien's bullets
    		for (int i=0; i < alienBulletList.size(); i++)
    		{
    			alienBulletList.get(i).draw(canvas);
    		}
 
       		// draw the explosions
    		for (int i=0; i < explosionList.size(); i++)
    		{
    			explosionList.get(i).draw(canvas);
    		}

  			myDrawText(canvas, "Game Over", getPreferredTextSizeForCentering(27), width/2, 150, Color.RED,1);
			myDrawText(canvas, "Touch the Anroid to Begin", getPreferredTextSizeForCentering(31), width/2, 175, Color.GREEN,1);
			myDrawText(canvas, "Wins: "+shipWins+"  Losses: "+shipLosses, getPreferredTextSizeForCentering(27), width/2, 200, Color.RED, 1);
 
       		if (levelButton != null)
    		{
        		levelButton.setX(width/4-levelButton.getWidth()/2);
         		levelButton.setY(280);
     			levelButton.draw(canvas);
    		}

    		if (startButton != null)
    		{
        		startButton.setX(width/2-startButton.getWidth()/2);
         		startButton.setY(280);
     			startButton.draw(canvas);
    		}

    		if (soundButton != null)
    		{
        		soundButton.setX(width/4*3-soundButton.getWidth()/2);
         		soundButton.setY(280);
     			soundButton.draw(canvas);
    		}

        }

        // this method will get called every threadDelay (20) ms
    	@Override
    	protected void onDraw(Canvas canvas)
    	{
     		
    		if (gameOverScreen && gameOver)
    		{
    			gameOverScreen(canvas);
        		return;
     		}
    		
    		if (firstTime)
    		{
    			firstTimeScreen(canvas);	
     		}
    		
       		if (gameOver)
    			return;
    		
   	   		// set the background color to black
    		canvas.drawColor(Color.BLACK);

    		
			// ***********  There are four main steps

    		
    		
			// 1
			// create any new alien objects
    		timeSinceLastNewAlien += localThreadDelay;
    		
			int r = (int) (Math.random() * chanceOfNewAlien);
			if (r==1 || timeSinceLastNewAlien > maxTimeAllowedForNewAlien)
			{
				float rx = (int) (Math.random() * width - 100) + 80;
				if (rx < 0)
					rx = 10;
				
	    	    MovableObject alien = new MovableObject(alienFilename,alienId,rx,-100,71,71);
	    	    if (rx > width-alien.getWidth())
	    	    {
	    	    	rx = width-alien.getWidth()-10;
	    	    	alien.setX(rx);
	    	    }
	    	    
	    	    alien.setSpeedXY(alienSpeed, alienSpeed);
	    	    alienList.add(alien);
	    	    timeSinceLastNewAlien = 0;
			}

			
			
			// 2
			// move all of your objects
			// remove them if they go off the screen

			// move the aliens and remove them if they go off the screen
			for (int i=0; i < alienList.size(); i++)
    		{
    			alienList.get(i).moveDown();
       			if (alienList.get(i).getY() > canvas.getHeight())
    			{
    				alienList.remove(i);
    				i--;
    				shipScore += shipPointsForAlienOffScreen;
    			}
    		}

			// move the alien bullets and remove them if they go off the screen
			for (int i=0; i < alienBulletList.size(); i++)
    		{
    			alienBulletList.get(i).moveDown();
       			if (alienBulletList.get(i).getY() > canvas.getHeight())
    			{
    				alienBulletList.remove(i);
    				i--;
    			}
    		}
			
			// move the ship bullets and remove them if they go off the screen
     		for (int i=0; i < shipBulletList.size(); i++)
    		{
    			shipBulletList.get(i).moveUp();
    			if (shipBulletList.get(i).getY() < -80)
    			{
    				shipBulletList.remove(i);
    				i--;
    				shipScore -= 1;
    			}
    		}
      		
       		// move the explosions and remove them if the time is up
    		for (int i=0; i < explosionList.size(); i++)
    		{
    			MovableObject explosion = explosionList.get(i);
    			explosion.setTime(explosion.getTime()-localThreadDelay);
    			if (explosion.getTime() <= 0)
    			{
    				explosionList.remove(i);
    				i--;
    			}
    		}

      		// remove any music players that have finished 
    		removeUnusedMusicPlayers();
    		/*
    		for (int i=0; i < mediaPlayers.size(); i++)
    		{

    			if (!mediaPlayers.get(i).isPlaying())
    			{
    				mediaPlayers.get(i).release();
    				mediaPlayers.remove(i);
    				i--;
    			}
    		}
     	    */
     		
			// 3
    		// check and see if objects are colliding with other objects
    		
     		// check the ship bullets to see if they hit an alien
     		for (int i=0; i < shipBulletList.size(); i++)
    		{
    			MovableObject bullet = shipBulletList.get(i);
    			// check and see if this bullet has hit an alien
    			for (int k=0; k < alienList.size(); k++)
    			{
    				if (bullet.intersects(alienList.get(k)))
    				{
    					// remove the alien and bullet from the screen
    					alienList.remove(k);
    					shipBulletList.remove(i);
    					i--;
    					shipScore += shipPointsForAlienHit;
    					
    					// now create an explosion and keep it on the screen for a certain amount of time
    	    	    	MovableObject explosion = new MovableObject(explosionFilename,explosionId,bullet.getX(),bullet.getY(),71,71);
      	    	    	float newX = bullet.getX() - (explosion.getWidth()-bullet.getWidth())/2;
       	    	    	explosion.setX(newX);

    					explosion.setSpeedXY(0,0);
    					explosion.setTime(explosionTimeOnScreen);  
    	    	    	explosionList.add(explosion);

      	    	    	// see if we have any available MediaPlayer objects first
    	    	    	playAvailableMusicPlayer();
    	    	    	//MediaPlayer mp = MediaPlayer.create(thisContext, R.raw.explosion);    
    	    	    	//mp.start();
    	    	    	// mp.isPlaying()
    	    	    	// mp.reset();
    	    	    	//mediaPlayers.add(mp);

    					break;
    				}
    			}
     		}
 
     		// check the alien bullets to see if they hit a ship bullet
     		for (int i=0; i < alienBulletList.size(); i++)
    		{
    			MovableObject bullet = alienBulletList.get(i);
    			// check and see if this bullet has hit a ship's bullet
    			for (int k=0; k < shipBulletList.size(); k++)
    			{
    				if (bullet.intersects(shipBulletList.get(k)))
    				{
    					// remove the bullets from the screen
    					alienBulletList.remove(i);
    					shipBulletList.remove(k);
    					i--;

    					// now create an explosion and keep it on the screen for a certain amount of time    					
       	    	    	MovableObject explosion = new MovableObject(explosionFilename,explosionId,bullet.getX(),bullet.getY(),71,71);
       	    	    	float newX = bullet.getX() - (explosion.getWidth()-bullet.getWidth())/2;
       	    	    	explosion.setX(newX);
    					explosion.setSpeedXY(0,0);
    					explosion.setTime(explosionTimeOnScreen);  
    	    	    	explosionList.add(explosion);
    	    	    	
    	    	    	// see if we have any available MediaPlayer objects first
    	    	    	playAvailableMusicPlayer();
    	    	    	//MediaPlayer mp = MediaPlayer.create(thisContext, R.raw.explosion);    
    	    	    	//mp.start();
    	    	    	// mp.isPlaying()
    	    	    	// mp.reset();
    	    	    	//mediaPlayers.add(mp);

    	    	    	
    					break;
    				}
    			}
     		}

     		// check the alien bullets to see if they hit the ship
     		for (int i=0; i < alienBulletList.size(); i++)
    		{
    			MovableObject bullet = alienBulletList.get(i);
    			if (ship != null && bullet.intersects(ship))
    			{
   					// now create an explosion and keep it on the screen for a certain amount of time    					
   	    	    	MovableObject explosion = new MovableObject(explosionFilename,explosionId,bullet.getX(),bullet.getY()+bullet.getHeight(),71,71);
   	    	    	float newX = bullet.getX() - (explosion.getWidth()-bullet.getWidth())/2;
   	    	    	explosion.setX(newX);
					explosion.setSpeedXY(0,0);
					explosion.setTime(explosionTimeOnScreen);  // 2 seconds
	    	    	explosionList.add(explosion);
					
    				alienBulletList.remove(i);
    				
   	    	    	// see if we have any available MediaPlayer objects first
    				playAvailableMusicPlayer();
	    	    	//MediaPlayer mp = MediaPlayer.create(thisContext, R.raw.explosion);    
	    	    	//mp.start();
	    	    	// mp.isPlaying()
	    	    	// mp.reset();
	    	    	//mediaPlayers.add(mp);

    				ship = null;
    				break;
    			}
    		}

     		// check and see if the ship collides with an alien
     		for (int i=0; i < alienList.size(); i++)
     		{
     			if (ship == null)
     				break;
     			
     			MovableObject alien = alienList.get(i);	
     			if (alien.intersects(ship))
     			{
   					// now create an explosion and keep it on the screen for a certain amount of time    					
   	    	    	MovableObject explosion = new MovableObject(explosionFilename,explosionId,alien.getX(),alien.getY()+alien.getHeight(),71,71);
   	    	    	float newX = alien.getX() - (explosion.getWidth()-alien.getWidth())/2;
   	    	    	explosion.setX(newX);
					explosion.setSpeedXY(0,0);
					explosion.setTime(explosionTimeOnScreen);  // 2 seconds
	    	    	explosionList.add(explosion);
	    	    	
   	    	    	// see if we have any available MediaPlayer objects first
	    	    	playAvailableMusicPlayer();
	    	    	//MediaPlayer mp = MediaPlayer.create(thisContext, R.raw.explosion);    
	    	    	//mp.start();
	    	    	// mp.isPlaying()
	    	    	// mp.reset();
	    	    	//mediaPlayers.add(mp);

    				ship = null;
     				break;
     			}
     		}
    		
     		// fire alien bullets
     		if (alienCanFire)
     		{
        		for (int i=0; i < alienList.size(); i++)
         		{
        			int ra = (int) (Math.random() * chanceOfAlienFiring);
        			if (ra==1)
        			{
        				MovableObject alien = alienList.get(i);
        				float rx = alien.getX() + alien.getWidth()/2;
        				float ry = alien.getY();
        	    	    MovableObject alienBullet = new MovableObject(alienBulletFilename,alienBulletId,rx,ry,71,71);
        	    	    alienBullet.setX(rx-alienBullet.getWidth()/2);
        	    	    alienBullet.setY(ry + alienBullet.getHeight()+2);
        	    	    alienBullet.setSpeedXY(alienBulletSpeed, alienBulletSpeed);
        	    	    alienBulletList.add(alienBullet);
        			}
        			
         		}    			
     		}

     		
    		// 4
    		// draw all of your objects
			
			// draw the ship
     		if (ship != null)
     			ship.draw(canvas);
 
     		// draw the ship's bullets
      		for (int i=0; i < shipBulletList.size(); i++)
    		{
    			shipBulletList.get(i).draw(canvas);
    		}
     		
     		// draw the aliens
    		for (int i=0; i < alienList.size(); i++)
    		{
    			alienList.get(i).draw(canvas);
    		}
     		
    		// draw the alien's bullets
    		for (int i=0; i < alienBulletList.size(); i++)
    		{
    			alienBulletList.get(i).draw(canvas);
    		}
   		
       		// draw the explosions
    		for (int i=0; i < explosionList.size(); i++)
    		{
    			explosionList.get(i).draw(canvas);
    		}

			firstTime = false;

			// check to see if the game is over
			if (ship==null || shipScore >= 100)
			{
				gameOver = true;
				gameOverScreen = true;
				initSetup = true;
				if (shipScore >= 100)
					shipWins++;
				else
					shipLosses++;
			}
			
  			myDrawText(canvas, "Score: "+shipScore + "  Level: "+level, getPreferredTextSizeForCentering(27), 10, 19, Color.RED,0);

    		/* for testing only, remove when finished
    		int xx = 10;
    		for (int yy=0; yy <= 100; yy=yy+10)
    		{
    			myDrawLine(canvas, xx, yy, xx, 100, Color.RED);
    			xx = xx + 10;
    		}
    		*/
    	}
    	
    	// other draw methods not required for this project
    	private void myDrawLine(Canvas canvas, float x1, float y1, float x2, float y2, int color)
    	{
    		Paint paintLineColor = new Paint();
    		paintLineColor.setColor(color);
    		paintLineColor.setStyle(Paint.Style.STROKE);  // filled is the default
    		canvas.drawLine(x1,y1,x2,y2,paintLineColor);
    	}
    
       	private void myDrawCircle(Canvas canvas, float x, float y, float radius, int color)
    	{
    		Paint paintLineColor = new Paint();
    		paintLineColor.setColor(color);
    		paintLineColor.setStyle(Paint.Style.STROKE);  // filled is the default
    		canvas.drawCircle(x,y,radius,paintLineColor);
    	}

      	private void myFillCircle(Canvas canvas, float x, float y, float radius, int color)
    	{
    		Paint paintFillColor = new Paint();
    		paintFillColor.setColor(color);
    		paintFillColor.setStyle(Paint.Style.FILL);  // fill is the default
    		canvas.drawCircle(x,y,radius,paintFillColor);
    	}
      	
      	private void myDrawText(Canvas canvas, String text, int size, float x, float y, int color, int alignment)
      	{
      		Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
      		paintText.setColor(color);
      		Typeface typeface = Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL);
      		paintText.setTextSize(size);
      		paintText.setTypeface(typeface);  // Sans Serif  is the default
      		
      		if (alignment==1)
      			paintText.setTextAlign(Paint.Align.CENTER);
      		 
      		canvas.drawText(text, x, y, paintText);
      		
      	}

      	
// ***********************************************************************
// MovableObject class
// ***********************************************************************

class MovableObject
{
	// direction to move
	// 0 to 360 
	private int direction;
	private int speed;
	
	// current location of object
	private float x;
	private float y;
	private float width;
	private float height;

	// amount of time on the screen
	private float time;
	
	// speed of object
 
	private int speedX;
	private int speedY;
	
	// list of possible images to use
	private ArrayList <Bitmap> imageList;
	
	// current image being displayed
	private Bitmap currentImage;

	// filename of current image being displayed
	private String currentFilename;
	int currentDrawableId;
	
	// list of filenames for the images (jpg, ...)
	private String [] imageFilenames;

    public MovableObject(String filename, int drawableId, float x, float y, float width, float height)
    {
		direction = 0; // Location.NORTH;
		speed = 3;
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		time = 0;
		speedX = 3;
		speedY = 3;
		imageList = null;
		currentImage = null;
		imageFilenames = null;
		currentDrawableId = drawableId;
		currentFilename = "";
		setCurrentFilename(filename);
		if (currentImage != null)
		{
			this.height = currentImage.getHeight();
			this.width = currentImage.getWidth();
			
		}
 	}

	public void setImageFilenames(String [] filenames)
	{
		imageFilenames = filenames;
		imageList = new ArrayList<Bitmap>();
		for (int i=0; i < filenames.length; i++)
		{
			try
			{
				// change me back
				Bitmap pic = BitmapFactory.decodeResource(getResources(),currentDrawableId);
				imageList.add(pic);
			}
			catch (Exception e)
			{
			}
		}
		if (filenames.length > 0)
		{
			currentFilename = filenames[0];
			setImage();
		}
	}

	private void setImage()
	{
		if (currentFilename != null && !currentFilename.equals(""))
		{
			try
			{
				// change me back
				currentImage = BitmapFactory.decodeResource(getResources(),currentDrawableId);
				width = currentImage.getWidth();
				height = currentImage.getHeight();
				//System.out.println("toolkit ok");
			}
			catch (Exception e)
			{
				currentImage = null;
				currentFilename = "";
				//System.out.println("error getImage with toolkit");
			}
		}
	}

	public void setCurrentFilename(String filename)
	{
		currentFilename = filename;
		setImage();
	}

	public void setCurrentFilenamePosition(int position)
	{
		if (imageFilenames == null)
			return;
		if (position < imageFilenames.length && position > -1)
			{
				currentFilename = imageFilenames[position];
				setImage();
			}
		else
			{
				currentFilename = "";
				currentImage = null;
			}
	}

    public int getDirection()
    {
        return direction;
    }

    public void setDirection(int direction)
    {
        this.direction = direction;
        this.direction = this.direction % 360;
    }

    public float getX()
    {
        return x;
    }

    public void setX(float x)
    {
        this.x = x;
    }

    public float getY()
    {
        return y;
    }

    public void setY(float y)
    {
        this.y = y;
    }

    public void setXY(float x, float y)
    {
        this.x = x;
        this.y = y;
    }

    public float getWidth()
    {
        return width;
    }

    public void setWidth(float width)
    {
        this.width = width;
    }

    public float getHeight()
    {
        return height;
    }

    public void setHeight(float height)
    {
        this.height = height;
    }

    public int getSpeedX()
    {
        return speedX;
    }

    public void setSpeedX(int speedX)
    {
        this.speedX = speedX;
    }

    public int getSpeedY()
    {
        return speedY;
    }

    public void setSpeed(int speed)
    {
        this.speed = speed;
    }

    public int getSpeed()
    {
        return speed;
    }

    public void setSpeedXY(int speedX, int speedY)
    {
        this.speedX = speedX;
        this.speedY = speedY;
    }

    public void setSpeedY(int speedY)
    {
        this.speedY = speedY;
    }

    public float getTime()
    {
        return time;
    }

    public void setTime(float time)
    {
        this.time = time;
    }

	public void moveUp()
	{
		setY(getY() - speedY);
	}

	public void moveDown()
	{
		setY(getY() + speedY);
	}

	public void moveLeft()
	{
		setX(getX() - speedX);
	}

	public void moveRight()
	{
		setX(getX() + speedX);
	}

	public void moveTo(float x, float y)
	{
		setX(x);
		setY(y);
	}

	public Rectangle getRect()
	{
		return new Rectangle(getX(),getY(),getWidth(),getHeight());
	}

	public boolean intersects(Rectangle rect)
	{
		if (getRect().intersects(rect))
			return true;
		return false;
	}
	
	public boolean intersects(MovableObject other)
	{
		if (getRect().intersects(other.getRect()))
			return true;
		return false;
	}

	public Point getPoint()
	{
		return new Point(getX(),getY());
	}

	public void turnRight()
	{
		setDirection(getDirection()+90);
	}
	
	public boolean containsPoint(Point point)
	{
		if (getRect().contains(point))
			return true;
		return false;
	}

	// moves toward the other object using the speed
	// uses similar triangles
	public void moveTowards(MovableObject other)
	{
		double sideX = Math.abs(other.getX() - getX());
		double sideY = Math.abs(other.getY() - getY());
		double d = Math.sqrt(sideX*sideX + sideY*sideY);
		
		int speedX = (int)Math.round((getSpeed()*sideX)/d);
		int speedY = (int)Math.round((getSpeed()*sideY)/d);
		
		if (getX() < other.getX())
			setX(getX() + speedX);
		else if (getX() > other.getX())
			setX(getX() - speedX);
		
		if (getY() < other.getY())
			setY(getY() + speedY);
		else if (getY() > other.getY())
			setY(getY() - speedY);			
	
	}

	public void draw2(Canvas g)
	{
		// change me back
		g.drawBitmap(currentImage,x,y,null);
	}
    
	public double degreesToRadians(double degrees)
	{
     	return degrees*Math.PI/180;
	}
	
	public void draw(Canvas g)
	{		
		// change me back
		if (currentImage != null)
			g.drawBitmap(currentImage,x,y,null);	
	}

}  // end of class MovableObject

//***********************************************************************
//Rectangle class
//***********************************************************************
class Rectangle
{
	float x;
	float y;
	float width;
	float height;	
	
	public Rectangle (float x, float y, float width, float height)
	{
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}
	
	public boolean intersects(Rectangle other)
	{
	   // see if this Rectangle intersects other
	    if (isInsideOf(x,y,other))
	   		return true;
	    if (isInsideOf(x+width,y,other))
	   		return true;
	    if (isInsideOf(x,y,other))
	   		return true;
	    if (isInsideOf(x+width,y+width,other))
	   		return true;
	   	return false;
	}
	
	public boolean isInsideOf(float x, float y, Rectangle other)
    {
        if (x >= other.x && x <= other.x + other.width  &&
        	y >= other.y && y <= other.y + other.height)
        		return true;
        return false;	
    }

	public boolean contains(Point point)
	{
		if (isInsideOf(point.x, point.y, this))
			return true;
		return false;
	}

	public boolean contains(float x, float y)
	{
		if (isInsideOf(x, y, this))
			return true;
		return false;
	}

}  // end of class Rectangle

// ***********************************************************************
// Point class
// ***********************************************************************
class Point
{
	float x;
	float y;
	
	public Point(float x, float y)	
	{
		this.x = x;
		this.y = y;
	}
	
	public float getX()
	{
		return x;
	}
	public float getY()
	{
		return y;
	}

}// end of class Point

    }

}  // end of class AndroidInvaders