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

public class MazeApplet extends Applet 
{       
        
        
        private int m_boxSize = 5;
        private final String PARAM_boxSize = "boxSize";
        
        int starty;     
        Dimension size;
        MazeClass Maze;
        Color bxColor;
        
        player player1;
        
        boolean done; // have we finished the maze yet?
        //used for double buffering to eliminate flicker
        Dimension offDimension;
        Image offImage;
        Graphics offGraphics;
        
                
        public String getAppletInfo()
        {
                return "Name: Mazes\r\n" +
                       "Author: Patrick Muldoon\r\n"+
                             "Copyright: 1998 Doon Software\r\n";
        }
        
        public String[][] getParameterInfo()
        {
                String[][] info =
                {
                        { PARAM_boxSize, "int", "size of each box in pixels" },
                };
                return info;            
        }
  
  // for control from maze Panel
        public void NewMaze()
        {
                Maze = new MazeClass(size.height/m_boxSize, size.width/m_boxSize);
                player1.curX=1;
                player1.curY = Maze.getPlayerStartY();
                player1.numMoves =0;
                starty = player1.curY;
                done = false;
                requestFocus();
                repaint();
        }
        
        public void setDiff(int diff)
        {
                //difficulty is determined by the size of the applet and the size of the boxes
                m_boxSize = diff;
                NewMaze();
        }
        
        public void init()
        {
                String param;
                size = getSize();
                param = getParameter(PARAM_boxSize);
                if (param != null)
                        m_boxSize = Integer.parseInt(param);
                
                Maze = new MazeClass(size.height/m_boxSize, size.width/m_boxSize);
                player1 = new player();
                player1.curX = 1;
                player1.curY = Maze.getPlayerStartY();
                starty = player1.curY;
                done = false;
                bxColor = Color.blue;
                
                this.addKeyListener(new KeyAdapter(){
                        public void keyPressed(KeyEvent e)
                        {
                                int key = e.getKeyCode();
                                if(!done)
                                {       
                                        switch(key)
                                        {
                                                case KeyEvent.VK_UP: //up
                                                        if (Maze.Maze[player1.curY-1][player1.curX] ==0)
                                                        {       
                                                                player1.curY--; 
                                                                player1.numMoves++;
                                                                repaint();
                                                        }
                                                        break;
                                                case KeyEvent.VK_RIGHT: //right
                                                        if(Maze.Maze[player1.curY][player1.curX+1] ==0)
                                                        {
                                                                player1.curX++;
                                                                player1.numMoves++;
                                                                repaint();
                                                        }
                                                        break;  
                                                case KeyEvent.VK_DOWN: //down
                                                        if(Maze.Maze[player1.curY+1][player1.curX]==0)
                                                        {
                                                                player1.curY++;
                                                                player1.numMoves++;
                                                                repaint();
                                                        }
                                                        break;
                                                case KeyEvent.VK_LEFT: //left
                                                        if(Maze.Maze[player1.curY][player1.curX-1]==0)
                                                        {
                                                                player1.curX--;
                                                                player1.numMoves++;
                                                                repaint();
                                                        }
                                                        break;
                                        }//end switch
                                showStatus(player1.numMoves + " ");
                                if (player1.curX == Maze.width-1)
                                {
                                        repaint();
                                        done = true;
                                        //todo put ending code here
                                }//end if player
                        } //end !done
                }//end key pressed
                });
        }
        
        public void destroy()
        {
                // TODO: Place applet cleanup code here
        }

        public void setColor(Color NewColor)
        {
                bxColor = NewColor;
          requestFocus();
                repaint();
        }
        public void update(Graphics g)
        {
                if(!done)
                {
                        if( (offGraphics == null) || (size.width != offDimension.width) || (size.height != offDimension.height) )
                        {
                                offDimension = size;
                                offImage = createImage(size.width,size.height);
                                offGraphics = offImage.getGraphics();
                        }
                        //erase the old image
                        offGraphics.setColor(getBackground());
                        offGraphics.fillRect(0,0,size.width,size.height);
                                
                        //actually draw the maze here.  
                        //todo optimize !!!
                        int j,k;
                
                        int x=0;
                        int y=0;
                        offGraphics.setColor(bxColor);
                        for (j=0;j<Maze.height;j++)
                        {
                                for(k=0;k<Maze.width;k++)
                                {
                                        if(Maze.Maze[j][k] == 1)
                                                offGraphics.fillRect(x,y,m_boxSize,m_boxSize);
                                        x+=m_boxSize;
                                } //end for k
                                y+=m_boxSize;
                                x=0; 
                        } //end for j
                        drawPlayer(offGraphics);
                        g.drawImage(offImage,0,0,this);
                } //end if(!done)
                else //we are done
                {
                        Color old = g.getColor();
                        g.setColor(Color.gray);
                        g.fillRect(0,0,size.width,size.height);
                        g.setColor(Color.black);
                        g.drawString("Congratulations! You've Finished The Maze !!",size.width/2 - 80, size.height/2-40);
                        g.drawString("Number of Moves: " + player1.numMoves, size.width/2-80,size.height/2 -20);
                        g.drawString("Click New Maze to Try again",size.width/2-80,size.height/2 );
                        g.setColor(old);
                }               
        }
        // maze Paint Handler
        //--------------------------------------------------------------------------
        public void paint(Graphics g)
        {
                update(g);
        }       

        public void start()
        {
                requestFocus();
        }
        
        public void stop()
        {
        }

        void drawPlayer(Graphics g)
        {
                Color old = g.getColor();
                g.setColor(Color.red);
                g.fillRect(player1.curX*m_boxSize,player1.curY*m_boxSize,m_boxSize,m_boxSize);
                g.setColor(old);
        }

        public void reset()
        {
                player1.curX=1;
                player1.curY=starty;
                requestFocus();
                repaint();
        }
}

class player
{
                public player()
                {
                        curX = curY = prevY = prevX = numMoves = 0;
                }
                public int curX;
                public int curY;
                public int prevX;
                public int prevY;
                public int numMoves;
}