
# See http://terai.xrea.jp/Swing/FileHistory.html

require 'pathname'
require 'jruby'

import javax.swing.JMenu
import javax.swing.JMenuBar
import javax.swing.JMenuItem
import javax.swing.JToolBar
import javax.swing.JButton
import javax.swing.ImageIcon

CONFIG_DIR = 'config'
HISTORY_FILE = 'config/hisotry'
HISTORY_MAX = 10
NO_HISTORY_LABEL = 'なし'
CLEAN_HISTORY_LABEL = 'X:履歴を削除'
CLEAN_HISTORY_MNEMNIC = 'X'

MENU_DEF = [
  {:label => 'File(F)', :mnemnic => 'F',:menu => [
      {:label => 'Open(O)...', :mnemnic => 'O', :action => :open},
      {:label => 'Save(S)...', :mnemnic => 'S', :action => :save},
      {:label => 'History(F)', :mnemnic => 'F', :action => :hisoty_menu},
      {:label => 'Quit(Q)', :mnemnic => 'Q', :action => :quit},
    ]},
  {:label => 'View(V)', :mnemnic => 'V', :menu => [
      {:label => 'Expand All', :action => :expand_all},
      {:label => 'Collapse All', :action => :collapse_all},
      {:label => 'Expand (selected items)', :action => :expand},
      {:label => 'Collapse (selected items)', :action => :collapse},
    ]},
  {:label => 'Help(H)', :mnemnic => 'H', :menu => [
      {:label => 'Help(H)...', :mnemnic => 'H', :action => :help},
      {:label => 'About(A)...', :mnemnic => 'A', :action => :about},
    ]},
]

TOOL_DEF = [
  {:icon => './images/icon_open-file.png', :tooltip => 'Open', :action => :open},
  {:icon => './images/icon_save-file.png', :tooltip => 'Save', :action => :save},
]

ACTIONS = {
  :open => :MyOpenAction,
  :save => :MySaveAction,
  :history => :MyHistoryAction,
  :quit => :MyQuitAction,
  :expand => :MyExpandAction,
  :expand_all => :MyExpandAllAction,
  :collapse => :MyCollapseAction,
  :collapse_all => :MyCollapseAllAction,
  :help => :MyHelpAction,
  :about => :MyAboutAction,
}

class BarFactory

  @@file_history = []
  @@menu_history = nil

  def initialize
    BarFactory::read_history
  end

  def create_submenu(menu_def, app_panel)
    ans = []
    menu_def.each do |m|
      if m[:action] == :hisoty_menu
        @@menu_history = JMenu.new(m[:label])
        @@menu_history.setMnemonic(m[:mnemnic][0]) if m[:mnemnic] != nil
        BarFactory::setup_file_history(app_panel)
        ans << @@menu_history
      elsif m[:menu] != nil
        menu = JMenu.new(m[:label])
        menu.setMnemonic(m[:mnemnic][0]) if m[:mnemnic] != nil
        sub = create_submenu(m[:menu], app_panel)
        sub.each do |item|
          menu.add(item)
        end
        ans << menu
      elsif
        menu_item = JMenuItem.new("#{m[:label]}")
        menu_item.setMnemonic(m[:mnemnic][0]) if m[:mnemnic] != nil
        if m[:action] != nil
          if ACTIONS[m[:action]] == nil
            pp "--- Not found action. #{m[:action]}"
          else
            menu_item.add_action_listener(eval("#{ACTIONS[m[:action]].to_s}.new(app_panel)"))
          end
        end
        ans << menu_item
      end
    end
    ans
  end

  def create_menubar(app_panel)
    menubar = JMenuBar.new

    sub = create_submenu(MENU_DEF, app_panel)
    sub.each do |item|
      menubar.add(item)
    end

    menubar
  end

  def create_toolbar(app_panel)
    toolbar = JToolBar.new
    toolbar.setRollover(true)
    toolbar.setFloatable(true)

    TOOL_DEF.each do |m|
      button = JButton.new(ImageIcon.new(m[:icon])) if m[:icon] != nil
      button.setToolTipText(m[:tooltip]) if m[:tooltip] != nil
      if m[:action] != nil
        button.add_action_listener(eval("#{ACTIONS[m[:action]].to_s}.new(app_panel)"))
      end
      toolbar.add(button)
    end
    toolbar
  end

  def self.read_history
    @@file_history = []
    if File.exist?(HISTORY_FILE)
      open(HISTORY_FILE) { |file|
        while line = file.gets
          @@file_history << line.strip
        end
      }
    end
  end

  def self.write_history
    Dir.mkdir(CONFIG_DIR) unless FileTest::exist?(CONFIG_DIR)
    open(HISTORY_FILE, 'w') { |file|
      @@file_history.each do |val|
        file.puts(val)
      end
    }
  end

  def self.setup_file_history(app_panel)
    @@menu_history.removeAll
    if @@file_history.size == 0
      mi = JMenuItem.new
      mi.setText(NO_HISTORY_LABEL)
      @@menu_history.add(mi)
    else
      @@file_history.each_with_index do |f, i|
        mi = JMenuItem.new(MyHistoryAction.new(app_panel, f))
        mi.setText("#{i}:#{f}")
        mi.setMnemonic(i.to_s[0])
        @@menu_history.add(mi)
      end
      mi = JMenuItem.new(MyClearHistoryAction.new(app_panel))
      mi.setText(CLEAN_HISTORY_LABEL)
      mi.setMnemonic(CLEAN_HISTORY_MNEMNIC[0])
      @@menu_history.add(mi)
    end
  end

  def self.update_history(file_path, app_panel)
    # p = Pathname.new(file_path)
    # file_path = p.realpath.to_s
    unless @@file_history.include?(file_path)
      # 配列の先頭に新しいファイルパスを追加
      @@file_history = [file_path] + @@file_history[0..HISTORY_MAX]
      setup_file_history(app_panel)
      BarFactory::write_history
    end
  end

  def self.clear_file_history
    @@file_history = []
  end
end

class MyOpenAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("open")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    jfc = javax.swing.JFileChooser.new
    jfc.setDialogTitle("Open")
    ret = jfc.showOpenDialog(@app_panel)
    if ret == javax.swing.JFileChooser::APPROVE_OPTION
      file_name = "#{jfc.getCurrentDirectory}/#{jfc.getSelectedFile.getName}"
      @app_panel.change_file(EdinetZip::get_instance_files(file_name)[0])
    end
  end
end

class MySaveAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("save")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    message = [APP_TITLE]
    javax.swing.JOptionPane.showMessageDialog(nil, 'TODO', "Save",
      javax.swing.JOptionPane::INFORMATION_MESSAGE)
  end
end

class MyHistoryAction < javax.swing.AbstractAction
  def initialize(app_panel, file_path)
    super("history")
    @app_panel = app_panel
    @file_path = file_path
  end
  def actionPerformed(evt)
    @app_panel.change_file(EdinetZip::get_instance_files(@file_path)[0])
    BarFactory.update_history(@file_path, @app_panel)
  end
end

class MyClearHistoryAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("clear-history")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    BarFactory::clear_file_history
    BarFactory::setup_file_history(@app_panel)
    BarFactory::write_history
  end
end

class MyQuitAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("quit")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    java.lang.System.exit(0)
  end
end

class MyExpandAllAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("expand-all")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    @app_panel.visit_all(@app_panel.item_tree_view, @app_panel.item_tree_view.getPathForRow(0), true)
  end
end

class MyCollapseAllAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("collapse-all")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    @app_panel.visit_all(@app_panel.item_tree_view, @app_panel.item_tree_view.getPathForRow(0), false)
  end
end

class MyExpandAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("expand")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    rows = @app_panel.item_tree_view.getTreeSelectionModel().getSelectionRows
    if rows != nil
      (rows.size() -1).downto(0) do |i|
        @app_panel.visit_all(@app_panel.item_tree_view, @app_panel.item_tree_view.getPathForRow(rows[i]), true)
      end
    end
  end
end

class MyCollapseAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("collapse")
    @app_panel = app_panel
  end
  def actionPerformed(evt)
    rows = @app_panel.item_tree_view.getTreeSelectionModel().getSelectionRows
    if rows != nil
      (rows.size() -1).downto(0) do |i|
        @app_panel.visit_all(@app_panel.item_tree_view, @app_panel.item_tree_view.getPathForRow(rows[i]), false)
      end
    end
  end
end

class MyHelpAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("help")
  end
  def actionPerformed(evt)
    message = [APP_TITLE]
    javax.swing.JOptionPane.showMessageDialog(nil, 'TODO', "Help",
      javax.swing.JOptionPane::INFORMATION_MESSAGE)
  end
end

class MyAboutAction < javax.swing.AbstractAction
  def initialize(app_panel)
    super("about")
  end
  def actionPerformed(evt)
    message = [APP_TITLE]
    javax.swing.JOptionPane.showMessageDialog(nil, message, "About",
      javax.swing.JOptionPane::INFORMATION_MESSAGE)
  end
end
