import java.awt.event.*;
import java.awt.*;

public class KeyMonitor implements KeyListener {

    public void keyPressed(KeyEvent e) {
	addPressed(e.getKeyCode());
    }
    public void keyReleased(KeyEvent e) {
	addReleased(e.getKeyCode());
    }
    public void keyTyped(KeyEvent e) {
    }
    
    public synchronized void reset() {
	synchronized (Obj3) {
	    for (int x = 0; x < numReleased; x++) {
		remDown(keysReleased[x]);
	    }
	    synchronized (Obj2) {
		numPressed = 0;
	    }
	    numReleased = 0;
	}
    }
    public void addGenerator(Component c) {
	c.addKeyListener(this);
	c.requestFocus();
    }
    
    public boolean wasPressed(int key) {
	int z = 0;
	while ((z<numPressed)&&(keysPressed[z]!=key)) {
	    z++;
	}
	return (z!=numPressed);
    }
    public boolean isDown(int key) {
	int z = 0;
	while ((z<numDown)&&(keysDown[z]!=key)) {
	    z++;
	}
	return (z!=numDown);
    }
    public boolean wasReleased(int key) {
	int z = 0;
	while ((z<numReleased)&&(keysReleased[z]!=key)) {
	    z++;
	}
	return (z!=numReleased);
    }


    Object Obj1 = new Object();
    Object Obj2 = new Object();
    Object Obj3 = new Object();
    
    private void addPressed(int x) {
	synchronized (Obj1) {
	    int z = 0;
	    if (numPressed == 128)
		return;
	    while ((z<numPressed)&&(keysPressed[z]!=x)) {
		z++;
	    }
	    if (z==numPressed) {
		keysPressed[numPressed++]=x;
	    }
	}

	addDown(x);
    }
    private void addDown(int x) {
	synchronized (Obj2) {
	    int z = 0;
	    if (numDown == 128)
		return;
	    while ((z<numDown)&&(keysDown[z]!=x)) {
		z++;
	    }
	    if (z==numDown) {
		keysDown[numDown++]=x;
	    }
	}
    }
    private void remDown(int x) {
	synchronized (Obj2) {
	    int z = 0;
	    while ((z<numDown)&&(keysDown[z]!=x)) {
		z++;
	    }
	    if (z!=numDown) {
		keysDown[z]=keysDown[numDown--];
	    }
	}
    }
    private void addReleased(int x) {
	synchronized (Obj3) {
	    int z = 0;
	    if (numReleased == 128)
		return;
	    while ((z<numReleased )&&(keysReleased[z]!=x)) {
		z++;
	    }
	    if (z==numReleased) {
		keysReleased[numReleased++]=x;
	    }
	}
    }
    
    int[] keysDown = new int[256];
    int[] keysPressed = new int[256];
    int[] keysReleased = new int[256];
    int numDown = 0;
    int numReleased = 0;
    int numPressed = 0;
}
