module IgsObserver
  attr_reader :number, :white, :black, :header, :game_over, :game_info

  def igs_init(header,title)

    @collection= SGF.new

    if header
      @last_node = Node.new
      @last_node['AP']= 'RubyGo:'+ $version
      @last_node['GM']= '1'
      @last_node['FF']= '4'
      @last_node['DT']= Time.now.strftime '%Y-%m-%d'
      @last_node['GN']= title ? title : header.white + '-' + header.black
      @last_node['PC']= $server_name if $server_name

      @white= header.white
      @black= header.black
    else 
      debug "ben pourquoi nil?"
    end

    @game_over= false
    @buf_comments = ''
  end

  def igs_set_info (game_info)

    @game_info=game_info

    @last_node['ID']=  game_info.number
    @number = game_info.number

    @last_node['PW']=  game_info.w_player
    @last_node['PB'] = game_info.b_player
    @last_node['BR'] = game_info.b_rank
    @last_node['WR'] = game_info.w_rank

    @last_node['HA'] = game_info.handicap if  game_info.handicap > 0
    @last_node['KM'] = game_info.komi
    #FF4
    @last_node['OT'] = (game_info.byo * 60).to_s
    @byo_time = (game_info.byo * 60)
    #FF5
    #@last_node['TO'] = 'OP:A:' + (game_info.byo * 60).to_s
    #@last_node['TO'] = 'OM:A:25'
    #@last_node['TO'] = 'NO:A:1'

    @last_node['SZ'] = game_info.size
    @size= game_info.size

    @last_node['GC']= 'Free'  if game_info.free
    @last_node['GC']= 'Teach' if game_info.teach

    set_root(@last_node)
    @collection.push(@root)

  end

  def set_adjourned(line)
    @game_adjourned= true

    @last_node['N']= line
    @last_node['N'].action(self)

  end

  def set_completed(g,line)
    @last_node['N']= line
    @last_node['N'].action(self)

    @game_completed= true

    if g.w_score.nil?
      if g.message =~ /adjourned/
        str= g.message
      elsif g.message =~ /(\S+) (\S+).*/
        str = ($1 == 'Black' ? 'W+' : 'B+')
      #~ if $2 == 'resigns.'
        str << 'Resign'
      else
        str << 'Time'
      end
    else
      if g.w_score > g.b_score
        str= "W+#{g.w_score - g.b_score}"
      else
        str= "B+#{g.b_score - g.w_score}"
      end
    end 

    @root['RE']=str
    @root['RE'].action(self)

  end

  def set_resigned(line)
    @last_node['N']= line
    @last_node['N'].action(self)
    @game_completed= true
  end

  def set_header(header)

    @header_node = Node.new
    @header_node['WL'] = header.w_clock
    @header_node['BL'] = header.b_clock
    @header_node['OB'] = header.b_byo
    @header_node['OW'] = header.w_byo


  end

  def igs_set_komi(km)
    @root.set('KM',km)
    @root.get_prop('KM').action(self)
  end
  def igs_set_free(km)
     @root.set('GC','Free')
     @root.get_prop('GC').action(self)
  end
  def igs_set_rated(km)
     @root.set('GC','')
     @root.get_prop('GC').action(self)
  end


  def igs_set_handi(h)
    @root.set_handi(h)
  end

  def push_node(node)

#debug "modif"
    @last_node['C']= @buf_comments unless @buf_comments.empty?
    @buf_comments= ''
    if @last_node.next
       nxt= @last_node.next
       nxt= nxt.var_next while nxt.var_next
       nxt.c_var= ?A if nxt.c_var.nil?
       node.c_var= nxt.c_var + 1
       node.var_prev = nxt
       node.prev = nxt.prev
    else
      @last_node.next = node
      node.prev = @last_node
      node.c_var= ?A
    end

    set_node(node) if @current_node == @last_node
    @last_node = node
    @header_node = nil


  end

  def push_fast_node(node)
    @last_node.next = node
    node.prev = @last_node
    node.c_var= ?A
    set_fast_node(node)
    @last_node = node
  end

  def pop_node

    undo_node(@last_node)
    set_node(@last_node.prev) if @current_node == @last_node
    @last_node= @last_node.prev
    @last_node.next = nil
    @header_node = nil # ?
  end

 def set_fast_move(move)
   node =  Node.new
   make_node(node,move)
   push_fast_node(node)
 end
	
def make_node(node,move)
node['MN'] = move.number

    case move.action
    when 'Move'
      x,y = Move.to_cr(move.coords)
      col,row =  Grid.to_int(x,y,@size)
      node[move.player] = Coords.to_a(col,row)
     #  debug "#{move.coords} = #{col} #{row} " << a << b
    when 'Pass'
      node[move.player]= ''
    when 'Handicap'
      @root.set('HA', move.handicap)

      array= IGSProtocol::HANDICAP19 if @size == 19
      array= IGSProtocol::HANDICAP13 if @size == 13
      array= IGSProtocol::HANDICAP9  if @size == 9

      array[move.handicap ].each { |coords|
        x,y = Move.to_cr(coords)
        col,row =  Grid.to_int(x,y,@size)
        node['AB']= Coords.to_a(col,row)
      }
      node['PL'] = 'W'
    end

end

  def set_move (move)
      node = @header_node
      make_node(node,move)
      push_node(node)
	@header_node=nil

  end

  def undo 
    pop_node
  end

  def set_status (status)
    node = Node.new

  #w_pris, w_TIF not used ?

    node['WL'] = status.w_clock
    node['BL'] = status.b_clock
    node['OB'] = status.b_byo
    node['OW'] = status.w_byo
    node['WP'] = status.w_pris
    node['BP'] = status.b_pris

    for col in 0...@size
      for row in 0...@size
        case status[col,row]
        when IGSProtocol::S_BLACK
          if @game[col][row]!= ?B
            $stderr.puts "warning: found a black stone that where \
not there at #{Grid.to_coords(col,row,@height)}" 
node['AB']= Coords.to_a(col,row)
          end

        when IGSProtocol::S_WHITE
          if @game[col][row]!= ?W
            $stderr.puts "warning: found a white stone that where \
not there at #{Grid.to_coords(col,row,@height)}" 
node['AW']= Coords.to_a(col,row)
          end
        when IGSProtocol::S_EMPTY
          if @game[col][row]!= ?E
            $stderr.puts "warning: found an empty point that where \ 
not there at #{Grid.to_coords(col,row,@height)}" 
node['AE']= Coords.to_a(col,row)
          end
        when IGSProtocol::S_DAME
          node['DA']= Coords.to_a(col,row)
        when IGSProtocol::S_W_POINT
          node['TW']= Coords.to_a(col,row)
        when IGSProtocol::S_B_POINT
          node['TB']= Coords.to_a(col,row)
        end

      end
    end

    push_node(node)

  end


end # module

