


class GoScore

  attr_reader :goban


  def quit
    @top.destroy
  end

  def initialize(editor)

    @editor= editor
    @dimx= editor.width
    @dimy= editor.height

    @top=GoWindow.new(self)

    @top.help_add('command','label'=>'scoring a game','command'=>proc { TkHtml.new("file://#{$current_path}/../help/editor.html#file") })

    @file_menu=Menu.new

    @file_menu.add('command', 'label' => 'Score again','command' => proc{score})
    @file_menu.add('separator')
    @file_menu.add('command', 'label' => 'Quit','command' => proc {quit})
    @top.menubar.add('cascade','menu' => @file_menu, 'label' => 'File')

    @komi= editor.get_komi
    game=editor.copy_game
    count(game)
    display_score(game)
  end

  def put_stones
    i=j=0
    for i in 0...@goban.dimx
      for j in 0...@goban.dimy
        if @game[i][j]== ?B
          @goban.set_obj(Stone,'B',i,j)
        elsif @game[i][j]== ?W
          @goban.set_obj(Stone,'W',i,j)
        end
      end
    end

  end

  def each (i,j)
    yield(i-1,j)
    yield(i+1,j)
    yield(i,j-1)
    yield(i,j+1)
  end


  def group(game,color,i,j,replace)
    game[i][j]= replace
    yield(i,j)
    each(i,j) { |x,y| group(game,color,x,y,replace) { |a,b| yield(a,b) } if  game[x][y]== color }
  end

  def score
    game= get_game
    count(game)
    display_score(game)
  end


  def get_game
    game= new_game
    i=j=0

    for i in 0...@dimx
      for j in 0...@dimy
        if @goban.board[i][j] and @goban.board[i][j].class== Stone

          if @goban.board[i][j].color == 'W'
            game[i][j]= ?W
          else
            game[i][j]= ?B
          end
        end

      end
    end

    game
  end



  def new_game
    i=j=0
    game=Array.new(@dimx+2)
    for i in -1..@dimx
      game[i]=Array.new(@dimy+2)
      for j in -1..@dimy
        if i==-1 or i==@dimx or j==-1 or j == @dimy
          game[i][j]= ?N
        else
          game[i][j]= ?E
        end
      end
    end

    game

  end

  def score_pris
    game= @editor.copy_game
    game_bis= @editor.copy_game

    count(game)

#display_score(game)


    i=j=0

    for i in 0...@dimx
      for j in 0...@dimy

        if  game[i][j]== ?B
          alive = false
          group(game,?B,i,j,?x) {|x,y| each(x,y) { |a,b| alive = true if  game[a][b]== ?b } }
          group(game,?x,i,j,?E) { |x,y| game_bis[x][y]= ?E} unless alive

        elsif game[i][j]== ?W
          alive = false
          group(game,?W,i,j,?y) {|x,y| each(x,y) { |a,b| alive = true if  game[a][b]== ?w } }
          group(game,?y,i,j,?E) { |x,y| game_bis[x][y]= ?E}  unless alive
        end
      end
    end




    count(game_bis)

    display_score(game_bis)
  end

  def count(game)

    i=j=0
    for i in 0...@dimx
      for j in 0...@dimy
        if game[i][j]== ?B
          each(i,j) { |x,y |
            if game[x][y] == ?E
              game[x][y] = ?x
            elsif  game[x][y] == ?y
              game[x][y] = ?D
            end
          }
        end
        if game[i][j]== ?W
          each(i,j) { |x,y |
            if game[x][y] == ?E
              game[x][y] = ?y
            elsif game[x][y] == ?x
              game[x][y] = ?D
            end
          }
        end
      end
    end


    begin
      finished = true
      for i in 0...@dimx
        for j in 0...@dimy
          if game[i][j]== ?x
            game[i][j]= ?b
            each(i,j) { |x,y |
              if game[x][y] == ?E
                game[x][y] = ?c
                finished= false
              elsif  game[x][y] == ?w
                game[x][y] = ?D
                finished= false
              end
            }
          elsif game[i][j]== ?y
            game[i][j]= ?w
            each(i,j) { |x,y |
              if game[x][y] == ?E
                game[x][y] = ?d
                finished= false
              elsif  game[x][y] == ?b
                game[x][y] = ?D
                finished= false
              end
            }
          end

        end
      end

      for i in 0...@dimx
        for j in 0...@dimy
          if game[i][j]== ?c
            game[i][j]= ?x
          elsif game[i][j]== ?d
            game[i][j]= ?y
          end
        end
      end

    end until finished

  end

  def score_bis
    for i in 0...goban.dimx
      for j in 0...goban.dimy
        if @game[i][j]== ?B
          @game[i-1][j] = ?b if  @game[i-1][j]== ?E
          @game[i+1][j] = ?b if  @game[i+1][j]== ?E
          @game[i][j-1] = ?b if  @game[i][j-1]== ?E
          @game[i][j+1] = ?b if  @game[i][j+1]== ?E
        end
        if @game[i][j]== ?B
          @game[i-1][j] = ?b if  @game[i-1][j]== ?E
          @game[i+1][j] = ?b if  @game[i+1][j]== ?E
          @game[i][j-1] = ?b if  @game[i][j-1]== ?E
          @game[i][j+1] = ?b if  @game[i][j+1]== ?E
        end

      end
    end
  end

  def print_score(game)
    puts
    i=j=0
    for i in 0...@dimx
      puts
      for j in 0...@dimy
        putc game[i][j]
      end
    end

  end

  def display_score(game)

    @top.cursor('watch')


    if @goban

      wpris = @goban.nb_pris_w
      bpris= @goban.nb_pris_b
      @goban.destroy
    else
      wpris= @editor.w_pris
      bpris= @editor.b_pris
    end

    wtotal=wpris
    btotal=bpris
    i=j=0

    begin
      @goban=GobanSc.new(@top,@dimx,@dimy,wpris,bpris,@komi).pack('fill'=> 'both','expand'=>'yes')
    rescue
      $stderr.puts $!
      $stderr.puts $@
    end


    for i in 0...@goban.dimx
      for j in 0...@goban.dimy
#  putc  game[i][j]
        if game[i][j]== ?w
          @goban.set_obj(Point,'W',i,j)
          wtotal += 1
        elsif game[i][j]== ?b
          @goban.set_obj(Point,'B',i,j)
          btotal +=1
  #elsif game[i][j]== ?D
      #@goban.set_mark(Dame,i,j)
        elsif game[i][j]== ?B
          @goban.set_obj(Stone,'B',i,j)
        elsif game[i][j]== ?W
          @goban.set_obj(Stone,'W',i,j)
        end


      end
    end

    wtotal += @komi

    @goban.set_score(btotal,wtotal)

    @top.cursor('')

  end
end


