
class GoBasic < TexturedPane

  attr_reader :canvas, :items, :dimx, :dimy, :marge, :step, :width, :height, :grid, :board, :markups

  def initialize(parent,dimx=19, dimy=19)
    
    @dimx=dimx
    @dimy=dimy
  #window not already opened
    @width=0
    @height=0
    @step=0


#    super(parent,TkDefaults::GUI['GoBasic.frame'])
super(parent,Defaults::DEFS['CommonBackground'],0,0,10,10)
    @h_margin= 2
    @v_margin =2

    @canvas=TkCanvas.new(self,TkDefaults::GUI['GoBasic.canvas'] ).place('x'=>0,'y'=>0)
#.pack('fill'=>'both','expand'=>'yes')

    make_wood(@canvas) if Defaults::DEFS[self.class.to_s + '.draw_woodboard']

    @items={}
    @grid=Grid.new(self)
    @board=Array.new(dimx)
    @markups=Array.new(dimx)
    0.upto(dimx-1) { |i|
      @board[i]=Array.new(dimy)
      @markups[i]=Array.new(dimy)
    }

    self.bind('Configure', proc {|e| do_resize(e) })

  end

  def destroy

    remove_all
    @items=nil
    @canvas.destroy
    super
  end

  def make_wood(canvas)
    wood= Defaults::DEFS['WoodBoard']

    w= wood.width
    h=wood.height

    for i in 0..12
      for j in 0..12

        $ip._eval("#{@canvas.path} create image #{i*w} #{j*h} -anchor nw -image #{wood.path} -tags {board}")
  #  TkcImage.new(canvas,i*s,j*s,'anchor'=>'nw', 'image'=> wood,'tags'=> ['board'])
      end
    end
  end

  def do_resize(event)


    @width = event.width
    @height = event.height

    stepx = @width.to_f/(@dimx+@h_margin)
    stepy = @height.to_f/(@dimy+@v_margin)
    step = (stepx < stepy ? stepx : stepy).round

    step -= step % 2

    if   step != @step
      @step = step
  #debug step
      @grid.coords(0,0,@step)
      resize_items
nw=@step*(@dimx+@h_margin*1)
nh=@step*(@dimy+@v_margin*1)
=begin
nx= (@width-nw)/2
ny=(@height-nh)/2
=end
@canvas.place('x'=>0, 'y'=>0, 'width'=>nw,'height'=>nh)

    end
  end

  def resize_items
    @items.each_value { |object|
      object.paint if object
    }

  end

  def raise_all
    @canvas.lower('Hidden')
    @canvas.raise('board')
    @canvas.raise('BgMark') # for Text Markups
    @canvas.raise('Select')
    @canvas.raise('Stone')
    @canvas.raise('Vars') # Viewers should take care, that the automatic variation
		  	# board markup DOESN'T overwrite any markup of other
		   	#properties.
			# ben  pourquoi ça marche pas ?
    @canvas.raise('Markup')
    @canvas.raise('Over')

  end

  def add(object,col,row,c2=nil,r2=nil)

    @items[object.caid]=object
    #debug "add #{object.class} #{col} #{row}"
    if object.class == Stone
      delete( @board[col][row])
      @board[col][row]=object
	# there is already a markup
	  if  @markups[col][row]
		@markups[col][row].reconfig(object)
	  end
    elsif object.kind_of?(Markup)  or object.kind_of?(TwoPoints)
      delete(@markups[col][row])
      @markups[col][row]=object
    else
  #debug object.class
    end
    object.reconfig(@board[col][row])
    object.set(col,row,c2,r2)
    object.paint

  end

  def delete(object)

    return if object.nil?

    if @items.key?(object.caid)
      @items.delete(object.caid)
      if  object.class == Stone
        @board[object.col][object.row]=nil
      elsif  object.kind_of?(Markup)
        @markups[object.col][object.row]=nil
      end
    end
    object.delete
  end

  def delete_id(id)
    if  object= @items[id]
      if  object.class == Stone
        @board[object.col][object.row]=nil
      elsif  object.kind_of?(Markup)
        @markups[object.col][object.row]=nil
      end
      object.delete
      @items.delete(id)
    end
  end

  def delete_mark_at(col,row)
    delete(@markups[col][row])
  end

  def delete_stone_at(col,row)
    delete(@board[col][row])
  end

  def new_board
    gm=Array.new(@dimx)
    for i in 0...@dimx
      gm[i]=Array.new(@dimy)
      for j in 0...@dimy
        if  @board[i][j].nil?
          gm[i][j]=  ?E
        else
          gm[i][j]= (@board[i][j].color== 'W' ? ?W : ?B)
        end
      end
    end
    gm
  end

  def make_group(stone)
    nb= new_board
    group= Array.new
    color=  (stone.color== 'W' ? ?W : ?B)
    col=stone.col
    row=stone.row
    add_group(nb,group,color,col,row)
    group
  end

  def add_group(nb,group,color,col,row)
    group.push(@board[col][row])
    nb[col][row] = ?E
    try(nb,group,color,col-1,row)
    try(nb,group,color,col+1,row)
    try(nb,group,color,col,row-1)
    try(nb,group,color,col,row+1)
  end

  def try(nb,group,color,col,row)
    if col >=0 and col< @dimx and row>=0 and row < @dimy
      if  nb[col][row] == color
        add_group(nb,group,color,col,row)
      end
    end
  end

  def move(object,col,row,c2=nil,r2=nil)
    if  object.kind_of?(Markup)
      @markups[object.col][object.row]=nil
      delete( @markups[col][row])
      @markups[col][row]=obj
    end

    object.reconfig(@board[col][row])
    object.set(col,row,c2,r2)
    object.paint
  end

  def move_mark(corig,rorig,col,row,c2=nil,r2=nil)
    obj=@markups[corig][rorig]
    move(obj,col,row,c2,r2)
  end

  def move_stone(corig,rorig,col,row,c2=nil,r2=nil)
    obj=@board[corig][rorig]
    move(obj,col,row,c2,r2)
  end

  def remove_all
    $ip._eval("#{@canvas.path} delete item")
    @items = {}
    @board.each { |col| 0.upto(col.length - 1) { |i| col[i] = nil } }
    @markups.each { |col| 0.upto(col.length - 1) { |i| col[i] = nil } }
  end

  def remove_tag(tag)
    l= $ip._eval("#{@canvas.path} find withtag #{tag}")
    return if l.empty?
    dlist=l.split(' ')

# dlist.each { |id| puts @items[id.to_i] }
    dlist.each { |id| delete_id(id.to_i) }
  end

  def remove_class(klass)
    list= []
    @items.each_value { |item| list.push(item) if item.class == klass }
    list.each { |item| delete(item) }
  end

  def postscript(options)
    @canvas.postscript(options)
  end

  def contains(col,row)
    col >=0 and col< @dimx and row>=0 and row < @dimy
  end

  def empty(col,row)
    @board[col].nil? or @board[col][row].nil?
  end

  def put_char(char,col,row)
    t= TextVar.new(@canvas,@grid,char.chr)
    add(t , col, row)

  end

  def cursor(motif)
    @canvas.configure('cursor',motif)
    Tk.update
  end

  def show_libs(col,row,stop=false)
  return unless col and row
    nb_libs=0
    begin
      group=make_group(@board[col][row])
      group.each { |stone|
        x=stone.col
        y=stone.row
        nb_libs += put_lib(stone.color,x-1,y)
        nb_libs += put_lib(stone.color,x+1,y)
        nb_libs += put_lib(stone.color,x,y-1)
        nb_libs += put_lib(stone.color,x,y+1)

      }

      if nb_libs <= 1
        group.each { |stone|
          stone.alarm("red")
        }

        tksleep(500)
        $ip._eval("#{@canvas.path} itemconfigure alarm -outline yellow")
        tksleep(500)
        $ip._eval("#{@canvas.path} itemconfigure alarm -outline red")
        tksleep(500)
        $ip._eval("#{@canvas.path} itemconfigure alarm -outline yellow")
        tksleep(500)
        $ip._eval("#{@canvas.path} itemconfigure alarm -outline red")
        tksleep(500)
      elsif nb_libs == 2
        group.each { |stone|
          stone.alarm("yellow")
        }
        tksleep(1000)
      else
        group.each { |stone|
          stone.alarm("white")
        }
        tksleep(1000)

      end

      remove_tag("Markup")
      $ip._eval("#{@canvas.path} delete alarm")
      Tk.update


      show_adv_libs(col,row) unless stop

    rescue
      puts $!
      puts $@
    end
  end

  def tksleep(n)
    $ip._eval("
      after #{n} set tksleep 1
      tkwait variable tksleep")
  end

  def put_lib(color,col,row)

    if col >=0 and col< @dimx and row>=0 and row < @dimy
      if @board[col][row].nil?
        add(Point.new(@canvas,@grid,color),col,row)
        return 1
      end
    end
    return 0
  end

  def show_adv_libs(col,row)
    color=@board[col][row].color
    put_adv_libs(col-1,row,color)
    put_adv_libs(col+1,row,color)
    put_adv_libs(col,row-1,color)
    put_adv_libs(col,row+1,color)
  end

  def  put_adv_libs(col,row,color)

    if col >=0 and col< @dimx and row>=0 and row < @dimy
      if st=@board[col][row] and st.color != color
        show_libs(col,row,true)
      end
    end

  end

end

