#!/usr/bin/env ruby
enable = true
begin
  require 'libglade2'
rescue LoadError
  begin
    require "lglade"
  rescue LoadError
    enable = false
  end
end

if enable
  begin
    require "gnomevfs"
    require "drb/drb"
    require "narray"
  rescue LoadError
    enable = false
  end
end

if enable

  DRb.start_service

  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 = DATA_PATH+"/gave/glade/fileselection.glade"
    def initialize(title="FileSelection")
      glade = GladeXML.new(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
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. 
  if enable
    Gnome::Program.new("Druby selection", "0.0")

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

    Gtk.main
  end

end
