import java.util.*;
import java.net.*;
import java.awt.*;

public class floodFill extends Panel implements Runnable,tool{
asciiJam aj;
Stack st = new Stack();
boolean letterMatch = true;
boolean colorMatch = true;
char oldChar;
char oldColor;
Thread t;
int offX;
int offY;
boolean defCurs = false;
charChooser chCh = null;

  public void identify(int x, int y, int zoom, asciiJam aj){}
  public void setchar(int c,int pos, int zoom, asciiJam aj){}
  public boolean mouseDrag(int x, int y){ return true;}
  public boolean mouseUp(int x, int y){ return true;}

  public floodFill(asciiJam aj){
        this.aj = aj;
        this.resize(123,275);
        this.setLayout(null);
        this.setBackground(Color.black);
        Panel prefs = new Panel();
        prefs.setLayout(new GridLayout(4,1,0,1));
        prefs.setBackground(Color.lightGray);
        prefs.add(new Label(" Fill Prefs"));
	    prefs.add(new Checkbox("char. match",true));
	    prefs.add(new Checkbox("color match",true));
        prefs.add(new Label(" Fill letter:"));
        chCh = new charChooser(aj);
        chCh.reshape(0,0,123,170);
		chCh.show();
        Panel inner = new Panel();
        inner.resize(size().width-2,size().height-2);
        inner.move(1,1);
        inner.setLayout(new BorderLayout());
        inner.add(chCh,BorderLayout.CENTER);
        inner.add(prefs,BorderLayout.NORTH);
        add(inner);
  }
  public void show(){
        setFont(env.dialogFont);
        super.show();
  }
  public void setLetterMatch(boolean b){
        letterMatch = b;
  }
  public void setColorMatch(boolean b){
        colorMatch = b;
  }

  public boolean mouseDown(int x, int y, int zoom, asciiJam aj){
    offX = aj.mapF.getX();
    offY = aj.mapF.getY();
    int z3 = zoom<<3;
    int z4 = zoom<<4;
    //int i = (x)/z3+(((y)/z4)<<7);
	int xindex = (x>>3)/aj.ta.zoom;
	int yindex = (y>>4)/aj.ta.zoom;
    oldChar  = (char)aj.ta.text[ (xindex)+(yindex<<7) ];
    oldColor = (char)aj.ta.text[ (xindex)+(yindex<<7)+ env.colorOffset ];
    //oldChar  = (char)aj.ta.text[ i ];
    //oldColor = (char)aj.ta.text[ i+ env.colorOffset ];
	//System.out.println("oldChar = "+oldChar);
    st.push(new Point(xindex,yindex));
	start();
	return true;
  }

  public void stop(){
   	   if(t!=null) t.stop();
   	   t = null;
  }
  public void start(){
       t = new Thread(this);
   	   t.start();	
  }
  public void run(){
	Point pt=null;
	boolean _letterMatch = letterMatch;
	boolean _colorMatch  = colorMatch;
	System.out.println(letterMatch+" "+colorMatch);
    if(oldChar == aj.fillChar){
		_letterMatch=false;
	}
    if(oldColor == aj.curColorIndex){
	    _colorMatch = false;
	}
	System.out.println(_letterMatch+" "+_colorMatch);
	if(!_colorMatch&&!_letterMatch) return;
	env.setCursor(env.WAIT_CURSOR,aj);
	Graphics g = aj.img.getGraphics();
	if(g!=null){
	g.setFont(env.font[aj.ta.zoom]);
	//g.translate(-aj.mapF.getX(),-aj.mapF.getY());
	int grid[][] = new int[64][128];
	for(int row=0;row<64;row++){
	  for(int col=0;col<128;col++){
			grid[row][col] = -1;
	  }
	}
    int maxwid = (env.width>>3)-1;
    int maxht = (env.height>>4)-1;
	while(!st.empty()){
         pt  = (Point)(st.pop());
		 if(grid[pt.y][pt.x]!=(int)aj.fillChar)
		 aj.ta.setchar(aj.fillChar,(pt.x<<3)*aj.ta.zoom-offX,(pt.y<<4)*aj.ta.zoom-offY,aj.curColorIndex,aj.curCol,g,false);
		 grid[pt.y][pt.x] = (int)aj.fillChar;
		 if(pt.x>0){
               int pty = pt.y<<7;
                if((_letterMatch && aj.ta.text[(pt.x-1)+(pty)]==oldChar)||
                   (_colorMatch && aj.ta.text[(pt.x-1)+(pty)+env.colorOffset]==oldColor))
                    st.push(new Point(pt.x-1,pt.y));
                    //System.out.println("a "+pt.x+" "+(int)oldColor+" "+oldChar);
         }
         if(pt.x<maxwid){
               int pty = pt.y<<7;
                if((_letterMatch && aj.ta.text[(pt.x+1)+(pty)]==oldChar)||
                   (_colorMatch && aj.ta.text[(pt.x+1)+(pty)+env.colorOffset]==oldColor))
                    st.push(new Point(pt.x+1,pt.y));
                    //System.out.println("b "+pt.x+" "+(int)oldColor+" "+oldChar);
         }
         if(pt.y>0){
                int pty = ((pt.y-1)<<7);
                if((_letterMatch && aj.ta.text[pt.x+pty]==oldChar)||
                   (_colorMatch && aj.ta.text[pt.x+pty+env.colorOffset]==oldColor))
                    st.push(new Point(pt.x,pt.y-1));
                    //System.out.println("c "+pt.x+" "+(int)oldColor+" "+oldChar);
         }
         if(pt.y<maxht){
               int pty = (pt.y+1)<<7;
                    if((_letterMatch && aj.ta.text[pt.x+pty]==oldChar)||
                       (_colorMatch && aj.ta.text[pt.x+pty+env.colorOffset]==oldColor ))
                       //st.push(new Point(pt.x,pt.y+1));
					{	
					   pt.y = pt.y+1;
                       st.push(pt); // avoid constructor, reuse
					}
         }
         //aj.ta.text[pt.x +(pt.y<<7)] = fillChar;
         //aj.ta.text[pt.x +(pt.y<<7) + env.colorOffset] = (char)aj.curColorIndex;
		 //System.out.println((int)aj.curColorIndex+" "+(char)aj.curColorIndex);
	}
	g.dispose();
	}
	//aj.ta.fillGrid();
    aj.ta.repaint();
    env.setCursor(aj.tool,aj);
  }

  public boolean handleEvent(Event e){
	 if(e.target instanceof Button){
	 	if(e.id==1001) 
			try{
			aj.getAppletContext().showDocument(new URL(env.helpFillURL),"_blank");
			}catch(Exception ex){}
	 }else if(e.target instanceof Choice){
	 		aj.fillChar = ((Choice)e.target).getSelectedItem().charAt(0);
			return false;
	 }else if(e.target instanceof TextField){
		if(e.id==402){
			//((TextField)e.target).setText((new Character((char)e.key)).toString());
			String s = ((TextField)e.target).getText();
			if(s!=null&&s.length()>0){
				aj.fillChar = s.charAt(0);
				((TextField)e.target).setText(s.substring(0,1));
			}
		}
		else if(e.id==401){
			((TextField)e.target).setText("");
		}
		return false;
	 }
     else if(e.target instanceof Checkbox){
	 	if(e.id==1001){
			if( ((Checkbox)e.target).getLabel().equals("char. match") ){
					setLetterMatch(((Checkbox)e.target).getState());
					System.out.println(e.id+"setting letter match"+((Checkbox)e.target).getState());
			}else{
					setColorMatch(((Checkbox)e.target).getState());
					System.out.println(e.id+"setting color match"+((Checkbox)e.target).getState());
			}
		}
	 }
     else if(e.id==Event.MOUSE_ENTER){
           env.setCursor(env.DEFAULT_CURSOR,aj);
     }
     else if(e.id==Event.MOUSE_MOVE){
          if(!defCurs){
              env.setCursor(env.DEFAULT_CURSOR,aj);
              defCurs = true;
          }
     }
     else if(e.id==Event.MOUSE_EXIT){
         if(e.target instanceof oval){
           env.setCursor(aj.tool,aj);
           defCurs = false;
         }
         else{
           env.setCursor(env.DEFAULT_CURSOR,aj);
           defCurs = true;
         }
     }

     
	 return true;
  }
}
