#==============================================================================
# ** Quip (Background Message) v3.1 by Lemonheaded (linesegment@gmail.com)
#------------------------------------------------------------------------------
# Shows popup message windows that go away on its own based on a set timer.
# Does not accept user input nor pauses the game, runs in the background.
#
# Please ask for clarification if documentation (in comments) are unclear.
# I'll try to fix bugs, but won't ensure compatibility with other scripts.
#
# You're free to use (and modify) this in non-commercial projects with due 
# credit. Please ask permission for commercial projects through e-mail.
#==============================================================================

#==============================================================================
# ■ Quipper (configuration options start here)
#==============================================================================

module Quipper
  
  DEFAULT_INTERVAL = 2 # duration in secs for which message is shown. if 0, stays until next quip is called, or quip is disposed through script call (quipbegone)
  DEFAULT_ALIGN = 0 # 0 for left, 1 for centre, 2 for right
  DEFAULT_FONT_COLOUR = [255,255,255,255] # red green blue alpha, only applies when speaker name isn't specified, as colours are set by speaker name in the get_color method below
  DEFAULT_OUTLINE_COLOUR = [0,0,0,128] # red green blue alpha, only applies when speaker name isn't specified, as colours are set by speaker name in the get_ocolor method below
  DEFAULT_WINDOWSKIN = "Window" # Cache.system("Window") # nil
  DEFAULT_LINE_HEIGHT = 24
  DEFAULT_CLEAR_QUEUE = true # if true, clears queue every time quip command is called
  # set in battle as 0 if you'll normally use quips in field screen. script call is quip("text") in field, quip("text",1) during battle
  # set in battle as 1 if you'll normally use quips during battle. script call is quip("text") during battle, quip("text",0) in field
  DEFAULT_IN_BATTLE = 0
  # if box wrap is true, line breaking is done manually with hard returns (enter) or "\n"
  # if box wrap is false, line breaking is automatic. hard returns and "\n" are ignored, use "\l" to manually force a line break
  DEFAULT_BOX_WRAP = false
  # if box wrap is true, x & y refer to the center co-ord of the message
  # if box wrap is false, x & y refer to the top-left co-ord of the message
  DEFAULT_X = 0
  DEFAULT_Y = 0
  # if box wrap is true, width and height and fitheight are ignored
  DEFAULT_WIDTH = 544
  DEFAULT_HEIGHT = 120
  DEFAULT_FIT_HEIGHT = true # like box-wrap for only the y co-ord. if true, height is ignored

  # all the above are defaults, and can be overridden in individual script calls.
  # if you want to go with defaults, quip("text") is enough. if you want to override anything,
  # use quip("text",1,:t=>5) during battle in troop events (1) when you want msgs to be shown for 5 seconds
  # use quip("text",0,:a=>1) in the field (0) when you want msgs to be centred
  # specifying 0 or 1 in 2nd position is mandatory when you want to override defaults, failing which you get a game-crashing error
  # you can override as many defaults as you like at one time, with all the :values in any order. e.g. quip("text",0,:t=>5,:c=>true,:s=>"Window",:n=>"Ann")
  # codes are as follows:
  # (t)ime, (x), (y), (b)oxwrap, (w)idth, (h)eight, (a)lignment, window(s)kin, (f)itheight, (l)ineheight, (c)learqueue, speaker(n)ame, fontcolo(r), (o)utlinecolor

  # quip is used to show the msg immediately, queue is used to make the msg appear after the current msg fades
  # the syntax for queue is similar to quip, only never specify the :c (clear queue) parameter for queue
  # also, the parameters for queue should be enclosed in quotes
  # e.g. quip("txt",0,:t=>2,:l=>12,:a=>1, :n=>"ANN",:s=>"Window")
  #     queue("txt",'0,:t=>2,:l=>12,:a=>1, :n=>"ANN",:s=>"Window"')
  # qclear is used to clear the queue. queue can also be cleared automatically whenever quip is called, see DEFAULT_CLEAR_QUEUE above or use :c=>true
  
  # change text colour according to speaker name, overrides font colour
  def self.get_color(spname)
    case spname
    when "Ann"
      return Color.new(0, 0, 0, 255)
    else
      return Color.new(255, 255, 255, 255)
    end
  end
  
  # change font outline colour according to speaker name, overrides normal outline colour
  def self.get_ocolor(spname)
    case spname
    when "Ann"
      return Color.new(0, 255, 0, 128)
    else
      return Color.new(0, 0, 0, 128)
    end
  end
  
  # only for when quips are shown in battle screen, to determine placement based on name of 1st enemy
  # please note that this is a relative offset from the default or overriden co-ords, not an absolute position
  # so set as [0,0] if you want to set the position manually from script calls
  def self.get_coords(enemy)
    case enemy
    when "Slime A"
      return [0,0]
    else
      return [0,0]
    end
  end
 
end # Quipper

#==============================================================================
# end of configuration options. Don't edit the following unless you're sure you
# know what you're doing
#==============================================================================

#==============================================================================
# ■ Window_Quip
#==============================================================================

class Window_Quip < Window_Base
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------  
  attr_accessor :time
  attr_accessor :lineheight
  
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(x, y, width, height)
    super
    update_padding
    update_tone
    create_contents
    @opening = @closing = false
  end

  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    if @time != 0
      if @timer == nil
        @timer = @time
      elsif @timer > 0
        @timer -= 1
        if @timer <= 0
          self.visible = false
          $queue = [] if $queue == nil
          if $queue.length != 0
            qtxt, qcmd = $queue.shift
            qcmd = qcmd.gsub("\n","")
            qcmd = "@qui.quip(" << "'" << qtxt << "'," << qcmd << ",:c=>false)"
            @qui = Game_Interpreter.new unless @qui
            eval(qcmd)
          end
        elsif @timer < 60
          @opacfrac ||= 255/@timer
          self.opacity -= @opacfrac
          self.contents_opacity -= @opacfrac
        end
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # draw_background_colour
  #--------------------------------------------------------------------------
  def draw_background_colour
    temp_rect = contents.rect.clone
    temp_rect.width *= 0.667
    back_colour1 = Color.new(0, 0, 0, 192)
    back_colour2 = Color.new(0, 0, 0, 0)
    contents.gradient_fill_rect(temp_rect, back_colour1, back_colour2)
  end
  
  #--------------------------------------------------------------------------
  # line_height
  #--------------------------------------------------------------------------
  def line_height
    return @lineheight
  end

end

#==============================================================================
# ■ Game_Interpreter
#==============================================================================

class Game_Interpreter
  
  #--------------------------------------------------------------------------
  # new method: quip
  #--------------------------------------------------------------------------
  def quip(text, enemy=Quipper::DEFAULT_IN_BATTLE, options={})    
    options = {:t=>Quipper::DEFAULT_INTERVAL, :x=>Quipper::DEFAULT_X, :y=>Quipper::DEFAULT_Y, :b=>Quipper::DEFAULT_BOX_WRAP, :w=>Quipper::DEFAULT_WIDTH, :h=>Quipper::DEFAULT_HEIGHT, :a=>Quipper::DEFAULT_ALIGN, :s=>Quipper::DEFAULT_WINDOWSKIN, :f=>Quipper::DEFAULT_FIT_HEIGHT, :l=>Quipper::DEFAULT_LINE_HEIGHT, :c=>Quipper::DEFAULT_CLEAR_QUEUE, :n=>"", :r=>Quipper::DEFAULT_FONT_COLOUR, :o=>Quipper::DEFAULT_OUTLINE_COLOUR}.merge(options)
    time, x, y, boxwrap, width, height, align, windowskin, fitheight, lineheight, clearqueue, spname, fontcolour, outlinecolour = options[:t], options[:x], options[:y], options[:b], options[:w], options[:h], options[:a], options[:s], options[:f], options[:l], options[:c], options[:n], options[:r], options[:o]
    
    if enemy == 1
      x_offset, y_offset = Quipper.get_coords($game_troop.members[0].name)
      x += x_offset
      y += y_offset
    end
    if boxwrap
      splittext = text.split("\n")
      textlength = splittext.max{|x,y| x.size <=> y.size}.length
      width = textlength * 10 + 30
      height = splittext.length * lineheight + 12 * 2
      height += lineheight if spname != ""
      x -= width/2
      y -= height/2
    else
      text = text.gsub("\n","")
      presplittext = text.split("\l")
      splittext = []
      maxchar = ((width - 12 * 2)/10).floor #52c for 544px
      presplittext.each do |line|
        charcount = 0
        pline = ""
        line = line.split(" ")
        line.each do |word|
          newcharcount = charcount + word.length
          if newcharcount > maxchar
            splittext << pline
            charcount = 0
            pline = ""
          end
          pline << word
          pline << " "
          charcount += (word.length + 1)
        end
        splittext << pline
      end
      height = splittext.length * lineheight + 12 * 2 if fitheight
      height += lineheight if spname != ""
    end
    qclear if clearqueue
    $quip.dispose if $quip
    $quip = Window_Quip.new(x,y,width,height)
    $quip.z = 30
    if windowskin == nil or windowskin == "nil"
      $quip.windowskin = nil
    else
      $quip.windowskin = Cache.system(windowskin)
    end
    $quip.lineheight = lineheight
    $quip.time = time*60
    if spname != ""
      $quip.change_color(Color.new(255, 255, 255, 255))
      $quip.contents.font.out_color.set(Color.new(0, 0, 0, 128))
      $quip.draw_text(0, 0, $quip.contents.width, $quip.fitting_height(0), spname, align)
      $quip.change_color(Quipper.get_color(spname))
      $quip.contents.font.out_color.set(Quipper.get_ocolor(spname))
    else
      cr, cg, cb, ca = fontcolour
      $quip.change_color(Color.new(cr, cg, cb, ca))
      cr, cg, cb, ca = outlinecolour
      $quip.contents.font.out_color.set(Color.new(cr, cg, cb, ca))
    end
    splittext.each_with_index do |txt, i|
      i += 1 if spname != ""
      $quip.draw_text(0, 0 + i*$quip.line_height, $quip.contents.width, $quip.fitting_height(0), txt, align)
    end
  end

  #--------------------------------------------------------------------------
  # new method: queue
  #--------------------------------------------------------------------------
  def queue(txt, para)
    $queue = [] if $queue == nil
    $queue << [txt, para]
  end
  
  #--------------------------------------------------------------------------
  # new method: qclear
  #--------------------------------------------------------------------------
  def qclear
    $queue = []
  end
  
  #--------------------------------------------------------------------------
  # new method: quipbegone
  #--------------------------------------------------------------------------
  def quipbegone
    $quip.time = 60 # in frames
  end
  
end

#==============================================================================
# ■ Scene_Battle
#==============================================================================

class Scene_Battle < Scene_Base
  
  #--------------------------------------------------------------------------
  # alias method: terminate
  #--------------------------------------------------------------------------
  alias scene_battle_terminate_quip terminate
  def terminate
    scene_battle_terminate_quip
    $quip.visible = false
  end
  
  #--------------------------------------------------------------------------
  # alias method: update_basic
  #--------------------------------------------------------------------------
  alias scene_battle_update_basic_quip update_basic
  def update_basic
    scene_battle_update_basic_quip
    $quip = Window_Quip.new(0,0,0,0) if $quip == nil
    $quip.update
  end
  
end

#==============================================================================
# ■ Scene_Map
#==============================================================================

class Scene_Map < Scene_Base
  
  #--------------------------------------------------------------------------
  # alias method: update
  #--------------------------------------------------------------------------
  alias scene_map_update_quip update
  def update
    scene_map_update_quip
    $quip = Window_Quip.new(0,0,0,0) if $quip == nil
    $quip.update
  end
  
  #--------------------------------------------------------------------------
  # alias method: terminate
  #--------------------------------------------------------------------------
  alias scene_map_terminate_quip terminate
  def terminate
    scene_map_terminate_quip
    $quip.visible = false
  end
  
end