import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;



public class alienbillhorde extends Applet implements Runnable, MouseMotionListener {
	Thread animation;

	int BILL_HEIGHT = 32;
	int BILL_WIDTH = 32;
	int BILL_FRAMES = 5;
	int BILL_FRAMELENGTH = 5;//5;

	private int mouseX = -100, mouseY = -100;

	int screenWidth,screenHeight ;
	Graphics offscreenGraphics;
	Image offscreenImage;
	Color screenColor = Color.white;
	static final int REFRESH_RATE = 30;//30; // in ms, target time between clicks
	long oldTime; //used for time keeping

	Image imgBill,imgBillFlip;

	alienbill bills[];

	public void init() {
		screenWidth = getBounds().width;            // get applet dimensions
		screenHeight = getBounds().height;
		offscreenImage = createImage(screenWidth,screenHeight); // make offscreenGraphics buffer
		offscreenGraphics = offscreenImage.getGraphics();

		//setupGame(); //run game setup routine
		setBackground(screenColor);        // applet background

		imgBill = getImage(getCodeBase(), "billstrip.gif");
		imgBillFlip = getImage(getCodeBase(), "billstrip_mirror.gif");

		if(imgBill == null) {
				System.out.println("can't load imgBill");
		}

		bills = new alienbill[screenHeight];

		addMouseMotionListener(this);





		oldTime = System.currentTimeMillis(); //setting clocktracker
	}


	public void run() {
		while (true) {
			repaint();
			Thread.currentThread().yield();
			long newTime = System.currentTimeMillis();
			try {
				if(oldTime + REFRESH_RATE > newTime){
					Thread.sleep (oldTime+REFRESH_RATE-newTime);
				}
			} catch (Exception exc) { };
			oldTime = newTime;
		}
	}

	public void start() {
		animation = new Thread(this);
		if (animation != null) {
			animation.start();
		}
	}



	// override update so it doesn't erase screen
	public void update(Graphics g) {
		paint(g);
	}



	public void paint(Graphics g) {

		offscreenGraphics.setClip(0,0,screenWidth,screenHeight);
		offscreenGraphics.setColor(screenColor);
		offscreenGraphics.fillRect(0,0,screenWidth,screenHeight);  // clear buffer

		showBills(offscreenGraphics);  //game expected to drawitself

		addBill();

		g.drawImage(offscreenImage,0,0,this);
	}



	public void addBill(){
			int newPosPos = (int)(Math.random() * (screenHeight-BILL_HEIGHT));

			if(bills[newPosPos] == null){
				bills[newPosPos] = new alienbill(-1 * BILL_WIDTH,newPosPos,imgBill,imgBillFlip);

			}


	}


	public void showBills(Graphics g){

		//g.drawImage(imgBill,200,200,this);

		for(int i = 0; i < screenHeight; i++){
			if(bills[i] != null){
				alienbill thisBill = bills[i];


				thisBill.checkHit(mouseX,mouseY);
				thisBill.move();
				thisBill.draw(g,this);

				if(thisBill.isOffside(screenWidth)){
						thisBill = null;
						bills[i] = null;
				}

			}
		}







	}





	public void mouseMoved(MouseEvent e) {
		updateMousePos(e);
	}
	public void mouseDragged(MouseEvent e) {
		updateMousePos(e);
	}

	public void updateMousePos(MouseEvent e){
			mouseX = e.getX();
			mouseY = e.getY();

	}


	public class alienbill implements Comparable {
		private int top;
		private int left;
		private Image img;
		private Image imgflip;
		private Image currentimg;

		private int frame;
		private int framedir = 1;

		private int framecounter;

		private int dir;
		private boolean mouseIsOver = false;


		public alienbill(int l, int t, Image i, Image iflip){
			top = t;
			left = l;
			img = i;
			imgflip = iflip;
			frame = (int)(Math.random() * BILL_FRAMES);
			framecounter = (int)(Math.random() * BILL_FRAMELENGTH);
			currentimg = img;
			dir = 1;
		}

		public int getTop(){
			return top;
		}
		public int getLeft(){
			return left;
		}
		public int compareTo(Object o){
			alienbill ab = (alienbill)o;
			return top - ab.getTop();
		}

		public void draw(Graphics g, Applet a){
			g.setClip(left,top,BILL_WIDTH,BILL_HEIGHT);
			//System.out.println(frame);
			g.drawImage(currentimg , left , top - (frame * BILL_HEIGHT), a);
		}
		public void move(){
				framecounter--;
				//System.out.println(framecounter);

//				if(framecounter > 3){
					//int r = ((int)(Math.random() * 5));
					//if(r > 0){
						left+=dir;

				//}
//			}
				if(framecounter <= 0){
					framecounter = BILL_FRAMELENGTH;
					frame += framedir;
					if(frame >= BILL_FRAMES){
						frame = BILL_FRAMES-2; //-2 ??
						framedir = -1;
					}
					if(frame < 0){
						frame = 1;  //1?
						framedir = 1;
					}
			}




		}

		public void checkHit(int mx, int my){
			if(mx >= left && mx < left + BILL_WIDTH &&
			   my >= top  && my < top  + BILL_HEIGHT){
				   if(! mouseIsOver ){
					   mouseIsOver = true;
						dir *= -1;
						if(dir == 1){
							currentimg = img;
						} else {
							currentimg = imgflip;
						}
				   }


			} else {
					mouseIsOver = false;
			}
		}


		public boolean isOffside(int screenright){
			if(dir == 1 && left > screenright){
				return true;
			}
			if(dir == -1 && left < -4 - BILL_WIDTH){
				return true;
			}
			return false;
		}

	}


}