module AR::Game::PrinterBehavior 
  attr_accessor :drip_char_procs

  #...initialize them here
  def self.init ar_object 
    ar_object.class.attr_serializeable :console_width, :cache, :char_drip_delay
    ar_object.drip_char_procs = []
    ar_object.console_width = 60
    ar_object.cache = ""
    ar_object.char_drip_delay
  end

  def self.extended ar_object
    self.init ar_object
    #add to object's event subscriptions and resolutions here...
  end 


  def reprint_cache!
    #need both
    #osx/nix:
    system "clear"

    #sindows:
    system "cls"
    print self.cache 
  end



  def put_s s
    print_s "#{s}\n"
  end

  def print_s s
    s = process s
    really_print s
  end

  def really_print s
    self.cache += s
    print s
    nil
  end


  def drip_print_s s 
    delay = char_drip_delay || 0.0225
    s = process s
    to_print = s.dup
    until to_print.empty?
      next_ch = to_print[0]
      drip_char_procs.map{|p| p.call next_ch, self}
      really_print next_ch 
      to_print[0] = ""
      sleep delay
    end
  end

  def wrap(s)
    width = self.console_width
    s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n").chomp
  end

  def process s
    return s if console_width.nil? 
    tmp = s.dup
    if (self.since_last_line + " " + first_word(s)).length >= console_width
      tmp = "\n#{tmp}"
    end
    tmp = self.since_last_line + tmp
    tmp = wrap(tmp)
    res = tmp[self.since_last_line.length..-1] 
    res
  end

  def new_paragraph!
    new_line! 2
  end

  def new_line! n = 1
    really_print ("\n" * n)
  end

  def first_word s
    s.split(" ").first || ""
  end

  def since_last_line
    return "" if self.cache[-1] == "\n"
    ret = self.cache.split("\n").last || ""
    ret
  end

  def log_if_player s
    if self.id.to_s.include? "narration_printer"
      AR.log s
    end
  end

  def nl_replace s
    s.gsub(/\n/, "<NL>")
  end

end
