class GoWin
  include Game

  attr_reader :game_info
  attr_reader :goban, :w_p_inf, :b_p_inf, :game_disp
  attr_reader :show_move_nb


  def initialize

    @game_adjourned=  @game_completed= false
    @move_msg= @info_msg = ''
    @show_move_nb = Defaults.get_default_value('show_move_nb')
    @show_coords= Defaults.get_default_value('show_coordinates')
    @show_hoshis= Defaults.get_default_value('show_hoshis')
    @show_diagram_name= Defaults.get_default_value('show_diagram_name')
    @remove_captured= Defaults.get_default_value('remove_captured_stones')
    @show_list_moves= Defaults.get_default_value('list_hidden_moves')
    @print_float_figures= Defaults.get_default_value('print_float_figures')
    @show_right =  Defaults.get_default_value('show_commands')
    @show_siblings= Defaults.get_default_value('show_siblings')
    @show_markup= Defaults.get_default_value('show_markup')
    @show_move_nb = Defaults.get_default_value('show_move_nb')
    @node_annotation = TkVariable.new('')

    @diagram_name= ''
    @list_hidden_moves= []

    @edit_item= nil

    open_win

  end

  def open_win
    open_win_basic

  end

  def quit
    close
  end

  def close

    return if @top.nil?

    # @detached_text.destroy if @detached_text
    @goban.destroy if @goban

    @top.destroy
    @top=nil
  end

  def open_win_basic


    @top= GoWindow.new(self)
    @top.protocol('WM_DELETE_WINDOW', proc{ quit })

    @main = TkFrame.new(@top,TkDefaults::GUI[ 'Gowin.frame.main'])
    @main.pack('fill'=> 'both','expand'=>'yes')

    @mid = TkFrame.new(@main,TkDefaults::GUI['Gowin.frame.mid']).pack('side'=>'left','fill'=> 'both','expand'=>'yes')

    @right = TkFrame.new(@main,TkDefaults::GUI['Gowin.frame.right'])
    @right.pack( 'side'=>'right','fill' => 'both','expand'=>'no') if Defaults.get_default_value('show_commands').value == '1'

    @msgline =  VTexturedPane.new(@mid,Defaults::DEFS['gowin-bg'],0,2,10,0).pack('fill'=>'x')
    @msgline.configure('relief'=>'raised', 'borderwidth'=>1)

    @msg = @msgline.add_text('fill'=> 'white')

    @msg.configure('text'=>'') # calcul de la hauteur

    @f1 = TkFrame.new(@right).pack('expand'=>'no','fill'=>'both')
    @f2 = TkFrame.new(@right).pack('expand'=>'yes','fill'=>'both')

    @talk = Dialog.new(@f2,self.class.to_s ).pack('fill'=>'both','expand'=>'yes')

    @node_bar= HTexturedPane.new(@mid, Defaults::DEFS['black'],0,2,10,0).pack('fill'=> 'x','side'=>'bottom')
    @node_bar.configure('borderwidth'=>1, 'relief'=> 'raised')
    @node_name= @node_bar.add_text('fill'=>'white')
    @node_name.configure('text'=>'') #calcul de la hauteur
    @node_annot= @node_bar.add_text('fill'=>'white','text'=>'')
  end

  def open_win_info
    @info=  VTexturedPane.new(@f1,Defaults::DEFS['CommonBackground'],10,20,1,6).pack('fill'=>'both','expand'=>'no','side'=>'left')

    @w_p_inf = PlayerInfo.new(@info, 'white').pack('pady'=>5)
    @w_p_inf.configure('relief' => 'groove','borderwidth'=>4 )
    @b_p_inf = PlayerInfo.new(@info,'black').pack('pady'=>5)
    @b_p_inf.configure('relief' => 'groove','borderwidth'=>4 )

    @game_disp= GameDisplay.new(@info).pack('padx'=>5,'pady'=>5)
    @game_disp.configure('relief' => 'groove','borderwidth'=>4 )

    playsound('chimes.wav')
  end

  def set_title(title)
    name= title
    if index= name.index("\n")
      name= name[0,index ]
    end
    if name.length > 40
      name = name[0,40]
    end

    @top.title(name)
  end

  def set_node_name(txt)
    @node_name.configure('text'=> txt) if @node_name
  end

  def set_byo_stones(v)
   @game_disp.set_byo_stones(v) if @game_disp
  end

  def set_byo_periods(v)
   @game_disp.set_byo_periods(v) if @game_disp
  end

  def set_byo_time(v)
    @game_disp.set_byo_time(v) if @game_disp
  end

  def set_time(v)
    @game_disp.set_time(v) if @game_disp
  end

  def set_number(v)
    @game_disp.set_number(v) if @game_disp
  end

  def set_type(v)
    @game_disp.set_type(v) if @game_disp
  end

  def set_handi(h)
    super(h)
    @game_disp.set_handi(h) if  @game_disp
  end

  def set_komi(k)
    super(k)
    @game_disp.set_komi(k) if @game_disp
  end
   

  def set_rank(who,r)
    inf= (who == ?W ? @w_p_inf : @b_p_inf)
    inf.set_rank(r) if inf
  end

  def set_name(who,n)
    inf= (who == ?W ? @w_p_inf : @b_p_inf)
    inf.set_name(n) if inf

  end

  def set_msg(msg = nil)
    if msg.nil?
      @msg.configure('text'=> @move_nb.to_s + ' '+ @move_msg + ' ' + @info_msg)
    else
      @msg.configure('text'=>msg)
    end
  end

  def set_info_msg(line)
    @info_msg=line
    set_msg
  end

  def clear_msg
    @move_msg= @info_msg = ''
    @msg.configure('text'=>'')
  end

  def set_move_label(str)
    @move_msg = str
    set_msg
  end

  def set_show_vars(val)
    @show_siblings.value= ((val & 1 == 1) ? '1' : '0')
    @show_markup.value= ((val & 2 == 2) ? '0' : '1')
  end


  def set_show_move_nb(val)
    @goban.show_move_nb.value= val
    if val == '2'
      @goban.delta_move = @move_nb - @move_nb % 100
    else
      @goban.delta_move = 0
    end

  end

  def set_show_coords(v=nil)
    @show_coords.value= v   unless v.nil?
    if @show_coords.value == '0'
      @goban.canvas.lower('Coords')
    else
      @goban.canvas.raise('Coords')
    end
  end

  def set_show_hoshis(v=nil)
    @show_hoshis.value= v   unless v.nil?
    if @show_hoshis.value == '0'
      @goban.canvas.lower('Hoshis')
    else
      @goban.canvas.raise('Hoshis')
      @goban.raise_all
    end
  end

  def set_show_diagram_name(v=nil)
    @show_diagram_name.value= v   unless v.nil?
    if   @show_diagram_name.value== '1'
      @info_msg= @diagram_name
      set_msg
    end
  end

  def set_diagram_name(name)
    @diagram_name=name
    if   @show_diagram_name.value== '1'
      @info_msg= @diagram_name
      set_msg
    end
  end

  def set_show_list_moves (v=nil)
    @show_list_moves.value= v   unless v.nil?
  end

  def set_remove_captured (v)
    @remove_captured.value= v
  end

  def set_root(root)

    super(root)

    @goban.destroy if @goban

    @goban = GoGame.new(@mid,@width,@height).pack('fill'=> 'both','expand'=>'yes')


    if @root.has_key?('GN') and  @root['GN'].values[0]  =~ /Kogo/
      set_node_annot('Kogo\'s Joseki detected - setting "show letters" to "false"')
      @show_markup.value= false
    end

    #  @virtual_text= VirtualText.new(@goban.canvas,10)

    set_node( @root)
    set_turn('B')

  end

def change_turn(color)
  @current_node.set('PL',color)
  @current_node['PL'].action(self)
end

  def open_editor
    GoEditor.new(@collection)
  end

  def add_comment(line)
    @talk.putline(line)
  end

  def clear_comment
    @talk.clear
  end

  def set_node_annot(txt)
    @node_annot.configure('text' => txt) if @node_annot
  end

  def set_annot(txt)
    set_node_annot(txt)
  end

  def add_pris(color,col,row,nb)

    super(color,col,row,nb)

    if  @remove_captured.value== '0'
      @list_hidden_moves.push([color,col,row,nb])
    else
      @goban.delete_stone(col,row)
    end
  end

  def del_pris(color,col,row,nb)

    super(color,col,row,nb)
    if  @remove_captured.value== '1'
      @list_hidden_moves.delete([color,col,row,nb])
    end
  end

  def delete_stone(col,row)
    super(col,row)
    @goban.delete_stone(col,row)
  end

  def put_stone(color,col,row,nb)
    super(color,col,row,nb)
    #debug "#{color}  #{col} #{row} #{nb}"
    #return if @show_move_nb.nil? # bug ?
    if col
      if @remove_captured.value== '0' and @game[col][row] == ?E and @goban.board[col][row]
	@list_hidden_moves.push([color,col,row,nb])
      else
	return @goban.put_stone(color,col,row,nb)
      end
    else
      @goban.unset_mark
    end
    nil
  end

  def set_mark(col,row)
    @goban.set_mark(col,row)
  end

  def set_stone(c,col,row)
    super(c,col,row)
    @goban.set_stone(c,col,row)
  end

  def add_text(text,col,row)
	  @goban.add_text(text,col,row)
  end


  def open_file(file = nil)

    #debug $defaultFiles

    if file.nil?
      file=@top.getOpenFile($defaultFiles)
      return if  file.empty?
    end


    @file= file
    $defaultFiles.update('initialfile'=>  File.basename(@file) )
    $defaultFiles.update('initialdir'=>  File.dirname(@file) )

    begin
      @file= file
      collection= SGF.new
      collection.read_file(file)
      set_collection collection
      set_title(@file)
    rescue
      $stderr.puts "Error when reading #{file}: " + $!
      $stderr.puts  $@
      Misc.warning("Error when reading #{file}:\n" + $!)
    end
  end

  def save_file

    if  @file.nil?
      if @root['GN'].nil? or @root['DT'].nil?
	@file='New_game'
      else
	@file =   @root['GN'].values[0]+ '-'+ @root['DT'].values[0]
      end
      $defaultFiles.update('initialfile'=>  File.basename(@file) )
    end
    file=@top.getSaveFile($defaultFiles)
    return if file.empty?

    @file= file
    $defaultFiles.update('initialdir'=>  File.dirname(@file) )
    $defaultFiles.update('initialfile'=>  File.basename(@file) )
    @collection.write_file(@file)
  end

  def save_var

    file=@top.getSaveFile($defaultFiles)
    return if file.empty?
    @file= file
    $defaultFiles.update('initialdir'=>  File.dirname(@file) )
    $defaultFiles.update('initialfile'=>  File.basename(@file) )
    @collection.write_var(file,@current_node)
  end

  def save_ascii
    file=@top.getSaveFile("filetypes"=>[["Ascii file", ".txt"]], "defaultextension"=>".txt","title"=>"Save as ascii diagram")
    return if file.empty?
    File.open(file,"w") { |f| f.print(self.to_ascii) }
  end

  def set_collection(collect)
    @collection=collect
    set_root( @collection[0])
  end

  def set_clock(who,clock)

    super(who,clock)
    if who == 'W'
      @w_p_inf.set_clock(clock)
    else
      @b_p_inf.set_clock(clock)
    end

  end

  def set_byo(who,byo)
    super(who,byo)
    if who == 'W'
      @w_p_inf.set_byo(byo)
    else
      @b_p_inf.set_byo(byo)
    end
  end

	def view_sgf
		wd= GoWindow.new('ViewSgf')
	    opts=TkDefaults::GUI['ViewSgf.text']
		txt= TkText.new(wd,opts).pack('expand'=>'yes','fill'=>'both')
		txt.insert('end', @collection.to_s)
	end

  def score_game
    GoScore.new(self)
  end

  def edit
    gos = GoSetup.new(self,@width,@height)
    copy_goban(gos.goban)
    gos
  end

  def copy_goban(goban)
    @goban.items.each_value { |item|
      if item.class == Stone or item.class == Point
	goban.set_obj(item.class,item.color,item.col,item.row)
      end
    }

    @goban.items.each_value { | item|
      if item.kind_of? Markup  and not item.kind_of? Text
	goban.set_mark(item.class,item.col,item.row) unless item == @goban.mark or item.class== TextMove
      end
    }

    @goban.items.each_value { | item|
      if item.kind_of? TwoPoints
	goban.set_2p(item.class,item.col, item.row, item.c2, item.r2)
      end
    }

    @goban.items.each_value { | item|
      if item.class== Text
	goban.set_text(item.text_value,item.col,item.row)
      end
    }

    goban.raise_all
  end

  class Gomme
  end

  def keypressed(key)
    case key
    when 'Escape'
      @edit_item=nil
      @goban.cursor('')
    when 'F1'
      @edit_item=Triangle
    when 'F2'
      @edit_item=Circle
    when 'F3'
      @edit_item=Rectangle
    when 'F4'
      @edit_item=Cross
    when 'F5'
      @edit_item=Text
      @edit_char= 'a'
    when 'F6'
      @edit_item= Gomme
    end
    ready
  end

def create_file(c,r)
  col=c.to_i
  row=r.to_i

  if col>0 and row>0
    coll= SGF.new
    root=Node.new
    root['AP']= 'RubyGo:'+ $version
    root['GM']= '1'
    root['FF']= '4'
    root['SZ']= col.to_s+':'+row.to_s
    coll.push(root)
    set_collection(coll)
  end

end

  def set_forward
    if  @current_node.next.nil?
      stop_play
      return
    end
    set_node @current_node.next
  end

  def set_backward
    return if  @current_node.prev.nil?
    undo_node
    set_node @current_node.prev
  end

  def set_fastb
    return if @current_node.prev.nil?
    i = 1
    @goban.fast_move= true
    until  i == Defaults::REPLAY['fast_backward']
      break if @current_node.prev.prev.nil?
      undo_fast_node
      @current_node = @current_node.prev
      i += 1
    end
    @goban.fast_move=false
    set_backward
  end

  def set_fastf
    return if @current_node.next.nil?
    i = 1
    goban.fast_move= true
    until  i == Defaults::REPLAY['fast_forward']
      break if @current_node.next.next.nil?
      set_fast_node( @current_node.next)
      i += 1
    end
    goban.fast_move=false
    set_forward
  end

  def set_begin
    @goban.fast_move= true
    while @current_node.prev != @root and  @current_node.c_var == ?A
      undo_fast_node
      @current_node = @current_node.prev
    end
    @goban.fast_move=false
    set_backward

  end

  def set_end
    return if @current_node.next.nil?
    @top.cursor('watch')
    goban.fast_move= true
    while  @current_node.next.next and @current_node.next.next.var_next.nil?
      set_fast_node(@current_node.next)
    end
    goban.fast_move=false
    set_forward
    @top.cursor('')
  end

def config_btns
# ne doit pas etre appelé si cmd pas ouverte
 
    if @current_node.prev.nil?
      @b_begin.configure('state'=>'disabled')
      @b_fastb.configure('state'=>'disabled')
      @b_backw.configure('state'=>'disabled')
    else
      @b_begin.configure('state'=>'normal')
      @b_fastb.configure('state'=>'normal')
      @b_backw.configure('state'=>'normal')
    end

    if @current_node.next.nil?
      @b_end.configure('state'=>'disabled')
      @b_fastf.configure('state'=>'disabled')
      @b_forw.configure('state'=>'disabled')
    else
      @b_end.configure('state'=>'normal')
      @b_fastf.configure('state'=>'normal')
      @b_forw.configure('state'=>'normal')
    end

  end



end
