#!/usr/bin/env ruby

# このままだと最後で改行しないと駄目
# 何も入れずにリターンを入力するとおかしくなる

require 'gtk'
require 'irb-wrapper'

include Gtk

def editor_debug 
  window = Window.new
  window.set_default_size(200, 200)
  vbox = VBox.new
  window.add(vbox)
  @editor = Editor.new
  vbox.pack_start(@editor, true, true, 3)
  hbox = HBox.new
  vbox.pack_start(hbox, true, true, 3)
  btn1 = Button.new("Button 1")
  btn2 = Button.new("Button 2")
  btn3 = Button.new("Button 3")
  hbox.pack_start(btn1, true, true, 3)
  hbox.pack_start(btn2, true, true, 3)
  hbox.pack_start(btn3, true, true, 3)
  window.show_all

  def window.destroy 
    exit
  end
  
  btn1.signal_connect('clicked') do |btn|
    @editor.buffer_write("hogehoge")
  end

  btn2.signal_connect('clicked') do
    p @editor.buffer_gets
  end

  btn3.signal_connect('clicked') do
    p $i
  end
  
  Gtk::main
end




class Editor < Text

  def initialize
    super
    @can_gets = false
    @length_when_get_last = 0
    set_editable(true)

    # ユーザーの入力に改行があると、
    # buffer_getsが値を返せるように
    # @can_getsにtrueを入れる。
    signal_connect('key_press_event') do |edit, event|
      if event.keyval == Gdk::GDK_Return # Return 
	#p get_length
	@can_gets = true
      end
    end

    #signal_connect('destory'){ exit }
  end

  
  # 最後にbuffer_getsしてから
  # buffer_writeまでの間に
  # ユーザーからのバッファへの入力がないことを前提にしている
  def buffer_write(str)
=begin
    STDOUT.print "buffet_write string: "
    STDOUT.p str
    STDOUT.print "buffet_write string type: "
    STDOUT.p str.type
=end
    begin 
      insert(nil, nil, nil, str)
      
      # IRB側からの入力はbuffer_getsで取れないようにする
      @length_when_get_last = get_length
      return true
    rescue
      return false
    end
  end

  alias buffer_putc buffer_write


  
  # とりあえずrsは無視
  # EOFは存在しないので、nilは返さない
  def buffer_gets(rs = $/)
    while true
      # Retun が入力されるまでループ
      if @can_gets 
	break
      end

      # 再描画
      while (Gtk.events_pending)
	Gtk.main_iteration
      end
      sleep 0.03
    end

    str = get_chars(@length_when_get_last, get_length)
    @length_when_get_last = get_length
    @can_gets = false
    str
  end

end




class  IRBWindow < Window

  def initialize
    super
    set_modal(true)
    set_default_size(300, 250)
    @editor = Editor.new

    scroll_window = Gtk::ScrolledWindow.new
    scroll_window.add(@editor)
    add(scroll_window)
  end

  def editor
    @editor
  end
end


class MainWindow 
  
  def initialize(w)
    @window = Window.new(Gtk::WINDOW_TOPLEVEL)
    @button = Button.new('IRB')
    @window.add(@button)
    @window.show_all
    @window.set_default_size(100,100)
      
    def @window.destroy
      exit
    end

    @button.signal_connect('clicked') do
      w.show_all
      IRB.start_on_gui
    end
    
  end

end


#
# Main
#

if ARGV[0] == '-e'
  editor_debug
end
  

w = IRBWindow.new

# STDOUT STDIN SDTERRを差し替える
$> = GUIWrapper::GuiConsole.new(w.editor)
include GUIWrapper::GuiIoEmulate
$stdout = $>
$stdin = $>
$stderr = $>


window = MainWindow.new(w)
Gtk::main
  


