// Coffer Vengeance by Chris Arnold Jager.
// Copyright 2005(C). All rights reserved.
//
// E-mail:sloesp@hotmail.com
//
// Coffer Vengeance is part of the European Hero galaxy.
// Visit www.europeanhero.com for more information.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;

public class CofferVengeance extends Applet implements Runnable, KeyListener,MouseListener, MouseMotionListener {
	//Game thread & double buffering
	private Thread proces; 
	private Image offscreenImage;   
    	private Graphics offscreen;  
    	
    	//Images
    	private Image back,player,crate,player_death;
    	private Image prismo_stand,prismo_walk_left,prismo_walk_right,prismo_shoot,prismo_death;  
    	private Image bullet1,bullet2,cannon_green,shotgun_green;
    	private Image prismo,prismoopen;
	
	//Audio
	private AudioClip shoot1, shoot2, hit, death, gameover,victory;
	private int[] sound_timer = new int[4];
	 
	//Various    
	private int x,y; 
	private int xPosCrate,yPosCrate,xPosCrate1,xPosCrate2,showCrateTimer,crate_random_time;
	private int leftBorder,rightBorder,topBorder,bottomBorder; 
	private int cofferWidth,cofferHeight; 
	private boolean left,right,up,down,ctrl,enter;//The keyboard flags
	private boolean pressedShot;
	private boolean inInfoScreen,inGameOver,inVictoryScreen;
	private boolean showCrate;
	private int shieldTimer;
	private int prismo_end_timer;
	
	//Banner properties
	private int bannerX;
	private int bannerY;
	private int mouseX;
	private int mouseY;
	private int bannerWidth;
	private int bannerHeight;
	private URL bannerURL;
	private boolean notClicked;
		
	//Prismo infantry
	private int nrOfPrismos=50;
	private int[] xPosPrismo = new int[nrOfPrismos];
	private int[] yPosPrismo = new int[nrOfPrismos];
	private int[] xChangePrismo = new int[nrOfPrismos];
	private int[] yChangePrismo = new int[nrOfPrismos];
	private int[] timerPrismo = new int[nrOfPrismos];
	private int[] speedPrismo = new int[nrOfPrismos];
	private boolean[] alivePrismo = new boolean[nrOfPrismos];
	private boolean[] shootPrismo = new boolean[nrOfPrismos];
	private int prismoWidth;
	private int prismoHeight;
	private int prismo_bullet_speed;
	private int prismo_releases;
	private int prismos_allowed;
	private int prismos_in_field;
	private int prismo_death_count;
	private String prismo_death_string;
	
	//Prismo bullets
	private int nrOfBullets=30;
	private int[] xPosBullet = new int[nrOfBullets];
	private int[] yPosBullet = new int[nrOfBullets];
	private int[] xChangeBullet = new int[nrOfBullets];
	private int[] yChangeBullet = new int[nrOfBullets];
	private int[] timerBullet = new int[nrOfBullets];
	private boolean[] firedBullet = new boolean[nrOfBullets];
		
	//Coffer bullets
	private int nrOfCofferBullets=50;
	private int[] xPosCofferBullet = new int[nrOfCofferBullets];
	private int[] yPosCofferBullet = new int[nrOfCofferBullets];
	private int[] xChangeCofferBullet = new int[nrOfCofferBullets];
	private int[] yChangeCofferBullet = new int[nrOfCofferBullets];
	private int[] timerCofferBullet = new int[nrOfCofferBullets];
	private int[] typeCofferBullet = new int[nrOfCofferBullets];
	private boolean[] firedCofferBullet = new boolean[nrOfCofferBullets];
	private boolean firePermission;
		
	
	//Weapon properties
	private int rockets;
	private int lives;
	private int phase;
	private int score;
	
	//Timers
	private boolean getNewStartTime=true;
	private long startTime,runTime,time;
	private int seconds,crate_appear,game_next_phase;
	private int crate_timer,game_timer;
	private int prismo_timer,prismo_release_rate,death_timer;
	
	public void init() {
		resize(300,328); //Resize the applet
		
		resetProperties(); //Set all properties.
		
		loadImages(); //Load the images
		loadSounds(); //Load the sounds
		
		this.addMouseListener(this); //Add mouse listener
		this.addMouseMotionListener(this); //Add mouse motion listener
		
		this.addKeyListener(this); //Add key listener
		
		proces=new Thread(this);  //Initiate the thread.
        	proces.start(); //Start the thread.
	}
	
	public void loadSounds(){
		shoot1 = getAudioClip(getCodeBase(),"data/shoot1.au");
        	shoot1.play();    shoot1.stop();
		shoot2 = getAudioClip(getCodeBase(),"data/shoot2.au");
        	shoot2.play();    shoot2.stop();
        	hit = getAudioClip(getCodeBase(),"data/hit.au");
        	hit.play();    hit.stop();
        	death = getAudioClip(getCodeBase(),"data/death.au");
        	death.play();    death.stop();
        	gameover = getAudioClip(getCodeBase(),"data/gameover.au");
        	gameover.play();    gameover.stop();
        	victory = getAudioClip(getCodeBase(),"data/victory.au");
        	victory.play();    victory.stop();
        }
	
	public void resetProperties(){
		x=80;y=260; 
		
		//Weapon properties
		rockets = 0;
		lives = 3;
		phase = 0;
		score = 0;
		
		//Set the borders
		leftBorder=0; 
		rightBorder=300;
		topBorder=0;
		bottomBorder=300;
		
		cofferWidth=31; 
		cofferHeight=32;
		
		prismoWidth = 13;
		prismoHeight = 8;
		
		xPosCrate1=260;
		xPosCrate2=15;
		
		yPosCrate=270;
		
		//Banner properties
		mouseX=0;
		mouseY=0;
		bannerX=0;
		bannerY=300;
		bannerWidth=300;
		bannerHeight=28;
		notClicked=true;
					
		//Prismo properties
		for(int i=0;i<nrOfPrismos;i++){
			alivePrismo[i]=false;
			timerPrismo[i]=0;
			shootPrismo[i]=false;
		}
		for(int i=0;i<nrOfBullets;i++){
			firedBullet[i]=false;
		}
		
		prismo_bullet_speed = 1;
		prismo_releases = 1;
		prismos_allowed = 15;
		prismos_in_field = 0;
		prismo_death_count = 0;
		prismo_death_string = "";
		
		//Coffer properties
		for(int i=0;i<nrOfCofferBullets;i++){
			firedCofferBullet[i]=false;
		}
		
		firePermission=true;
					
		// Key flags.
		left  = false;
		right = false;
		up    = false;
		down  = false;
		ctrl = false;
		enter = false;
		
		pressedShot = false;
		
		inInfoScreen = true;
		inGameOver = false;
		inVictoryScreen = false;
		
		showCrate = false;
		showCrateTimer = 0;
		shieldTimer = 0;
		
		prismo_death_count = 0;
		
		seconds=0;
		crate_random_time = 10;
		crate_appear=8 + (int)(Math.random() * crate_random_time);
		game_next_phase=10;
		crate_timer=0;
		game_timer=0;
		prismo_timer=0;
		prismo_release_rate=2;	
		death_timer=0;
		
		//Phase 28 test conditions
		//prismo_release_rate=0;
		//prismo_releases=50; 
		//prismos_allowed=50;
	}
	
	public void run(){
        	Graphics g = getGraphics(); 
        	   
        	while(true){ //Loop forever
	        	paint(g); //Draw the game on the screen.
	        		        	
	        	firePermissionCheck(); //Check if player is allowed to shoot(5 bullets max).
	        	              
	       		handleKeyboard(); //Handle keyboard events.
	       		crateCheck(); //Check if crate is picked up.
	       		
	       		updateTimers(); //Update game-timers and trigger game events.
	       		
	       		//If in-game
	       		if(!inInfoScreen && !inVictoryScreen){
	       			placePrismos(); //Spawn prismos.
	       			
	       			movePrismos(); //Move the prismos.
	       			moveBullets(); //Move the prismo bullets.
	       			moveCofferBullets(); //Move the player bullets.
	       			
	       			if(death_timer>0){ //Count death timer.
	       				death_timer++;
	       				
	       				if(death_timer>=100){
	       					death_timer=0;
	       				}
	       			}
	       		}
	       		
	       		if(inVictoryScreen){ //Run end timer(prismo talking animation).
	       			prismo_end_timer++;
	       			
	       			if(prismo_end_timer>10){
	       				prismo_end_timer=0;
	       			}
	       		}
	       		
	       		updateSoundTimers(); //Keep track of how long a sound has been playing. If the sound has ended, permission is given to play that sound again.
	       		
	       		checkMouseEE(); //Keep track of mouse position.
	       			       		
	       		try {Thread.sleep(20);} //Let the thread sleep for 20 milliseconds
            		catch(InterruptedException e){} 
            		
            		//!!NOTE!!
            		//Thead.sleep should preferably not be used. The sleep command is very 
            		//inaccurate(-20 to 20ms deviation in Windows). Instead, use the JAVA 
            		//nanotimer(1.5 only) or a external high-resolution timer(e.g. GAGETimer).
		}		        
        }
	
	public void paint(Graphics g) {
		if(offscreen==null){ //Set double buffering
            		offscreenImage=createImage(this.getSize().width,this.getSize().height); 
            		offscreen=offscreenImage.getGraphics(); 
        	}
        	offscreen.setFont(new Font("Tahoma",Font.BOLD,16));
        	
        	offscreen.setColor(Color.white); 
        	offscreen.fillRect(0,0,this.getSize().width,this.getSize().height);  //clear
        	
		offscreen.drawImage(back,0,0,this);
		
		offscreen.setColor(new Color(0,83,166));
		offscreen.fillRect(0,300,300,28);
		offscreen.setColor(Color.white);
		
		if(!inGameOver){
			offscreen.setFont(new Font("Tahoma",Font.BOLD,16));
			offscreen.drawString("WWW.EUROPEANHERO.COM",34,320);
		}
		else{
			offscreen.setFont(new Font("Tahoma",Font.BOLD,10));
			offscreen.drawString("COFFER VENGEANCE IS PART OF THE EH GALAXY.",22,318);
		}
		
		offscreen.setColor(new Color(0,128,255));
		//offscreen.setColor(new Color(0,0,0));
		offscreen.drawRect(0,300,299,27);
		offscreen.setColor(new Color(119,187,255));
		offscreen.drawRect(1,301,297,25);
		offscreen.setColor(new Color(179,255,255));
		offscreen.drawRect(2,302,295,23);
		
		if(showCrate){
			offscreen.drawImage(crate,xPosCrate,yPosCrate,this);
		}
		
		paintPrismos(offscreen);
		paintBullets(offscreen);
		paintCofferBullets(offscreen);
		
		if(death_timer==0 && !inGameOver){
			offscreen.drawImage(player,x,y,this);
			
			if(shieldTimer>0){
				if(shieldTimer<200){
					offscreen.setColor(new Color(0,200,0,100));
					offscreen.fillOval(x-4,y-5,40,40);
					offscreen.setColor(new Color(0,255,0));
					offscreen.drawOval(x-4,y-5,40,40);
				}
				else if(shieldTimer<275){
					offscreen.setColor(new Color(0,200,0,75));
					offscreen.fillOval(x-4,y-5,40,40);
					offscreen.setColor(new Color(0,230,0));
					offscreen.drawOval(x-4,y-5,40,40);
				}
				else if(shieldTimer<290){
					offscreen.setColor(new Color(0,200,0,50));
					offscreen.fillOval(x-4,y-5,40,40);
					offscreen.setColor(new Color(0,205,0));
					offscreen.drawOval(x-4,y-5,40,40);
				}
				else if(shieldTimer<300){
					offscreen.setColor(new Color(0,200,0,25));
					offscreen.fillOval(x-4,y-5,40,40);
					offscreen.setColor(new Color(0,180,0));
					offscreen.drawOval(x-4,y-5,40,40);
				}
			}
		}
		else{
			if(!inGameOver){
				if(death_timer<20){
					offscreen.drawImage(player_death,x-6,y,this);
				}
				else{
					if(death_timer<60){
						if(death_timer%6==0){
							offscreen.drawImage(player,x,y,this);
						}
					}
					else{
						if(death_timer%3==0){
							offscreen.drawImage(player,x,y,this);
						}
					}
				}
			}
			else{
				offscreen.drawImage(player_death,x-6,y,this);
			}
		}
		
		if(inInfoScreen){
			offscreen.setColor(new Color(50,50,50,200));
			offscreen.fillRect(20,20,260,260);
			
			offscreen.setColor(Color.white); 
			offscreen.drawRect(20,20,259,259);
			
			offscreen.setFont(new Font("Tahoma",Font.BOLD,16));
			offscreen.drawString("COFFER VENGEANCE",30,50);
			
			offscreen.setFont(new Font("Tahoma",Font.BOLD,12));
			offscreen.drawString("FED UP WITH THE SUPRESSION OF YOUR",30,75);
			offscreen.drawString("PEOPLE, YOU TAKE TO ARMS IN AN",30,90);
			offscreen.drawString("ATTEMPT TO WIPE OUT THE HOSTILE",30,105);
			offscreen.drawString("PRISMO FORCES. ",30,120);
			offscreen.drawString("",30,135);
			offscreen.drawString("GOOD LUCK SOLDIER!",30,150);
			
			offscreen.drawString("CONTROLS",30,210);
			offscreen.drawString("LEFT AND RIGHT ARROW KEYS FOR",30,225);
			offscreen.drawString("MOVEMENT. CTRL TO FIRE.",30,240);
			
			offscreen.drawString("PRESS CTRL TO START.",30,270);
		}
		else if(inGameOver){
			offscreen.setColor(new Color(50,50,50,200));
			offscreen.fillRect(20,20,260,260);
			
			offscreen.setColor(Color.white); 
			offscreen.drawRect(20,20,259,259);
			
			offscreen.setFont(new Font("Tahoma",Font.BOLD,16));
			offscreen.drawString("GAME OVER",102,100);
			
			offscreen.setFont(new Font("Tahoma",Font.BOLD,12));
			offscreen.drawString("YOUR SCORE WAS "+score+" POINTS.",50,160);
			offscreen.drawString("REACHED PHASE "+phase+" OF 30.",50,180);
			
			offscreen.drawString("PRESS ENTER TO RESTART.",50,270);	
		}
		else if(inVictoryScreen){
			offscreen.setColor(new Color(50,50,50,200));
			offscreen.fillRect(20,20,260,260);
			
			offscreen.setColor(Color.white); 
			offscreen.drawRect(20,20,259,259);
			
			offscreen.setFont(new Font("Tahoma",Font.BOLD,16));
			offscreen.drawString("VICTORY!",30,50);
			
			prismo_death_string=""+prismo_death_count;
			
			if(prismo_end_timer<5){
				offscreen.drawImage(prismo,130,80,this);
			}
			else{
				offscreen.drawImage(prismoopen,130,80,this);
			}
			
			offscreen.setFont(new Font("Tahoma",Font.BOLD,12));
			offscreen.drawString("THIS IS INSANE! YOU'VE SLAUGHTERED",30,140);
			if(prismo_death_count<1000){
				offscreen.drawString("OVER "+prismo_death_string+" OF OUR BEST SOLDIERS!",30,155);
			}
			else if(prismo_death_count>999 && prismo_death_count<10000){
				offscreen.drawString("OVER "+prismo_death_string.substring(0,1)+"."+prismo_death_string.substring(1,4)+" OF OUR BEST SOLDIERS!",30,155);
			}
			else if(prismo_death_count>9999 && prismo_death_count<100000){
				offscreen.drawString("OVER "+prismo_death_string.substring(0,2)+"."+prismo_death_string.substring(2,5)+" OF OUR BEST SOLDIERS!",30,155);
			}
			//offscreen.drawString("OF OUR BEST SOLDIERS!",30,105);
			offscreen.drawString("WE SURRENDER...",30,170);
			
			offscreen.drawString("YOUR SCORE WAS "+score+" POINTS.",30,210);
			offscreen.drawString("REACHED PHASE "+phase+" OF 30.",30,230);
			
			offscreen.drawString("PRESS ENTER TO RESTART.",30,270);	
			
		}
		else{
			offscreen.setFont(new Font("Tahoma",Font.BOLD,12));
			offscreen.setColor(Color.white);
			offscreen.drawString("S="+score,10,20);	
			offscreen.drawString("L="+lives,10,35);	
			offscreen.drawString("R="+rockets,10,50);
			
			
			
			if(crate_appear-crate_timer>-1){
				offscreen.drawString("NEXT CRATE",190,20);	
				offscreen.drawString("=",267,20);	
				offscreen.drawString(""+(crate_appear-crate_timer),280,20);	
			}
			else{
				offscreen.drawString("NEXT CRATE",190,20);	
				offscreen.drawString("=",267,20);	
				offscreen.drawString("X",280,20);	
			}
		}
						
		g.drawImage(offscreenImage,0,0,null); //Print the entire double buffered screen.
	}
	
	public void paintPrismos(Graphics offscreen){
		for(int i=0;i<nrOfPrismos;i++){
			if(alivePrismo[i]){ //Animate the prismo(walking and shooting)
				if(timerPrismo[i]<5){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<10){
					offscreen.drawImage(prismo_walk_left,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<15){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<20){
					offscreen.drawImage(prismo_walk_right,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<25){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<30){
					offscreen.drawImage(prismo_walk_left,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<35){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<40){
					offscreen.drawImage(prismo_walk_right,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<45){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<50){
					offscreen.drawImage(prismo_walk_left,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<55){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<60){
					offscreen.drawImage(prismo_walk_right,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<65){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<70){
					offscreen.drawImage(prismo_walk_left,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<75){
					offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<80){
					offscreen.drawImage(prismo_walk_right,xPosPrismo[i],yPosPrismo[i],this);
				}
				else if(timerPrismo[i]<90){
					if(timerPrismo[i]==80){
						if(fireBullet(i)){ //If there are still bullets available
							shootPrismo[i]=true; //Paint a shooting prismo.
							offscreen.drawImage(prismo_shoot,xPosPrismo[i],yPosPrismo[i],this);
						}
						else{ //If there are no bullets available
							shootPrismo[i]=false; //Paint standing prismo.
							timerPrismo[i]=0;
							offscreen.drawImage(prismo_stand,xPosPrismo[i],yPosPrismo[i],this);
						}
					}
					else{
						offscreen.drawImage(prismo_shoot,xPosPrismo[i],yPosPrismo[i],this);	
					}
				}
			}
			else{
				if(timerPrismo[i]<0){
					offscreen.drawImage(prismo_death,xPosPrismo[i]-8,yPosPrismo[i]-9,this);	
				}
			}
		}
	}
	
	public void paintBullets(Graphics offscreen){
		for(int i=0;i<nrOfBullets;i++){
			if(firedBullet[i]){
				if(timerBullet[i]<5){
				}
				else if(timerBullet[i]<10){
					offscreen.drawImage(bullet1,xPosBullet[i],yPosBullet[i],this);
				}
				else{
					offscreen.drawImage(bullet2,xPosBullet[i],yPosBullet[i],this);
				}
			}
		}
	}
	
	public void paintCofferBullets(Graphics offscreen){
		for(int i=0;i<nrOfCofferBullets;i++){
			if(firedCofferBullet[i]){
				if(typeCofferBullet[i]==0){
					offscreen.drawImage(cannon_green,xPosCofferBullet[i],yPosCofferBullet[i],this);
				}
				else{
					offscreen.drawImage(shotgun_green,xPosCofferBullet[i],yPosCofferBullet[i],this);
				}
			}
		}
	}
	
	public void destroy(){ //if the applet is closed, the loop is ended
        	if(proces!=null)
            	proces.stop(); 
        }
        
        public void updateSoundTimers(){
        	//Update timers for all sounds currently playing, and trigger permission 
       		//for a sound to play again.
       		for(int i=0;i<4;i++){ 
       			if(sound_timer[i]!=0){
       				sound_timer[i]++;
       				
       			}
       			
       			switch(i){
       				case 0: //Reset "player_gun" timer
       					if(sound_timer[i]>20){
       						sound_timer[i]=0;
       					}
       				break;
       				case 1: //Reset "player_cannon" timer
       					if(sound_timer[i]>20){
       						sound_timer[i]=0;
       					}
       				break;
       				case 2: //Reset "prismo_death" timer
       					if(sound_timer[i]>5){
       						sound_timer[i]=0;
       					}
       				break;
       				case 3: //Reset "player_death" timer
       					if(sound_timer[i]>20){
       						sound_timer[i]=0;
       					}
       				break;
       			}
       		}
        }
        
        public void placePrismos(){
        	if(prismo_timer>prismo_release_rate){
        		int prismo_needed=prismo_releases;
        		
        		if(prismos_in_field<prismos_allowed){
        		
	        		prismo_timer=0;
	        		for(int i=0;i<nrOfPrismos;i++){
					if(!alivePrismo[i] && timerPrismo[i]>=0){
						prismo_needed--;
						prismos_in_field++;
						
						alivePrismo[i]=true;
						xPosPrismo[i] = 10 + (int)(Math.random() * 280);
						yPosPrismo[i] = -10;
						
						yChangePrismo[i] = 1;
						xChangePrismo[i] = (int)(Math.random() * 2);
						
						if(xChangePrismo[i]== 0){
							xChangePrismo[i]=-1;
						}
						
						timerPrismo[i]=0;
						
						speedPrismo[i]= 1 + (int)(Math.random() * 4);
					}
					if(prismo_needed==0){
						break;
					}
				}	
			}
		}
        }
        
        public void movePrismos(){
        	for(int i=0;i<nrOfPrismos;i++){
			if(alivePrismo[i] && timerPrismo[i]>=0){
				if(timerPrismo[i]%speedPrismo[i]==0){
					//timerPrismo[i]=0;
					
					if(timerPrismo[i]<45){
						xPosPrismo[i]+= xChangePrismo[i];
					}
					
					if(xPosPrismo[i]<5){
						xChangePrismo[i]=-xChangePrismo[i];
					}
					
					if(xPosPrismo[i]>295-prismoWidth){
						xChangePrismo[i]=-xChangePrismo[i];
					}
				
				
					if(timerPrismo[i]<80){
						yPosPrismo[i]+= yChangePrismo[i];
					}
					
					if(yPosPrismo[i]>200){
						if(speedPrismo[i]>1){
							speedPrismo[i]--;
						}
						yChangePrismo[i]=-yChangePrismo[i];
					}
					
					if(yPosPrismo[i]<0 && yChangePrismo[i]<0){
						yChangePrismo[i]=-yChangePrismo[i];
					}
					
				}
				
				timerPrismo[i]++;
				
				if(timerPrismo[i]==90){timerPrismo[i]=0;}
			}
			else{
				timerPrismo[i]++;
			}
		}
        }
        
        public boolean fireBullet(int prismo){
        	boolean bullet_found=false;
        		
        		for(int i=0;i<nrOfBullets;i++){
				if(!firedBullet[i]){
					bullet_found=true;
					
					firedBullet[i]=true;
					xPosBullet[i] = xPosPrismo[prismo];
					yPosBullet[i] = yPosPrismo[prismo]+15;
					
					//yChangeBullet[i] = prismo_bullet_speed;
					xChangeBullet[i] = 0;
					
					timerBullet[i]=0;
				}
				if(bullet_found){
					break;
				}
			}	
        	return bullet_found;
        }
        
        public void fireCofferBullet(int type){
        	boolean bullet_found=false;
        		
        		
        		if(type==0){
	        		if(firePermission){
		        		for(int i=0;i<nrOfCofferBullets;i++){
						if(!firedCofferBullet[i]){
							bullet_found=true;
							
							firedCofferBullet[i]=true;
							xPosCofferBullet[i] = x+20;
							yPosCofferBullet[i] = y;
							
							yChangeCofferBullet[i] = -4;
							xChangeCofferBullet[i] = 0;
							
							typeCofferBullet[i] = 0;
													
							if(sound_timer[0]==0){
								sound_timer[0]=1;
								shoot1.play();
							}

						}
						if(bullet_found){
							break;
						}
					}	
				}
			}
			else{
				int needed = 5;
				
				for(int i=0;i<nrOfCofferBullets;i++){
					if(!firedCofferBullet[i]){
						needed--;
						
						firedCofferBullet[i]=true;
						xPosCofferBullet[i] = x+11;
						yPosCofferBullet[i] = y+11;
						
						yChangeCofferBullet[i] = -4;
						
						switch(needed){
							case 4:
								xChangeCofferBullet[i] = -2;
							break;
							case 3:
								xChangeCofferBullet[i] = -1;
							break;
							case 2:
								xChangeCofferBullet[i] = 0;
							break;
							case 1:
								xChangeCofferBullet[i] = 1;
							break;
							case 0:
								xChangeCofferBullet[i] = 2;
							break;
						}
													
						if(sound_timer[1]==0){
							sound_timer[1]=1;
							shoot2.play();
						}
							
						
						typeCofferBullet[i] = 1;
						
						//timerCofferBullet[i]=0;
					}
					if(needed==0){
						break;
					}
				}	
			}
        	
        }
        
        public void moveCofferBullets(){
        	for(int i=0;i<nrOfCofferBullets;i++){
			if(firedCofferBullet[i]){	
				yPosCofferBullet[i]+=yChangeCofferBullet[i];
				xPosCofferBullet[i]+=xChangeCofferBullet[i];
				
				if(yPosCofferBullet[i]<-10){
					firedCofferBullet[i]=false;
				}
				
				
				for(int j=0;j<nrOfPrismos;j++){
					if((xPosCofferBullet[i]+4>xPosPrismo[j] && xPosCofferBullet[i]<xPosPrismo[j]+prismoWidth) && (yPosCofferBullet[i]<yPosPrismo[j]+prismoHeight && yPosCofferBullet[i]+8>yPosPrismo[j]) && alivePrismo[j]){
						firedCofferBullet[i]=false;
						
						alivePrismo[j]=false;
						prismos_in_field--;
						
						prismo_death_count++;
						
						score+=10;
						
						if(score%2500==0){
							lives++;
						}
						
						timerPrismo[j]=-60;
						
						if(sound_timer[2]==0){
							sound_timer[2]=1;
							hit.play();
						}
					}
				}
			}
		}	
        }
        
        public void moveBullets(){
        	for(int i=0;i<nrOfBullets;i++){
			if(firedBullet[i]){	
				timerBullet[i]++;
				
				if(timerBullet[i]>15){timerBullet[i]=5;}
				
				yPosBullet[i]+=yChangeBullet[i];
				xPosBullet[i]+=xChangeBullet[i];
				
				if(yPosBullet[i]>300){
					firedBullet[i]=false;
				}
				
				if(timerBullet[i]==4){
					yChangeBullet[i]=prismo_bullet_speed;	
				}
				
				if((xPosBullet[i]+5>x+2 && xPosBullet[i]<x+(cofferWidth-2)) && (yPosBullet[i]+5>y+8 && yPosBullet[i]<y+(cofferHeight-2))){
					if(death_timer==0){
						firedBullet[i]=false;
						
						if(shieldTimer==0){
							lives--;
							
							death_timer=1;
							
							if(lives<=0){
								if(!inGameOver){
									gameover.play();
								}
								
								inGameOver=true;
								
								
							}
							else{
								if(sound_timer[3]==0){
									sound_timer[3]=1;
									death.play();
								}
							}
						}
					}
				}
			}
		}
        }
        
        public void firePermissionCheck(){
        	int bullets_fired=0;
        	
        	for(int i=0;i<nrOfCofferBullets;i++){
			if(firedCofferBullet[i]){
				bullets_fired++;
			}
		}
		if(bullets_fired>4){
			firePermission=false;
		}
		else{
			firePermission=true;
		}
        }
        
        public void crateCheck(){
        	if(x+cofferWidth>xPosCrate && x<xPosCrate+25 && showCrate){
        		showCrate = false;
        		crate_timer=0;
        		crate_appear=8 + (int)(Math.random() * crate_random_time);
        		rockets += 5;
        		shieldTimer = 1;
        	}
        	
        	if(showCrate){
        		showCrateTimer++;
        		
        		if(showCrateTimer>300){
        			showCrate = false;
        			crate_timer=0;
        			crate_appear=8 + (int)(Math.random() * crate_random_time);
        		}	
        	}
        	
        	if(shieldTimer>0){
        		shieldTimer++;
        		
        		if(shieldTimer>400){
        			shieldTimer=0;
        		}
        	}
        }
        
        public void updateTimers(){
        	if(!inInfoScreen){
        	
	        	if(System.currentTimeMillis()-time>1000){
		       		seconds++;
		       		crate_timer++;
		       		game_timer++;
		       		prismo_timer++;
		       		time+=1000;
		       	}
		       	
		       	if(crate_timer>crate_appear && !showCrate){
		       		xPosCrate = (int)(Math.random() * 2);
		       		if(xPosCrate==1){
		       			xPosCrate = xPosCrate1;
		       		}
		       		else{
		       			xPosCrate = xPosCrate2;
		       		}
		       		
		       		showCrate=true;
		       		showCrateTimer=0;
		       		
		       	}
		       	
		       	
		       	if(game_timer>game_next_phase){ //Go to the next phase.
		       		game_timer=0;
		       		
		       		if(!inGameOver && phase<30){
		       			phase++;
		       		}
		       		
		       		if(prismo_release_rate>0){ //Increase release_rate(interval between incoming prismos).
		       			prismo_release_rate--;
		       		}
		       		else{
		       			if(prismo_releases<5){ //Increase prismo_releases(number of incoming prismos per release).
		       				prismo_releases++;
		       			}
		       			else{
		       				if(prismos_allowed<20){ //Increase total prismo_allowed(maximum of prismos allowed on-screen).
		       					prismos_allowed++;
		       				}
		       				else{
		       					if(prismo_releases<15){
		       						prismo_releases+=3;
		       					}
		       					else{
		       						if(prismos_allowed<46){
		       							if(prismo_releases<50){
		       								prismo_releases+=5;
		       							}
		       							if(prismos_allowed<46){
			       							prismos_allowed+=2;
			       						}
		       						}
		       						else{
		       							if(prismo_bullet_speed<3){ //Increase prismo_bullet_speed(speed of prismo bullets).
		       								prismo_bullet_speed++;
		       							}
		       							else{ //If maximum phase has been reached
		       								if(!inVictoryScreen && !inGameOver){
		       									victory.play();
		       								}
		       								
		       								//Goto victory screen.
		       								inVictoryScreen=true;
									
										
		       							}
		       						}
							}
		       				}
		       			}
		       		}
		       	}
		}
        }
	
	public void handleKeyboard(){
		if(!inInfoScreen && !inGameOver && !inVictoryScreen){ //If in-game
			if(left){x=x-4;} //If keyboard left has been pressed decrease x by 4 pixels.
			if(right){x=x+4;} //If keyboard right has been pressed increase x by 4 pixels.
			
			if(x>rightBorder-cofferWidth-5){x=x-4;} //If x exceedes the right border substract 4 again.
			if(x<leftBorder){x=x+4;} //If x exceedes the left border add 4 again.
		}
		
		if(ctrl){ //If fire button has been pressed
			if(inInfoScreen){
				ctrl=false;
				time=System.currentTimeMillis(); 
				inInfoScreen=false;
			}
			else if(inGameOver){
				
			}
			else if(inVictoryScreen){
				
			}
			else{ //If in-game
				ctrl=false; //Disable fire button flag(so that you have to press it again to fire; no auto-fire).
				
				if(rockets>0){ //If rockets
					rockets--;
					fireCofferBullet(1); //Fire rocket
				}
				else{ //If no rockets
					fireCofferBullet(0); //Fire normal bullet
				}
			}
		}
		if(enter){ //If enter button has been pressed
			if(inGameOver){
				enter=false;
				resetProperties();
			}
			else if(inVictoryScreen){
				enter=false;
				resetProperties();	
			}	
		}
	}
	
	public void checkMouseEE(){ //Check if the mousepointer is on the banner
		if((mouseX>=bannerX&&mouseX<=bannerX+bannerWidth-1)&&(mouseY>=bannerY&&mouseY<=bannerY+bannerHeight-1)){
    			if(notClicked){
    				getAppletContext().showStatus("Click to visit www.europeanhero.com!"); //Set browser status bar.
    				setCursor(new Cursor(12)); //Change mouse cursor to link hand.	
    			}
    		}
    		else{
    			getAppletContext().showStatus("");  //Set browser status bar.
    			setCursor(new Cursor(0)); //Change mouse cursor back.	
    		}	
	}
	
	public void bannerClicked(){ //Performs actions when mouse is clicked on banner
		notClicked=false;
		
		try{
			bannerURL=new URL("http://www.europeanhero.com");
		}
		catch(MalformedURLException e){System.out.println("invalid URL!");
		}
		if(bannerURL!=null){
			getAppletContext().showStatus("");
    			setCursor(new Cursor(0));
			
			getAppletContext().showDocument(bannerURL);
		}
	}
	
	public void loadImages(){ 
		MediaTracker mt = new MediaTracker(this); //Use a mediatracker to load the images.
		back = getImage(getDocumentBase(),"data/back.gif"); //Retrieve the image from the JAR file.
		mt.addImage(back, 0); //Add the image to the mediatracker at position 0.
		player = getImage(getDocumentBase(),"data/player.gif");
		mt.addImage(player, 1);
		crate = getImage(getDocumentBase(),"data/crate.gif");
		mt.addImage(crate, 2);
		prismo_stand = getImage(getDocumentBase(),"data/prismo_stand.gif");
		mt.addImage(prismo_stand, 3);
		prismo_walk_left = getImage(getDocumentBase(),"data/prismo_walk_left.gif");
		mt.addImage(prismo_walk_left, 4);
		prismo_walk_right = getImage(getDocumentBase(),"data/prismo_walk_right.gif");
		mt.addImage(prismo_walk_right, 5);
		prismo_shoot = getImage(getDocumentBase(),"data/prismo_shoot.gif");
		mt.addImage(prismo_shoot, 6);
		bullet1 = getImage(getDocumentBase(),"data/bullet1.gif");
		mt.addImage(bullet1, 7);
		bullet2 = getImage(getDocumentBase(),"data/bullet2.gif");
		mt.addImage(bullet2, 8);
		player_death = getImage(getDocumentBase(),"data/player_death.gif");
		mt.addImage(player_death, 9);
		prismo_death = getImage(getDocumentBase(),"data/prismo_death.gif");
		mt.addImage(prismo_death, 10);
		cannon_green = getImage(getDocumentBase(),"data/cannon_green.gif");
		mt.addImage(cannon_green, 11);
		shotgun_green = getImage(getDocumentBase(),"data/shotgun_green.gif");
		mt.addImage(shotgun_green, 12);
		prismo = getImage(getDocumentBase(),"data/prismo.gif");
		mt.addImage(prismo, 13);
		prismoopen = getImage(getDocumentBase(),"data/prismoopen.gif");
		mt.addImage(prismoopen, 14);
		try{
			mt.waitForAll(); //Wait for all images to be loaded(to prevent the game from starting before the images are loaded; causes flickering).
			System.out.println("Images loaded!");
		}
		catch(Exception e){
			System.err.println("Could not load images");
			System.err.println(e);
			e.printStackTrace();
		}
	}
	
	
	public void keyPressed(KeyEvent e) { //The keyEvent handler(pressed).
		if (e.getKeyCode() == 37)
	      		left = true;
	    	if (e.getKeyCode() == 39)
	      		right = true;
	    	if (e.getKeyCode() == 38)
	      		up = true;
	    	if (e.getKeyCode() == 40)
	      		down = true;
	      	if (e.getKeyCode() == KeyEvent.VK_CONTROL){
	      		if(!pressedShot){ //Check pressedShot flag so you can only shoot again if key is released and pressed again.
	      			pressedShot = true;
      				ctrl = true;
      			}
      		}
      		if (e.getKeyCode() == 10)
      			enter = true;
	}
	
	public void keyReleased(KeyEvent e) { //The keyEvent handler(released).
		if (e.getKeyCode() == 37)
	      		left = false;
	    	if (e.getKeyCode() == 39)
	      		right = false;
	    	if (e.getKeyCode() == 38)
	      		up = false;
	    	if (e.getKeyCode() == 40)
	      		down = false;
	      	if (e.getKeyCode() == KeyEvent.VK_CONTROL){
	      		pressedShot = false; //Set pressedShot flag so permission is given to shoot again if CTRL is pressed again.
      			ctrl = false;
      		}
      		if (e.getKeyCode() == 10)
      			enter = false;
	}

	public void keyTyped(KeyEvent e) {} //Currently unused listener methods.

	public void mouseMoved(MouseEvent event){ //Keeps track of mouse x and y coordinates.
		mouseX = event.getX();
		mouseY = event.getY();
	}
	public void mouseClicked (MouseEvent event){ //Check if the mouse was clicked from within the banner area.
		if((mouseX>=bannerX&&mouseX<=bannerX+bannerWidth-1)&&(mouseY>=bannerY&&mouseY<=bannerY+bannerHeight-1)){
    			bannerClicked();
    		}
	}
	
    	public void mouseDragged(MouseEvent event){} //Unused listener methods.	
    	public void mouseReleased (MouseEvent event){}
    	public void mousePressed (MouseEvent event){}
    	public void mouseEntered (MouseEvent event){}
    	public void mouseExited (MouseEvent event){}
}
