#!/usr/bin/env ruby
begin
  require 'libglade2'
rescue
  require "lglade"
end
require "gnomevfs"
require "drb/drb"
require "narray"

class NArray
  def self._load(o) to_na(*Marshal::load(o)).ntoh end
end
class NArrayMiss
  def self._load(o)
    ary, mask = Marshal::load(o)
    ary = NArray._load(ary)
    mask = NArray._load(mask)
    NArrayMiss.to_nam_no_dup(ary,mask)
  end
end
  

class DFileSelection
  Glade_file = "numru/gave/fileselection.glade"
  def initialize(title="FileSelection")
    path = nil
    $:.each{|path| break if File.exist?(path+"/"+Glade_file) }
    glade = GladeXML.new(path+"/"+Glade_file) {|handler| method(handler)}
    @window = glade.get_widget("Fileselection")
    @window.hide
    @window.title = title
    @ok = glade.get_widget("ok")
    @entry = glade.get_widget("entry")
    hpaned = glade.get_widget("hpaned1")
    hpaned.position=245
    @dirlist = glade.get_widget("dirlist")
    @filelist = glade.get_widget("filelist")
    column = Gtk::TreeViewColumn.new("Dir", Gtk::CellRendererText.new,
                                     {:text=>0})
    @dirlist.append_column(column)
    column = Gtk::TreeViewColumn.new("File", Gtk::CellRendererText.new,
                                     {:text=>0})
    @filelist.append_column(column)
    @dirlist.show_all
    @filelist.show_all
    @dirmodel = Gtk::TreeStore.new(String)
    @filemodel = Gtk::TreeStore.new(String)
    @dirlist.model = @dirmodel
    @filelist.model = @filemodel
    GnomeVFS.init
    @uri = GnomeVFS::URI.new(File.expand_path("."))
    make_models
  end

  def on_dirlist_cursor_changed(widget)
    path = widget.cursor[0]
    name = @dirmodel.get_iter(path)[0]
    if GnomeVFS::URI===@uri
      uri = @uri.append_path(name)
      return until uri.exists?
      return if @uri.to_s==uri.to_s
      @uri = uri 
    else
      return until @uri.list_dirs.index(name) || name=="." || name==".."
      uri = @uri.dir(name)
      return if @uri.path==uri.path
      @uri = uri
    end
    make_models 
  end
  def on_filelist_cursor_changed(widget)
    path = widget.cursor[0]
    name = @filemodel.get_iter(path)[0]
    if GnomeVFS::URI===@uri
      uri = @uri.append_path(name)
      return until uri.exists?
      @entry.text = uri.to_s
    else
      return until @uri.list_data.index(name)
      @entry.text = @uri.__drburi+@uri.path+name
    end
  end
  def on_entry_activate
    jump
  end
  def on_jump_clicked(widget)
    jump
  end
  def jump
    if @entry.text =~ /^druby:\/\//
      path = @entry.text
      uri = DRbObject.new(nil,path)
      return until uri
      @uri = uri
    else
      uri = GnomeVFS::URI.new(@entry.text)
      if uri.exists?
        @uri = uri
      else
        return
      end
    end
    make_models
  end
  def on_cancel_clicked(widget)
    hide
  end
  def on_Fileselection_delete_event(widget, arg0)
    hide
  end

  def make_models
    @dirmodel.clear
    @filemodel.clear
    items = Array.new
    if GnomeVFS::URI===@uri
      GnomeVFS::Directory.open(@uri).each{|i| items.push i}
      items = [".",".."]+items if items[0].name != "."
      items.each{|item|
        if String===item || item.directory?
          iter = @dirmodel.append(nil)
        else
          iter = @filemodel.append(nil)
        end
        item = item.name until String===item
        iter[0] = item
      }
      @entry.text = @uri.to_s
    else
      @dirmodel.append(nil)[0] = "."
#      @dirmodel.append(nil)[0] = ".." if @uri.dir("..")
      @dirmodel.append(nil)[0] = ".."
      @uri.list_dirs.each{|name| @dirmodel.append(nil)[0] = name}
      @uri.list_data.each{|name| @filemodel.append(nil)[0] = name}
      @entry.text = @uri.__drburi+@uri.path
    end
  end

  def ok_button
    @ok
  end
  def show
    @window.show
  end
  def hide
    @window.hide
  end
  def selection
    [@entry.text]
  end
end

if $0 == __FILE__

#If you use only Ruby/GTK2 widgets, call Gtk.init here. 
#Gtk.init
#If you use Ruby/GNOME2 widgets, call Gnome::Program.new here. 
Gnome::Program.new("Druby selection", "0.0")

# Set correct path yourself.
fs = DFileSelection.new("test")
fs.show
fs.ok_button.signal_connect("clicked"){|w|
  fs.hide
  p fs.selection
}

Gtk.main

end
