# tags : 'Graphics' are deleted at each node
# BgMark below Markup
#        'Markup' are over 'Stone' in stack order
#	'Markup' are over 'Vars'
#        'board' are not removable
#        'item' are removable and movable




class CaItem

  attr_reader :caid, :row, :col, :c2, :r2,  :x, :y

  def initialize(canvas,grid,opts,*args)
    @canvas=canvas
    @c = canvas.path
    @grid= grid
    @args=args

    @caid= $ip._eval("#@c create  #{opts}").to_i
  end

  def duplicate
    self.class.new(@canvas,@grid,*@args)
  end

  def bind(event,cb)
    TkCb.tk_register_cb(cb)
    $ip._eval("#@c bind #@caid <#{event}> { ruby {tk_callback( '#{cb.id}',%x,%y)}}")
  end

  def delete

    $ip._eval("#@c delete #@caid")
  end

  def configure(args = '')
    $ip._eval("#@c itemconfigure #@caid #{args}")
  end

  def cget (opt)
    $ip._eval("#@c itemcget #@caid #{opt}")
  end

  def dtag(tag)
    $ip._eval("#@c dtag #@caid #{tag}")
  end

  def addtag(tag)
    $ip._eval("#@c addtag #{tag} withtag #@caid")
  end

  def bbox
    s=  $ip._eval("#@c bbox #@caid")
    if s.empty?
      return [0,0,0,0]
    else
      return   s.split(' ').collect {|x| x.to_i}
    end

  end

  def set(col,row,c2=nil,r2=nil)

    @col=col
    @row=row
    @c2=c2
    @r2=r2
    do_place
  end

  def do_place
  end

  def paint

    @x,@y= @grid.grid_put(@col,@row)
    do_redraw(@x,@y,@grid.step)

  end

# def do_motion(x,y)
#   do_redraw(x,y,@grid.step)
# end

  def coords(*args)
    $ip._eval("#@c coords #@caid #{args.join(' ')}")
  end

  def get_coords
    s=  $ip._eval("#@c coords #@caid")
    s.split(' ').collect {|x| x.to_i}
  end

  def reconfig(stone)
    if stone.nil?
      outl= Defaults::DEFS['marks_outline']
      ins= Defaults::DEFS['marks_fill']
    else
      if stone.color == 'W'
        outl='black'
        ins='white'
      else
        outl='white'
        ins='black'
      end
    end
    do_colors(outl,ins)
  end

  def do_colors(outl,ins)
    self.configure("-outline #{outl}")
  end

  def raise
    $ip._eval("#@c raise #@caid")
  end

  def lower
    $ip._eval("#@c lower #@caid")
  end

  def cursor(motif,item=self)
    old_cursor= $ip._eval("#@c cget -cursor")
    $ip._eval("#@c bind #@caid <Enter> { #@c configure -cursor #{motif}}")
    $ip._eval("#@c bind #@caid <Leave> {#@c configure -cursor {#{old_cursor}}}")
  end


  def movable
    cursor('hand2')

  end

end

class Hoshi < CaItem

  def initialize(canvas,grid,col,row)

    super(canvas,grid,"oval 0 0 0 0 -fill black -tags {Hoshi board}")
    set(col,row)
  end

  def do_redraw(x,y,step)
    r=(step/10).round
    self.coords((x-r),(y-r),(x+r),(y+r))
  end

end

class Stone < CaItem

  attr_reader :color, :nb
  attr_accessor :move_nb

  def initialize(canvas,grid,color,nb=nil)
    @color= color
    @color = 'W' if @color == ?W
    @color = 'B' if @color == ?B
    @fill = 'white' if @color == 'W'
    @fill = 'black' if @color == 'B'
    @nb=nb
    @step=0

  # super(canvas,grid, "oval  0 0 0 0 -fill #{fill} -tags {item Stone}",color,nb )
    super(canvas,grid, "image  0 0  -anchor c -tags {item Stone}",@color,@nb )

  end

  def do_redraw(x,y,step)
    @x=x
    @y=y
    if step != @step
      @step=step
      if Defaults::WStones[@step]
        if @fill == 'white'
          img= Defaults::WStones[@step].path
        else
          img= Defaults::BStones[@step].path
        end
        configure("-image #{img}")
      else
        $stderr.puts "warning: stone image not found"
      end
    end
    self.coords(x,y)
  end

  def reconfig(*args)
  end

  def highlight(color= "yellow")
    r= @step/2
    @hlight= $ip._eval("#@c create oval #{@x-r} #{@y-r} #{@x+r} #{@y+r} -outline #{color} -tags {movable highlight}")
    $ip._eval("#@c itemconfigure #@caid -tags {item Stone movable}")

  end

  def normal
    $ip._eval("#@c delete  #@hlight")
    $ip._eval("#@c itemconfigure #@caid -tags {item Stone}")
  end

  def alarm(color)
    r= @step/2
    $ip._eval( "
#@c create oval #{@x-r} #{@y-r} #{@x+r} #{@y+r} -outline #{color} -tags alarm
              ")
  end
end

class Dame < CaItem

  def initialize(canvas,grid)
    super(canvas,grid,"oval 0 0 0 0 -outline black -tags {item Graphics Markup}" )
  end

  def do_redraw(x,y,step)
    r=(step/5).round
    self.coords((x-r).round,(y-r).round,(x+r).round,(y+r).round)
  end

end

class Point < CaItem


  attr_reader :color
  def initialize(canvas,grid,color)
    @color = color
    fill = 'white' if color == 'W'
    fill = 'black' if color == 'B'

    super(canvas,grid, "oval  0 0 0 0 -fill #{fill} -tags {item Graphics Markup}",color )
  end

  def do_redraw(x,y,step)
    r=(step/5).round
    self.coords(x-r,y-r,x+r,y+r)
  end

  def do_colors(outl,ins)
  end

end

class Markup < CaItem
end

class Rectangle < Markup

  def initialize(canvas,grid)

    super(canvas,grid, "polygon 0 0 0 0 0 0 -fill {} -outline black -width #{Defaults::DEFS['marks_width']}\ -tags {item Graphics Markup}")
  end


  def do_redraw(x,y,step)
    r=(step/4.5).round
    self.coords(x-r,y-r,x+r,y-r,x+r,y+r,x-r,y+r,x-r,y-r)
  end
end

class Triangle < Markup
  def initialize(canvas,grid)

    super(canvas,grid, "polygon 0 0 0 0 0 0 -fill {} -outline black -width #{Defaults::DEFS['marks_width']} -tags {item Graphics Markup}")
  end


  def do_redraw(x,y,step)
    r=(step/4).round
    self.coords(x,y-r-1,x+r,y+r-1,x-r,y+r-1,x,y-r-1)
  end
end

class Bar < Markup

  def initialize(canvas,grid)

    super(canvas,grid, "line 0 0 0 0  -fill black  -width #{Defaults::DEFS['marks_width']} -tags {item Graphics Markup}")
  end

end

class Cross < Markup
  attr_reader :tags, :line1, :line2, :caid
  def initialize(canvas,grid)

    @canvas=canvas
    @grid= grid
    @args=[]

    @line1 = Bar.new(canvas,grid)
    @line2 = Bar.new(canvas,grid)
    @caid= @line1.caid
  end


  def do_redraw(x,y,step)
    r=(step/3).round
    @line1.coords(x-r,y-r,x+r,y+r)
    @line2.coords(x-r,y+r,x+r,y-r)
  end

  def do_colors(outl,ins)
    @line1.configure("-fill #{outl}")
    @line2.configure("-fill #{outl}")
  end

  def delete
    @line1.delete
    @line2.delete
  end

  def bind (event,action)
    @line1.bind(event,action)
    @line2.bind(event,action)
  end

  def raise
    @line1.raise
    @line2.raise
  end
  def lower
    @line1.lower
    @line2.lower
  end

  def movable
    @line1.cursor('hand2')
    @line2.cursor('hand2')
    @line1.bind('B1-Motion',proc  { |x,y| do_redraw(x,y,@grid.step)})
    @line2.bind('B1-Motion',proc  { |x,y| do_redraw(x,y,@grid.step)})
  end


  def coords(*args)

  end
  def bbox
    @line1.bbox
  end

  def do_colors(outl,ins)
    @line1.configure("-fill #{outl}")
    @line2.configure("-fill #{outl}")

  end



end

class Circle < Markup

  def initialize(canvas,grid)
    super(canvas,grid, "oval 0 0 0 0 -fill {} -outline black -width #{Defaults::DEFS['marks_width']}\ -tags {item Graphics Markup}")
  end

  def do_redraw(x,y,step)
    r=(step/4.5).round
    self.coords(x-r,y-r,x+r,y+r)
  end

end

class Sqr < CaItem
  def initialize(canvas,grid,x1,y1,x2,y2)

    super(canvas,grid, "polygon 0 0 -fill {} -outline black  -tags {item Over}")
    coords(x1,y1,x2,y2)
  end

  def coords(x1,y1,x2,y2)
    super(x1,y1,x2,y1,x2,y2,x1,y2)
  end


end

module TwoPoints
  attr_reader :c2, :r2

  def set(col,row,c2=nil,r2=nil)

    if c2.nil?
     #debug "#{col},#{row}+#{c2},#{r2}"
      x1,y1,x2,y2= get_coords
      gs=@grid.step/2
      @col,@row= @grid.grid_round(x1,y1)
      @col=0 unless @col
      @row=0 unless @row
      @c2,@r2= @grid.grid_round(x2,y2)
      @c2= @grid.dimx - 1 unless @c2
      @r2= @grid.dimy - 1 unless @r2

   #
   #  debug "#{@col},#{@row}+#{@c2},#{@r2}"
    else
      @col=col
      @row=row
      @c2=c2
      @r2=r2
    end
    do_place
  end

  def set_sq
    #  debug "#{@col},#{@row}"
    x,y= @grid.grid_put(@col, @row)
   # debug "#{x},#{y}"
    if  @sq1.nil?
      @sq1= Sqr.new(@canvas,@grid,x-3,y-3,x+3,y+3)
      @sq1.bind('B1-Motion',proc  { |x,y|
                @sq1.coords(x-3,y-3,x+3,y+3)
                redraw(x,y,@x2,@y2)
      })
      @sq1.bind('ButtonRelease-1', proc { |x,y|
                $ip._eval("#@c dtag movable movable")
                c,r= @grid.grid_round(x, y)
                unless c.nil? or r.nil?
                  @col,@row= c,r
                  paint
                  x,y= @grid.grid_put(@col, @row)
                  @sq1.coords(x-3,y-3,x+3,y+3)

                end
      })
      @sq1.cursor('top_left_corner')
    else
      @sq1.coords(x-3,y-3,x+3,y+3)
    end
    @sq1.raise

    x,y= @grid.grid_put(@c2, @r2)
   # debug "#{x},#{y}"
    if  @sq2.nil?
      @sq2= Sqr.new(@canvas,@grid,x-3,y-3,x+3,y+3)
      @sq2.bind('B1-Motion',proc  { |x,y|
                @sq2.coords(x-3,y-3,x+3,y+3)
                redraw(@x1,@y1,x,y)
      })
      @sq2.bind('ButtonRelease-1', proc { |x,y|
                $ip._eval("#@c dtag movable movable")
    c,r= @grid.grid_round(x,y)
    unless c.nil? or r.nil?
      @c2,@r2= c,r
      paint
      x,y= @grid.grid_put(@c2, @r2)
      @sq2.coords(x-3,y-3,x+3,y+3)

    end
    })
    @sq2.cursor('bottom_right_corner')
    else
      @sq2.coords(x-3,y-3,x+3,y+3)
    end
    @sq2.raise

  end


  def paint
# debug "#{@col} #{@row}" if self.kind_of? Dim
    @x1,@y1= @grid.grid_put(@col,@row)
    @x2,@y2= @grid.grid_put(@c2,@r2)

    do_redraw(@x1,@y1,@grid.step,@x2,@y2)
  end



  def do_redraw (x1,y1,step,x2=nil, y2=nil)

    if x2.nil? # toolbox et paint ?
      @x1= x1.round
      @y1= y1.round
      @x2= x1.round
      @y2= y1.round

    else # paint
      @x1= x1
      @y1= y1
      @x2= x2
      @y2= y2

    end
    redraw(@x1,@y1,@x2,@y2)
  end
end

class Line < CaItem
  include TwoPoints
  def initialize(canvas,grid)

    super(canvas,grid, "line 0 0 0 0  -fill #{Defaults::DEFS['marks_outline']}  -tags {item Graphics Over} -arrow none -width #{Defaults::DEFS['marks_width']}")

  end

  def redraw(x1,y1,x2,y2)
    if x2== x1 and y1 == y2
      step = @grid.step
      x1= (x1-step/2).round
      y1= (y1-step/2).round
      x2= (x2+step/2).round
      y2= (y2+step/2).round
    end

    self.coords(x1,y1,x2,y2)
  end

  def reconfig(object)
  end

end

class Arrow < Line
  def initialize(canvas,grid)
    super(canvas,grid)
    self.configure('-arrow last')
  end
end

class Dim < CaItem

  include TwoPoints

  def initialize(canvas,grid)

    super(canvas,grid, "rectangle 0 0 0 0  -fill #{Defaults::DEFS['stipple-color']} -outline {} -tags {item Inherit Dimmed Over} -stipple #{Defaults::DEFS['stipple']}")

  end

  def redraw(x1,y1,x2,y2)

    r= (@grid.step/2).round
    self.coords(x1-r,y1-r,x2+r,y2+r)
  end

  def reconfig(object)
  end

end

class Select < CaItem

  include TwoPoints
  def initialize(canvas,grid)


    super(canvas,grid, "rectangle 0 0 0 0  -fill white -outline {} -stipple gray50 -tags {item Select Graphics}")
  end

  def redraw(x1,y1,x2,y2)
    r= (@grid.step/2).round
    self.coords(x1-r,y1-r,x2+r,y2+r)
  end

  def reconfig(object)
  end

end

class View < CaItem

  include TwoPoints
  attr_reader :a1, :b1, :a2, :b2

  def initialize(canvas,grid)

 #     super(canvas,0,0,0,0,'outline'=>'red','fill'=>'',
  #            'tags'=> ['View','Inherit','Over'])
    super(canvas,grid, "rectangle 0 0 0 0  -fill {} -outline red -tags {item View Inherit Over}")
  end

  def redraw(x1,y1,x2,y2)
    r= (@grid.step/2).round
    self.coords(x1-r,y1-r,x2+r,y2+r)
    @a1= x1-r
    @b1= y1-r
    @a2= x2+r
    @b2= y2+r
  end

  def reconfig(object)
  end

end

class Text < Markup

  attr_reader :text_value
  def initialize(canvas,grid,text= nil,opts=nil)
    if text
      @text_set=true
      @text_value=text
    else
      text='A'
      @text_set=false
    end

  if opts
    super(canvas,grid,opts)
  else
    super(canvas,grid,"text 0 0 -text {#{text}} -tags {item Text Graphics Markup}")
  end

#debug $ip._eval("#@c gettags #@caid")
  end

  def do_redraw(x,y,step)
    self.coords(x,y)
  end

    def do_colors(outl,ins)
      self.configure("-fill #{outl}")
    end


  def do_place
    return if @text_set
    Misc.get_text('Enter text:') { |str| set_textvar(str)}
  end

  def set_textvar (t)

    t = 'A' if t.empty?
    self.configure("-text {#{t}}")
    @text_set=true
    @text_value= t
    @args=[t]
  end
end

class TextBoard < Text


#BG='#e2aa6c'
  BG='#daa65c'
  def do_redraw(x,y,step)

    super(x,y,step)
    if @cr1
      r=(step/3).round
#debug " #{x} #{y} #{r}"
      $ip._eval("#@c coords #@cr1 #{x-r} #{y} #{x+r} #{y}")
      $ip._eval("#@c coords #@cr2 #{x} #{y-r} #{x} #{y+r}")
    end
  end

  def reconfig(stone)
    if stone.nil?
      outl= 'black'
      opts= "line  0 0 0 0 -fill #{BG}  -tags {item Text Graphics BgMark}"
     #opts= "oval  0 0 0 0 -fill #{BG} -outline {} "
      @cr1= $ip._eval("#@c create  #{opts}").to_i
      @cr2= $ip._eval("#@c create  #{opts}").to_i
      self.raise
    else
      if stone.color == 'W'
        outl='black'
      else
        outl='white'
      end
      @cr1=@cr2= nil
    end
    self.configure("-fill #{outl}")
  end

  def delete
    super()
    $ip._eval("#@c delete #@cr1 #@cr2") if @cr1
  end


end



class TextVar < TextBoard # for variations

  def initialize(canvas,grid,text= nil)
    super(canvas,grid,text,"text 0 0 -text {#{text}} -tags {item Text Graphics Vars}")
    #dtag('Markup')
    #addtag('Vars')
#debug $ip._eval("#@c gettags #@caid")

  end

  def reconfig(stone)
    super(stone)
    self.configure("-fill #{Defaults::DEFS['vars_color']}")
  end

end

class TextMove < Text # move numbers
  attr_reader :nb
  def initialize(canvas,grid,text)
    super(canvas,grid,text)
    @nb=text
    self.configure("-tags {Text Moves Markup}")
  end
end

cl = case Defaults::DEFS['last_move_mark']
when 'Dame'
  Dame
when 'Circle'
  Circle
when 'Rectangle'
  Rectangle
when 'Triangle'
  Triangle
end


class LastMove < cl
  def initialize(canvas,grid)
    super(canvas,grid)
    self.configure("-tags {LastMove Markup Hidden}")
  end

end

