//
// 迷路
//
import java.awt.* ;
import java.awt.event.* ;
import java.applet.* ;

public class meiro extends Applet implements Runnable, ActionListener {

  int x = 0, y = 1 ; // スタート位置
  int muki = 1 ;     // 最初の向き
  int[][] Map = {
    {9,9,9,9,9,9,9,9,9,9},
    {1,0,0,0,9,0,0,0,9,9},
    {9,9,9,0,9,0,9,0,0,9},
    {9,0,9,0,0,0,9,0,9,9},
    {9,0,0,0,9,9,9,0,9,9},
    {9,9,9,0,0,9,9,9,9,9},
    {9,0,0,0,9,0,9,9,9,9},
    {9,0,9,9,0,0,0,9,0,9},
    {9,0,0,0,0,9,0,0,0,2},
    {9,9,9,9,9,9,9,9,9,9}
  } ;
  Image imgStart, imgGoal, imgBlock, imgTsuuro ;
  Image[] imgMuki = new Image[4];
  Image    backImg = null ;
  Graphics backG ;
  Button   btnReset     = new Button("Reset") ;
  Button   btnStep      = new Button("Step") ;
  Button   btnStartStop = new Button("Start") ;
  Thread   th = null ;
  boolean  showFlag = true ;
  boolean  isRunning = false ;

  private void drawMeiro() {
    int i, j ;
    for( i=0 ; i<10 ; i++ ) {
      for( j=0 ; j<10 ; j++ ) {
        switch( Map[j][i] ) {
        case 0: backG.drawImage(imgTsuuro,i*20,j*20,this) ; break ;
        case 1: backG.drawImage(imgStart, i*20,j*20,this) ; break ;
        case 2: backG.drawImage(imgGoal,  i*20,j*20,this) ; break ;
        default:backG.drawImage(imgBlock, i*20,j*20,this) ; break ;
        }
      }
    }
  }

  private void showMe() {
    backG.drawImage(imgMuki[muki],x*20,y*20,this) ;
    showFlag = true ;
  }
  private void hideMe() {
    switch( Map[y][x] ) {
    case 0: backG.drawImage(imgTsuuro,x*20,y*20,this) ; break ;
    case 1: backG.drawImage(imgStart, x*20,y*20,this) ; break ;
    case 2: backG.drawImage(imgGoal,  x*20,y*20,this) ; break ;
    default:backG.drawImage(imgBlock, x*20,y*20,this) ; break ;
    }
    showFlag = false ;
  }
  
  public void init() {
    MediaTracker mt = new MediaTracker(this) ;
    int m ;
    imgStart  = getImage(getDocumentBase(), "meiro_s.gif") ;
    imgGoal   = getImage(getDocumentBase(), "meiro_g.gif") ;
    imgTsuuro = getImage(getDocumentBase(), "meiro_f.gif") ;
    imgBlock  = getImage(getDocumentBase(), "meiro_b.gif") ;
    for( m=0 ; m<4 ; m=m+1 )
      imgMuki[m] = getImage(getDocumentBase(), "meiro_"+m+".gif") ;
    mt.addImage(imgStart,0) ;
    mt.addImage(imgGoal,1) ;
    mt.addImage(imgTsuuro,2) ;
    mt.addImage(imgBlock,3) ;
    for( m=0 ; m<4 ; m=m+1 )
      mt.addImage(imgMuki[m],4+m) ;
    try {
      mt.waitForAll() ; // 画像ファイルが完全に読み込まれるまで待機
    }
    catch(InterruptedException e) {
      System.err.println(e.toString()) ; // エラーの内容を表示
    }

    add(btnReset) ; add(btnStep) ; add(btnStartStop) ;
    btnReset.addActionListener(this) ;
    btnStep.addActionListener(this) ;
    btnStartStop.addActionListener(this) ;
  }

  private void doStep() {
    int tugi_muki, tugi_x, tugi_y ;
    if( Map[y][x] == 2 ) {  // Goal地点ならStartへ戻す
      x = 0 ; y = 1 ; muki = 1 ;
    }
    else {
      // 問題文に対応
      tugi_muki = muki + 3 ;       // 【ス】
      do {
        if( tugi_muki >= 4 ) {     // 【セ】
          tugi_muki = tugi_muki - 4 ;
        }
        tugi_x = x ; tugi_y = y ;
        switch( tugi_muki ) {
        case 0: tugi_y = tugi_y-1 ; break ; // 【ソ】
        case 1: tugi_x = tugi_x+1 ; break ; // 【タ】
        case 2: tugi_y = tugi_y+1 ; break ; // 【チ】
        case 3: tugi_x = tugi_x-1 ; break ; // 【ツ】
        }
        tugi_muki = tugi_muki+1 ;
      } while( ! (Map[tugi_y][tugi_x] != 9) ) ; // 【テ】 xとyは逆
      // 本来なら while( Map[tugi_y][tugi_x] == 9 )
      muki = tugi_muki - 1 ;
      x = tugi_x ; y = tugi_y ;
    }
  }
  
  public void actionPerformed(ActionEvent ev) {
    if( ev.getSource() == btnReset ) {
      if( isRunning ) {
	isRunning = false ;
        btnStartStop.setLabel("Start") ;
	btnStartStop.repaint() ;
      }
      if( showFlag ) hideMe() ;
      x = 0 ; y = 1 ; muki = 1 ;
      showMe() ;
      repaint() ;
    }
    else if( ev.getSource() == btnStartStop ) {
      isRunning = !isRunning ;
      if( isRunning ) {
        btnStartStop.setLabel("Stop") ;
      }
      else {
        btnStartStop.setLabel("Start") ;
      }
      btnStartStop.repaint() ;
    }
    else if( ev.getSource() == btnStep ) {
      if( showFlag ) hideMe() ;
      doStep() ;
      showMe() ;
      repaint() ;
    }
  }

  public void start() {
    backImg = createImage(200,200) ;
    backG = backImg.getGraphics() ;
    drawMeiro() ;
    showMe() ;
    th = new Thread(this) ;
    th.start() ;
  }

  public void run() {
    int b, blinkMax, blinkInt ;
    while( th != null ) {
      if( isRunning ) { blinkMax = 3 ; blinkInt =  80 ; }
      else            { blinkMax = 1 ; blinkInt = 250 ; }
      for( b=0 ; b<blinkMax ; b++ ) {
        showMe() ;
        repaint() ;
        try {
	  th.sleep(blinkInt) ;
	}
        catch(InterruptedException e) {
        }
        hideMe() ;
        repaint() ;
        try {
          th.sleep(blinkInt) ;
        }
        catch(InterruptedException e) {
        }
      }
      if( isRunning ) {
        doStep() ;
      }
    }
  }

  public void update(Graphics g) {
    paint(g) ;
  }
  public void paint(Graphics g) {
    if( backImg != null ) {
      g.drawImage(backImg,0,50,this) ;
    }
  }

}