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

//
//  FlashCards.java
//
//  A java game to practice with fractions.
//
// To do:  
//
//  making it a 2-player game.
//
//




public class AddCards extends Applet {

    int TOPTOTAL = 20;
    int MINTOTAL = 5;
    // if you want to change NUMFACTORS, the pickaPairaCards still
    // needs an easy modification
    int NUMFACTORS=3;

    static int SCALEMAX = 20;
    static int SCALEMAXE = 3;
    int NUMPAIRS = 8;
    
    static int TOTAL=0;
    static int SUM = 1;

    static int MULTIPLICATION =5;
    static int ADDITION = 4;
    
    boolean REP[];

    static int MAXMULT = 21;

    boolean ALLOWREPS = false;

    String playerName = "Keen Student";

    static int EASY = 0;
    static int MEDIUM = 1;
    static int HARD = 2;

    static int BOTTOMPANEL = 50;
    String SETTINGS = "Change Settings";
    String GAME = "Game";
	
    double factorForcing = 0.3;
    double sizeForcing =0.5;
    double scaleForcing = 0.5;
    Random generator;

    ACard stack[];
    ACard deck[];

    int upcards[] = {-1, -1};
    int lev = EASY;


    Button againButton;
    GameCanvas gameCanvas;
    Image cardBack=null;
    Image backgroundGif;
    Panel pages;
    Panel selectionPanel;
    Panel checkboxPanel;
    Checkbox cb[];
    Checkbox cbfor[];
    Panel pagefor2to11;
    Panel pagefor12to21;
    public TextField pname;
    TextField scoreField;
    int score;
    Checkbox animateBox;
    boolean animate;

    Choice numCardChoice;
    Choice maxNumChoice;
    Choice c;

    boolean done;
    Image offImage;

    Color cardBackground;
    int typeGame = ADDITION;
    int maxforTable = 10;
    boolean blackedOut[];
    int numNums;

    public void init() {
	generator = new Random(System.currentTimeMillis());
	cardBackground = Color.white;
	if(typeGame == MULTIPLICATION) {
	    numNums =9;
	    blackedOut = new boolean[MAXMULT+1];
	    blackedOut[0]=true;
	    blackedOut[1]=true;
	    for(int i = 2; i<11;i++) {
		blackedOut[i]=false;
	    }
	    for(int i = 11; i<22;i++) {
		blackedOut[i]=true;
	    }
	}
	REP = new boolean[NUMFACTORS];

	GridBagLayout gridbag = new GridBagLayout();
	GridBagConstraints con = new GridBagConstraints();
	setLayout(gridbag);

	pages =new Panel();
	pages.setSize(getSize().width, getSize().height-BOTTOMPANEL);
	pages.setLayout(new CardLayout());

	// FRATCION SPECIFIC

	// MULTIPLICATION SPECIFIC

	// SCORES
	scoreField = new TextField(40);
	scoreField.setEditable(false);

	newDeck();

	gameCanvas = new GameCanvas(this, getSize().height-BOTTOMPANEL, getSize().width);
	offImage = createImage(getSize().width, getSize().height-BOTTOMPANEL);

	//	Toolkit toolkit = Toolkit.getDefaultToolkit();
	cardBack = getImage(getCodeBase(),"card.gif");
	backgroundGif = getImage(getCodeBase(), "background.gif");
	if(cardBack == null) {
	    cardBack = createImage(gameCanvas.cardWidth, gameCanvas.cardHeight);
	    Graphics cardGraphics = cardBack.getGraphics();
	    cardGraphics.setColor(Color.black);
	    cardGraphics.fillRect(0,0,gameCanvas.cardWidth, gameCanvas.cardHeight);
	}

	//	add(gameCanvas);


	selectionPanel = new Panel();
	selectionPanel.setLayout(gridbag);
	// settle for the default layout for now
	

	// IF MULTIPLICATION

	Panel whichnumsPanel = new Panel();
	GridBagLayout gridbagsrevenge = new GridBagLayout();
	whichnumsPanel.setLayout(gridbagsrevenge);

	con.gridx=0;
	con.gridy=0;
	con.gridwidth=2;

	Panel animatePanel = new Panel();
	animateBox = new Checkbox("Animate Card Flipping?");
	animateBox.setState(true);
	animate = true;
	animatePanel.add(animateBox);

	Panel namePanel = new Panel();
	namePanel.setLayout(new GridLayout(1,2));
        namePanel.add(new Label("What's your name?"));
	pname = new TextField(25);	
	pname.setText(playerName);
	namePanel.add(pname);

	Panel maxNumPanel = new Panel();
	maxNumPanel.setLayout(new GridLayout(1,2));
	maxNumChoice = new Choice();
	for(int i=8;i<=20;i++) {
	    maxNumChoice.addItem(""+i);
	}
	maxNumChoice.select("20");
	maxNumPanel.add(new Label("Number bonds from 5 to  "));
	maxNumPanel.add(maxNumChoice);
	
	Panel numCardPanel = new Panel();
	numCardPanel.setLayout(new GridLayout(1,2));
	numCardChoice = new Choice();
	numCardChoice.addItem("12");
	numCardChoice.addItem("16");
	numCardChoice.addItem("20");
	numCardChoice.addItem("24");

	numCardChoice.select("16");
	numCardPanel.add(new Label("How many cards?"));
	numCardPanel.add(numCardChoice);


	// ADDING ALL THE STUFF TO THE SELECTION PANEL
	con.gridx = 0;
	con.gridy = 0;
	//	con.gridwidth = 3;
	con.gridheight = 1;
	con.gridwidth = GridBagConstraints.REMAINDER;
	con.weightx = 0.25;
	con.weighty = 0.25;

	gridbag.setConstraints(namePanel, con);
	selectionPanel.add(namePanel);

	con.gridy=1;
	con.gridwidth = 1;
	con.gridheight = 2;
	//	if(typeGame == FRACTION) {
	//	    gridbag.setConstraints(checkboxPanel, con);
	//	    selectionPanel.add(checkboxPanel);
	//	}
	//	else {
	//	    gridbag.setConstraints(whichnumsPanel, con);
	//	    selectionPanel.add(whichnumsPanel);
	//	}

	con.gridy=1;
	con.gridx=1;
	con.gridheight = 1;
	//	gridbag.setConstraints(checkboxPanel, con);
	gridbag.setConstraints(numCardPanel, con);
	selectionPanel.add(numCardPanel);
	System.err.println("here1");

	con.gridx=2;
	gridbag.setConstraints(maxNumPanel, con);
	selectionPanel.add(maxNumPanel);
	System.err.println("here2");
	con.anchor = con.CENTER;
	con.gridy = 3;
	con.gridwidth = GridBagConstraints.REMAINDER;
	gridbag.setConstraints(animatePanel, con);
	selectionPanel.add(animatePanel);



	pages.add(GAME, gameCanvas);
	pages.add(SETTINGS, selectionPanel);

	con.gridx = 0;
	con.gridy = 0;
	//	con.gridwidth = 3;
	con.gridheight = 1;
	con.gridwidth = GridBagConstraints.REMAINDER;
	con.weightx = 1.0;
	con.weighty = 1.0;
	gridbag.setConstraints(pages, con);
	add(pages);

	con.gridy = 1;
	con.gridwidth = 1;
	c = new Choice();
        c.addItem(GAME);
        c.addItem(SETTINGS);
	gridbag.setConstraints(c, con);
        add(c);

	con.gridx = 1;
	gridbag.setConstraints(scoreField, con);
	add(scoreField);
	
	con.gridx = 2;
	con.fill = GridBagConstraints.NONE;
	againButton = new Button("Play again!");
	gridbag.setConstraints(againButton, con);
	add(againButton);


	repaint();
	((CardLayout)pages.getLayout()).show(pages,GAME);
	Graphics gr = gameCanvas.getGraphics();
	gameCanvas.update(gr);
	
    }

    public void newDeck() {
	stack = new ACard[NUMPAIRS];
	for(int i=0;i<NUMPAIRS;i++) {
	    do{
		stack[i] = new ACard(pickaPairaCards(typeGame));
	    } while (isInStack(i-1,stack, stack[i])); 
	    //	    System.err.println(stack[i].numerator+"/"+stack[i].denominator+ "  "+stack[i].scaling+ "  "+stack[i].representation+ " " + stack[i].representation % 100+ " " +(int)Math.floor((double)(stack[i].representation) / 100));
	}

	deck = new ACard[NUMPAIRS*2];
	for(int i=0;i<NUMPAIRS;i++) {
	    deck[2*i]=new ACard(stack[i]);
	    deck[2*i].rep = TOTAL;

	    deck[2*i+1]=new ACard(stack[i]);
	    deck[2*i+1].rep = SUM;
	}
	
	shuffle(deck);
	
    }

    public void paint(Graphics g) {
	//	againButton.reshape(385, 450, 80, 40);
    }

    void shuffle(ACard deck[]) {
	int i, x, y;
	ACard tmp;

	tmp = new ACard();


	for(i=0;i<300;i++) {
	    x = generator.nextInt()%(NUMPAIRS*2);
    	    y = generator.nextInt()%(NUMPAIRS*2);
	    if(x<0){x=-x;}
	    if(y<0){y=-y;}
	    //	    System.err.println(""+x+" "+y);
	    tmp.Copy(deck[x]);
	    deck[x].Copy(deck[y]);
	    deck[y].Copy(tmp);
	}
    }
    
    boolean isInStack(int num, ACard stack[], ACard test) {

	boolean retval = false;
	for(int i=0;i<=num;i++) {
	    if(stack[i].isEqual(test)) {
		retval= true;
	    }
	}
	return retval;
    }

    public ACard pickaPairaCards(int type) {
	ACard card = new ACard(pickaPairaCardsEasy());
	
	return card;
    }


    public ACard pickaPairaCardsEasy() {
	int tot = Math.abs(generator.nextInt()%(TOPTOTAL-MINTOTAL+1)) + MINTOTAL;
	
	ACard card = new ACard();

	int factor1 = Math.abs(generator.nextInt()%(tot+1));
	card.factors[0]=factor1;
	if(tot==factor1) {
	    card.factors[1]=0;
	    card.factors[2]=-1;
	}
	else if(tot==factor1+1) {
	    card.factors[1]=1;
	    card.factors[2]=-1;
	}
	else if(factor1==0) {
	    card.factors[1]=tot;
	    card.factors[2]=-1;
	}
	// if the second number is not 0 or 1, then we are going to decide
	// whether to have a 2 or 3 number bond
	else {
	    if(Math.abs(generator.nextInt()%2) == 0) {
		card.factors[1] = tot-factor1;
		card.factors[2]=-1;
	    }
	    else {
		// want a number between 1 and tot-factor1-1
		card.factors[1] = Math.abs(generator.nextInt()%(tot-factor1-1))+1;
		card.factors[2]= tot-card.factors[1]-card.factors[0];
	    }
	}

	return card;
    }



    boolean getParams() {
	boolean changed=false;
	if(playerName.compareTo(pname.getText())!=0) {
	    changed = true;
	    playerName = pname.getText();
	    //	    System.err.println("namechanged "+playerName+" "+name.getText()+".");
	}

       Integer numCards = new Integer(16);
        try{numCards = new Integer(numCardChoice.getSelectedItem());}
        catch (Exception f) {}
  
        int x = numCards.intValue();

        if(NUMPAIRS!=x/2) {
            changed = true;
            NUMPAIRS = x/2;
            //      System.err.println("numchanged");
        }

	int newtop = maxNumChoice.getSelectedIndex()+8;
	if(newtop !=TOPTOTAL) {
		  TOPTOTAL = newtop;
		  changed = true;
		  }


	animate = animateBox.getState();

	return changed;
    }

   public boolean action(Event e, Object arg) {
        Object target = e.target;


        if ((e.target == againButton)||(e.target==c))   { 
	    //	    System.err.println("target againbutton");
	   boolean changed = getParams();
	   if(((e.target==c) && (changed == true)) || (e.target==againButton)) {
	       newDeck();
	       gameCanvas.setValues();
	       Graphics gr = gameCanvas.getGraphics();
	       gameCanvas.update(gr);
	       if(e.target == c) {
		   ((CardLayout)pages.getLayout()).show(pages,(String)arg);
	       }
	       else {
		   ((CardLayout)pages.getLayout()).show(pages,GAME);
		   c.select(GAME);
	       }
	   }
	   else {
	       ((CardLayout)pages.getLayout()).show(pages,(String)arg);
	   }
	   return true;
	}
        return false;
   }


    public class ACard {
	int factors[];
	int rep;

	boolean show=false;

	int startx=0;
	int starty=0;
	int flippin = -1;

	boolean removed = false;
	Image image=null;

	ACard() {
	    factors= new int[NUMFACTORS];
	    factors[0]=TOPTOTAL;
	    factors[1]=0;
	    for(int i =2;i<NUMFACTORS;i++) {
		factors[i]=-1;
	    }
	    rep=TOTAL;
	}

	ACard(int fac[], int re) {
	    factors= new int[NUMFACTORS];
	    for(int i =0;i<NUMFACTORS;i++) {
		factors[i]=fac[i];
	    }
	    rep=re;
	}

	ACard(ACard m) {
	    factors= new int[NUMFACTORS];
	    for(int i=0;i<NUMFACTORS;i++) {
		factors = m.factors;
	    }
	    rep=m.rep;
	}
	void Copy(ACard m) {
	    factors=new int[NUMFACTORS];
	    for(int i=0;i<NUMFACTORS;i++) {
		factors[i] = m.factors[i];
	    }
	    rep=m.rep;
	}
	boolean isEqual(ACard m) {

	    boolean retval=true;
	    for(int j=0;j<NUMFACTORS;j++) {
		boolean found = false;
		for(int i=0;i<NUMFACTORS;i++) {
		    if(factors[i] == m.factors[j]) {
			found = true;
		    }
		}
		if(!found) {
		    retval = false;
		}
	    }

	    return retval;
		
	}
    }

    public class GameCanvas extends Canvas implements MouseListener{
	int width;
	int height;
	Container mama;
	Dimension minSize;
	boolean trueSizeKnown = false;
	Graphics offGraphics;
	Graphics g;
	Image cardImage;

	int numCardsInARow;
	int numCardsInAColumn;

	int cardWidth=75;
	int cardHeight=100;
	int spacing = 20;

	int cardsTurnedOver;
	int incIn;
	int numFrames = 5;
	int downInCard;

	Dimension offDimension;

	GameCanvas(Container parent, int boardHeight, int boardWidth){  
	    width = boardWidth;
	    height = boardHeight;
	    
	    mama = parent;
	    minSize = new Dimension(width,height);
	    //	    System.err.println("width/height" + width + " " + height);
	    setSize(width, height);


	    setValues();
	    addMouseListener(this);
	    mama.validate();
	}
	
	public Dimension preferredSize() {
	    return minimumSize();
	}
	
	public synchronized Dimension minimumSize() {
	    return minSize;
	}
	
	private void setValues() {
	    // calculate how the cards are arranged
	    //	    numCardsInARow = (width-spacing)/(cardWidth+spacing);
	    //	    numCardsInAColumn= (height-spacing)/(cardHeight+spacing);
	    
	    cardsTurnedOver = 0;
	    upcards[0]=-1;
	    upcards[1]=-1;
	    downInCard = -1;
	    score = 100;
	    scoreField.setText("Current Score is "+score);

	    // Card width & spacing
	    int spacingh = (int)(height/20);
	    int spacingw = (int)(width/25);
	    if(spacingh<spacingw) {
		spacing = spacingh;
	    }
	    else {spacing = spacingw;
	    }
	    cardHeight = 4*spacing;
	    
	    // at the moment, not allowing for very narrow windows.
	    cardWidth = (int)(3*spacing);

	    incIn= cardWidth/(2*numFrames);
	    done = false;

	}

	public void paint(Graphics g) {
	    update(g);
	}

	// Can put the cards anywhere you want in this section (permanently)
	public synchronized void update(Graphics g) {
	    int swidth = width;
	    int sheight = height;
	    switch(NUMPAIRS){
	    case 6: 
	    case 8: swidth = 4*(cardWidth+spacing)+spacing;
		break;
	    case 10:swidth = 5*(cardWidth+spacing)+spacing;
		break;
	    case 12: swidth = 6*(cardWidth+spacing)+spacing;
		break;
	    }

	    if(NUMPAIRS == 6) {
		sheight = 3*(cardHeight+spacing);
	    }
	    else {
		sheight = 4*(cardHeight+spacing);
	    }
		    

	    Dimension d = getSize() ;

            if ( (offGraphics == null) ||
		 (d.width != offDimension.width)
		     || (d.height != offDimension.height) ) {
		offDimension = d;
		//		System.err.println(d.width+" and "+d.height);
		//		offImage = createImage(d.width, d.height);
		if(offImage==null){
		    //		    System.err.println("why oh why");
		}
		offGraphics = offImage.getGraphics();
	    }


	    if(!done) {
		Color newColor = new Color(226, 229, 255);
		offGraphics.setColor(newColor);
		offGraphics.fillRect(0, 0, d.width, d.height);
		offGraphics.setColor(Color.black);

		int x;
		int y;
		// want to center the deck top and bottom
		int startx = (width -swidth)/2;
		if(startx<spacing/2) {
		    startx = (int)spacing/2;
		}
		int starty =  (int)spacing/2;

		x=startx;
		y=starty;
		
		for(int i=0;i<NUMPAIRS*2;i++) {
		    deck[i].startx=x;
		    deck[i].starty=y;
		    if(deck[i].removed!=true) {
			drawOneCard(offGraphics, deck[i], x,y);
		    }
		    else if(deck[i].flippin!=-1) {
			drawFlipCard(offGraphics, deck[i]);
			
		    }

		    x+=cardWidth+spacing;
		    if((x+cardWidth)>swidth+startx) {
			x=startx;
			y=y+cardHeight+spacing;
		    }
		}

	    }
	    else {
		if(backgroundGif == null) {

		    offGraphics.setColor(Color.white);
		    offGraphics.fillRect(0, 0, d.width, d.height);
		    offGraphics.setColor(Color.black);
		}
		else {
		    offGraphics.setColor(Color.white);
		    offGraphics.fillRect(0, 0, d.width, d.height);
		    offGraphics.setColor(Color.black);
		    offGraphics.drawImage(backgroundGif, 0, 0, d.width, d.height, null);
		    offGraphics.drawImage(backgroundGif, 0, 0, d.width, d.height, null);
		}
		Font font = offGraphics.getFont();
		String fname = font.getName();
		int style = font.getStyle();
		int size = 50;		
		offGraphics.setFont(font = new Font(fname,
					  style,
					  size));

		offGraphics.drawString("Well Done,", 25, 200);
		offGraphics.drawString(pname.getText()+"!", 150,300);

	    }

	    if(g==null) {
		System.err.println("eek");
	    }
	    g.drawImage(offImage, 0, 0, null);
	}

	//DRAWING
	void drawFlipCard(Graphics g, ACard card) {
	    int i = card.flippin;
	    int x, xw;
	    if(i<numFrames) {
		x=card.startx+i*incIn;
		xw=cardWidth-2*i*incIn;
		g.drawImage(cardBack, x, card.starty, 
	    	    xw, cardHeight, null);
	    	    }
	    else {
		i=i-numFrames;
		x=card.startx+(int)(cardWidth)/2-i*incIn;
		xw=2*i*incIn;
		g.drawImage(cardImage, x, card.starty, xw,cardHeight, null);
	    }
	    g.setColor(Color.black);
	    g.drawRect(x, card.starty, xw, cardHeight-1); 
	}
	void drawOneCard(Graphics g, ACard card, int x,int y) {

	    if(card.show == false) {
		g.drawImage(cardBack, x, y, cardWidth, cardHeight, null);
		g.drawRect(x, y, cardWidth-1, cardHeight-1); 
	    }
	    if(card.image!=null) {
		g.drawImage(card.image, x,y,null);
	    }
		
	    if (card.show==true) {
		drawAddCard(g, card, x, y);
	    }

	}

	void drawAddCard(Graphics g, ACard card, int x, int y) {

	    g.setColor(cardBackground);
	    g.fillRect(x,y,cardWidth-1, cardHeight-1);
	    g.setColor(Color.black);

	    
	    Font font = g.getFont();
	    
	    int origSize = font.getSize();
	    String name = font.getName();
	    int style = font.getStyle();
	    
	    g.setFont(font = new Font(name,
				      style,
				      40));
	    int size = 40;
	    FontMetrics fontMetrics = g.getFontMetrics();
	    
	    boolean cardfits = false;

	    String teststr;
	    teststr = new String(repStr(card));

	    while(!cardfits) {
		if(fontMetrics.stringWidth(teststr) <cardWidth) {
		    cardfits=true;;
		}
		else {
		    g.setFont(font = new Font(name,
					      style,
					      --size));
		    fontMetrics = g.getFontMetrics();
		}
	    }
	    int xstart = x+(int)((cardWidth-fontMetrics.stringWidth(teststr))/2);
	    int ystart = y+fontMetrics.getAscent()+(int)((cardHeight-fontMetrics.getAscent())/2);
	    g.drawString(teststr,xstart, ystart);

	    // draw a rectangle around the card.
	    g.drawRect(x, y, cardWidth-1, cardHeight-1); 
	    g.setFont(font = new Font(name,
				      style,
				      origSize));
	    
	}

	
	String repStr(ACard card) {
	    int tot=0;
	    if (card.rep == TOTAL) {
		for(int i = 0;i<NUMFACTORS;i++) {
		    if(card.factors[i]!=-1) {
			tot+=card.factors[i];
		    }
		}
		return ""+tot;
	    }
	    else {
		String str=""+card.factors[0];
		for(int i=1;i<NUMFACTORS;i++) {
		    if(card.factors[i]!=-1) {
			str+="+"+card.factors[i];
		    }
		}
		return str;
	    }
	}


	    
	void turnOverCard(int which){
	    if((upcards[0]==-1)&&(deck[which].show==false)) {
		upcards[0]=which;
		cardsTurnedOver = 1;
		if(animate) {
		    CardTurnOverThread cardThread = new CardTurnOverThread("spin"+which,which);
		    cardThread.run();
		}
		else {
		    deck[which].show = true;
		    Graphics gr = getGraphics();
		    update(gr);
		}
	    }
	    else if((upcards[1]==-1)&&(deck[which].show==false)) {

		upcards[1]=which;
		cardsTurnedOver =2;
		if(animate) {
		    CardTurnOverThread cardThread = new CardTurnOverThread("spin"+which,which);
		    cardThread.run();
		}
		else {
		    deck[which].show = true;
		    Graphics gr = getGraphics();
		    update(gr);
		}

	    }
	}

	void turnBackCards() {
	    if((upcards[0]!=-1)&&(upcards[1]!=-1)) {
		deck[upcards[0]].show = false;
		deck[upcards[1]].show = false;
	    }
	    upcards[0]=-1;
	    upcards[1]=-1;
	    cardsTurnedOver = 0;
	}

	boolean upCardsMatch() {
	    if((upcards[0]!=-1) && (upcards[1]!=-1)) {
		if(deck[upcards[0]].rep != deck[upcards[1]].rep) {
		    int total=0;
		    for(int i =0;i<NUMFACTORS;i++) {
			if(deck[upcards[0]].factors[i] !=-1) {
			    total+=deck[upcards[0]].factors[i];
			}
		    }

		    int total2=0;
		    for(int i =0;i<NUMFACTORS;i++) {
			if(deck[upcards[1]].factors[i] !=-1) {
			    total2+=deck[upcards[1]].factors[i];
			}
		    }
		    if(total==total2) {
			return true;
		    }
		}
	    }
	    return false;
	}

	void removeCards() {
	    
	    CardRemoveThread goaway = new CardRemoveThread("removing", upcards[0], upcards[1]);
	    goaway.run();
	    deck[upcards[0]].removed = true;
	    deck[upcards[1]].removed= true;
	    Graphics g=getGraphics();
	    update(g);
	}


	int isInCard(int x, int y) {
	    int retval = -1;
	    int i=0;
	    while((i<2*NUMPAIRS)&&(retval==-1)) {
		if((x>=deck[i].startx) && (x<=(deck[i].startx+cardWidth) )
		   &&(y>=deck[i].starty)&&(y<=(deck[i].starty+cardHeight))) {
		       retval = i;
		}
		i++;
	    }
	    return retval;
	}
		   

	boolean isDone() { 
	    boolean done = true;
	    for(int i =0;i<NUMPAIRS*2;i++) {
		if(deck[i].removed==false) {
		    done = false;
		}
	    }
	    return done;
	}


	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	    downInCard= isInCard(e.getX(), e.getY());

	}

	public void mouseReleased(MouseEvent e) {

	    int whichCard = isInCard(e.getX(), e.getY());	    
	    if(cardsTurnedOver==2) {
		turnBackCards();
	    }
	    else if(downInCard==whichCard) {
		if((whichCard!=-1)&&(deck[whichCard].removed!=true)) {
		    turnOverCard(whichCard);
		    if(upCardsMatch()) {
			removeCards();
			cardsTurnedOver = 0;
			upcards[0]=-1; upcards[1]=-1;
			score +=55;
		    }
		    else {
			score-=5;
		    }
		    done = isDone();
		    
		    if(done) {
			scoreField.setText("Final Score is "+score);
		    }
		    else {
			scoreField.setText("Current Score is "+score);
		    }
		}
	    }
	    Graphics g = getGraphics();
	    update(g);
	    if(done) {
		runthis();
	    }
	}

	public void runthis() {
	    Graphics g = getGraphics();
	    update(g);
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
	}


	public class CardTurnOverThread extends Thread{
	    
	    int which;
	    String name;

	    public CardTurnOverThread(String n, int w) {
		name = n;
		which = w;
	    }
	    
	    public void run() {
		if(g == null) {
		    g=getGraphics();
		}
		int i;
                cardImage = createImage(cardWidth, cardHeight);
                Graphics cardGraphics = cardImage.getGraphics();
		deck[which].show=true;
		cardGraphics.setColor(cardBackground);
		cardGraphics.fillRect(0,0,cardWidth, cardHeight);
		cardGraphics.setColor(Color.black);
		drawOneCard(cardGraphics, deck[which], 0,0);

		deck[which].removed = true;
		for (i=0;i<2*numFrames+1;i++) {
		    deck[which].flippin = i;
		    update(g);
		}
		deck[which].flippin = -1;
		deck[which].removed = false;
		
		// this would be for automatic reflipping
		//		if((!upCardsMatch()) && (cardsTurnedOver ==2)) {
		//		    try {
		//			sleep(1000);
		//		    } catch (InterruptedException e) {}
		//		}
		    
	    }
	
	}
    
	public class CardRemoveThread extends Thread {
	    String name;
	    int w1;
	    int w2;
	    Image card1, card2;

	    public CardRemoveThread(String n, int w1, int w2) {
		name =n;
		this.w1=w1;
		this.w2=w2;
	    }

	    public void run() {
		int i;
                deck[w1].image = createImage(cardWidth, cardHeight);
                deck[w2].image = createImage(cardWidth, cardHeight);

                Graphics cardGraphics = deck[w1].image.getGraphics();
		deck[w1].show=true;
		cardBackground = Color.red;
		//		cardGraphics.fillRect(0,0,cardWidth, cardHeight);
		//		cardGraphics.setColor(Color.black);
		drawOneCard(cardGraphics, deck[w1], 0,0);

                cardGraphics = deck[w2].image.getGraphics();
		deck[w2].show=true;
		cardGraphics.setColor(Color.red);
		cardGraphics.fillRect(0,0,cardWidth, cardHeight);
		cardGraphics.setColor(Color.black);
		drawOneCard(cardGraphics, deck[w2], 0,0);
		Graphics g = getGraphics();
		update(g);
		cardBackground = Color.white;
		deck[w2].image = null;
		deck[w1].image=null;
		 try {
		     sleep(1000);
		 } catch (InterruptedException e) {}
	    }
		
	}

    }
}


