#
# RRreadline.rb
#
#   $Author: hiroya $
#   $Date: 2000/11/23 01:53:10 $
#   Copyright (C) 2000 Hiroya KUBO
#

require "KeyBind"
require "Terminal"
require "EditingLine"
require "EditingContext"
require "CommandLineActions"

$term = nil
$suspendTerminal = nil

trap("SIGTSTP") do
  $term.print("stop").echo(true)
  $suspendTerminal = true
end

trap("SIGINT") do
  $term.echo(true).newline
  exit;
end

trap("SIGQUIT") do
  $term.echo(true).newline
  exit;
end

class RReadline

  include CommandLineActions

  def initialize
    @keybind = KeyBindFactory.new.create
    @term = TerminalFactory.new.create
    @line = EditingLine.new
    @ctx = EditingContext.new

    $term = @term
    @chr = nil

  end
 
  def getHistory
    return @ctx.getEditingHistory
  end

  def setHistory(history)
    @ctx.setEditingHistory(history)
  end

  def getEditingContext
    return @ctx
  end

  def setEditingContext(ctx)
    @ctx = ctx
  end

  def getEditingLine
    return @line
  end

  def setEditingLine(line)
    @line = line
  end

  # -- key bind --

  def getKeyBind
    return @keybind
  end

  def setKeyBind(keybind)
    @keybind = keybind
  end

  # -- prompt --

  def _print(list)
    @term.print(list)
  end

  def prompt
    _print("> ")
  end

  def showPrompt
    prompt
    @term.print(@line.getValue)
    if(@line.size > 0 )
      @term.rewind
      prompt
      if(@line.getCursorPosition > 0)
	if(@term.end_of_line(@line.getCursorPosition) == 0)
	  @term.print(@line.toString).ln
	else  
	  @term.print(@line.toString)
	end
      end
    end
  end

  # -- completion -- 

  def getCompletingList(key)
    return nil
  end

  def showCompletingList(array)
    if(array!=nil)
      array.each{|arg|
	@term.print(arg).newline
      }
    end
  end

  # -- main --

  def readline(addHistory = true)
    @term.echo(false)
    @line.clear
    @ctx.clearCompositeKeyStroke
    showPrompt

    begin
      while (chr = STDIN.getc)
	# resume terminal after C-z
	if($suspendTerminal == true)
	  @term.echo(false)
	  $suspendTerminal = false
	end

	begin
	  c = sprintf("%c", chr)
	  @ctx.setCurrentChar(c)
	  @ctx.addCompositeKeyStroke(c)

	  actionName = "default_command"
	  if((ka = @keybind[@ctx.getCompositeKeyStroke]) != nil)
	    actionName = ka.getAction
	  elsif((ka = @keybind[chr]) != nil)
	    actionName = ka.getAction

	  elsif( 32 <= chr &&  chr <= 126)
	    # " " to "~"
	    actionName = "self_insert_command"
	  end

	  eval actionName

	  @ctx.clearCompositeKeyStroke
	rescue ContinueCompositeKeyStroke
	end
      end
    rescue EndCommandLineEditor
      line = @line.getValue
      if(addHistory != nil && line != nil && line != "")
	@ctx.storeCurrentEditingHistory(line)
      end
    ensure
      @term.echo(true)      
    end

    return @line.getValue
  end

end

