/***********************************************************************************************
	Klassenavn: car
	Arver: sprite
	Beskrivelse:	kontrollerer delvis en bils bevegelse
								farger en bil i en gitt RGB farge
************************************************************************************************/
import java.awt.*;
import java.applet.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.lang.Math;
import sprite;

public class car extends sprite {

	private static final int totalPics = 2;			// Totalt antall animasjonsbilder
	private static final int picWidth = 61;			// Bredden..
	private static final int picHeight = 24; 		// ..og høyden på animasjonsbildene

	private Image pics[] = new Image[totalPics];		// Bilder av bilen i to retninger

	// Statisk data for "ufarget" bil:

	private static Image carsUnpainted = null;		
	private static final String rawImageName = "cars.gif";
	private static int carRawData[]=new int[picWidth*picHeight*16];
	private static int carData[]=new int[picWidth*picHeight*16];
	private static int colorTable[]= new int[256];
	private static final int transparentColor = 8421504;
	
	private AudioClip honkSound = null;
	private final int timeBetweenHonks = 700;
	private long timeSinceHonk;

			
	private int picnr = 1;							// Det aktive animasjonsbildet som skal vises 
	private int moveStatus = 0;				

	private int speed = 6;			// Antall pixels pr. bevegelse i en vilkårlig retning       
	
	/***********************************************************************************************
		Metodenavn: car (konstruktør)
		Beskrivelse: setter farge på en bil, henter inn lyd/bilde		
	************************************************************************************************/
		
	public car(double red, double green, double blue, Graphics g, Applet applet){

		parentApplet = applet;
		offScrGC = g;		
		pics = new Image[totalPics];
		tracker = new MediaTracker(parentApplet);
		
		honkSound = parentApplet.getAudioClip(parentApplet.getCodeBase(),"horn.au");
		honkSound.play(); honkSound.stop(); // For å starte nedlasting (Netscape venter til lyden skal spilles)
		
		x_pos = -100;
		y_pos = -100;
		
		collision = new Rectangle(3,6,55,16); // Rektangel for å avgjøre kollisjon med andre spriter

		if (carsUnpainted == null){	// Hvis det statiske bildet ikke er hentet..
			try {
				// Henter inn:
				
				carsUnpainted = parentApplet.getImage(parentApplet.getCodeBase(), rawImageName);
		   	tracker.addImage(carsUnpainted,99);
				tracker.waitForID(99);
		
			} catch (Exception e) {e.printStackTrace();}
	
			// Bruker pixelgrabber for å kunne forandre fargen på hver pixel i bildet:
			
			PixelGrabber pg;
			pg = new PixelGrabber(carsUnpainted,0,0,totalPics*picWidth,picHeight,carRawData,0,totalPics*picWidth);

			try	{pg.grabPixels();	}	catch(InterruptedException e) {}
		}
		
		makeColorTable(red,green,blue);	// lager farger til bilen
		prepareAndPaint();								// lager bil med farge
	}
	
	/***********************************************************************************************
		Metodenavn: honk
		Beskrivelse: lager en tutelyd
	************************************************************************************************/	
	public void honk(){
		if (System.currentTimeMillis() - timeSinceHonk > timeBetweenHonks){
			timeSinceHonk = System.currentTimeMillis();
			honkSound.play();
		}
	}
	
	/***********************************************************************************************
		Metodenavn: inHonkRange
		Beskrivelse: sjekker om en sprite er innenfor bilens tute-rekkevidde
	************************************************************************************************/
	public boolean inHonkRange(sprite s){

		Rectangle r1 = new Rectangle(collision.x+x_pos,collision.y+y_pos,collision.width,collision.height);
		Rectangle r2 = new Rectangle(s.collision.x+s.x_pos,s.collision.y+s.y_pos,s.collision.width,s.collision.height);

		//r1.grow(0,10);	
		
		if (moveStatus == 1) r1.x += 20*speed;
		else if (moveStatus == 2) r1.x -= 20*speed; 
		 
		return r1.intersects(r2);
	} 
	
	
	/***********************************************************************************************
		Metodenavn: initDrive
		Beskrivelse: tilbakestiller bilens bevegelse
	************************************************************************************************/
	public void initDrive(int status, int x,int y, int sp){
		x_pos = x; y_pos = y;
		moveStatus = status;
		
		if (status == 1) picnr = 1;
		else picnr = 0;
		
		speed = sp;  
	}
	
	/***********************************************************************************************
		Metodenavn: drive
		Beskrivelse: beveger bilen i en bestemt retning (hvis mulig)
	************************************************************************************************/
	public void drive(){
		if (moveStatus == 0) return;	// bilen står stille eller er ikke synlig
		
		if (moveStatus == 1) x_pos += speed;				// bilen går mot høyre..
		else if (moveStatus == 2) x_pos -= speed;	// ..eller mot venstre
	}
	
	
	/***********************************************************************************************
		Metodenavn: getStatus
		Beskrivelse: returnerer bilens bevegelses-status
	************************************************************************************************/
	public int getStatus(){return moveStatus;}
	
	/***********************************************************************************************
		Metodenavn: setStatus
		Beskrivelse: setter bilens bevegelses-status
	************************************************************************************************/
	public void setStatus(int s){moveStatus = s;}
	
	/***********************************************************************************************
		Metodenavn: stop
		Beskrivelse: stopper bilen
	************************************************************************************************/
	public void stop(){moveStatus = 0;}
	
	
	/***********************************************************************************************
		Metodenavn: prepareAndPaint
		Beskrivelse: deler opp bilbildet i to separate bilder, og gir bilen en farge
	************************************************************************************************/
	public void prepareAndPaint(){
		
		int i; 
		
		for (i=0; i<totalPics; i++)	{
			pics[i] = parentApplet.createImage(new MemoryImageSource(picWidth,picHeight,carData,i*picWidth,totalPics*picWidth));
			tracker.addImage(pics[i],totalPics);
		}
		
		for (i=0; i<totalPics*picWidth*picHeight; i++){
			if (carRawData[i] != transparentColor) carData[i]=colorTable[carRawData[i]&255];
			else carData[i]=carRawData[i];
		}
		
		for (i=0;i<totalPics;i++) pics[i].flush();
		
		try	{tracker.waitForID(2);	}	catch(InterruptedException e) {}	
	}
	
	
	/***********************************************************************************************
		Metodenavn: draw
		Beskrivelse: tegner bilen til applet'ens offscreen-bilde
	************************************************************************************************/
	public void draw(){
		offScrGC.drawImage(pics[picnr],x_pos,y_pos,parentApplet);
	}
		
	/***********************************************************************************************
		Metodenavn: makeColorTable
		Beskrivelse: lager en farge tabell av 256 farger brukt til farging av biler
	************************************************************************************************/
	public void makeColorTable(double r, double g, double b){
		
		double rt=0,gt=0,bt=0,rd=2.0*r+0.01,gd=2.0*g+0.01,bd=2.0*b+0.01,shift;
		int i=0, j;
		
		for (j=0;j<4;j++){
			while ((rt<255.4) && (gt<255.4) && (bt<255.4) && (i<256)){
				colorTable[i] = 0xff000000 | (((int)rt)<<16) | (((int)gt)<<8) | ((int)bt);
				rt += rd;
				gt += gd;
				bt += bd;
				i++;
			}
			
			if (rt>255.4)	{rd=0; rt=255.1;}
			if (gt>255.4)	{gd=0; gt=255.1;}
			if (bt>255.4)	{bd=0;	bt=255.1;}
			
			shift = 2.0*(r+g+b)/(0.01+rd+gd+bd);
			rd *= shift; gd *= shift; bd *= shift;
		}
	}


}	// class car