require 'etc'
require 'fileutils'

###############################################################################
# テンポラリディレクトリ
###############################################################################

if !File.exist?("~/.mfiler2")
    `mkdir -p ~/.mfiler2`
    `chmod 700 ~/.mfiler2`
end

ENV['MTEMP'] = ENV['HOME'] + "/.mfiler2"

###############################################################################
# 日本語の設定
###############################################################################

# KCODE
if `uname -s`.index("CYGWIN") || ENV['LANG'] == "ja_JP.SJIS" || ENV['LANG'] == "ja_JP.sjis"
    $KCODE = "SJIS"
elsif ENV['LANG'] != nil && (ENV['LANG'].index("utf") || ENV['LANG'].index("UTF")) || `uname -s`.index("Darwin")
    $KCODE = "UTF8"
else
    $KCODE = "EUC"
end

# iconv settings
set_iconv_kanji_code_name "sjis", "sjis"
set_iconv_kanji_code_name "eucjp", "eucjp"
set_iconv_kanji_code_name "utf8", "utf-8"
set_iconv_kanji_code_name "utf8-mac", "utf-8-mac"

###############################################################################
# キーマップ
###############################################################################
keymap   KEY_UP,        27,   91,   65,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_UP,        27,   79,   65,   -1,       -1,    -1, -1,-1,-1,-1
#keymap   KEY_UP,        56,   -1,   -1,   -1,       -1,    -1, -1,-1,-1,-1
keymap   KEY_DOWN,      27,   91,   66,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_DOWN,      27,   79,   66,   -1,       -1,    -1, -1,-1,-1,-1
#keymap   KEY_DOWN,      50,   -1,   -1,   -1,       -1,    -1, -1,-1,-1,-1
keymap   KEY_RIGHT,     27,   91,   67,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_RIGHT,     27,   79,   67,   -1,       -1,    -1, -1,-1,-1,-1
#keymap   KEY_RIGHT,     54,   -1,   -1,   -1,       -1,    -1, -1,-1,-1,-1
keymap   KEY_LEFT,      27,   91,   68,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_LEFT,      27,   79,   68,   -1,       -1,    -1, -1,-1,-1,-1
#keymap   KEY_LEFT,      52,   -1,   -1,   -1,       -1,    -1, -1,-1,-1,-1
keymap   KEY_INSERT,    27,   91,   50,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_DELETE,    27,   91,   51,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_BACKSPACE, 127,  -1,   -1,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_HOME,      27,   79,   72,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_HOME,      27,   91,   72,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_HOME,      27,   91,   55,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_HOME,      27,   91,   0,    -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_HOME,      27,   91,   49,   126,      -1,    -1, -1,-1,-1,-1
keymap   KEY_END,       27,   79,   70,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_END,       27,   91,   70,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_END,       27,   91,   56,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_END,       27,   91,   101,  -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_END,       27,   91,   52,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_PAGEUP,    27,   91,   53,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_PAGEUP,    27,   91,   73,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_PAGEDOWN,  27,   91,   54,   126,     -1,     -1, -1,-1,-1,-1
keymap   KEY_PAGEDOWN,  27,   91,   71,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F1,        27,   91,   49,   49,      126,    -1, -1,-1,-1,-1
keymap   KEY_F1,        27,   79,   80,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F1,        27,   91,   91,   65,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F2,        27,   91,   49,   50,      126,    -1, -1,-1,-1,-1
keymap   KEY_F2,        27,   79,   81,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F2,        27,   91,   91,   66,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F3,        27,   91,   49,   51,      126,    -1, -1,-1,-1,-1
keymap   KEY_F3,        27,   79,   82,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F3,        27,   91,   91,   67,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F4,        27,   91,   49,   52,      126,    -1, -1,-1,-1,-1
keymap   KEY_F4,        27,   79,   83,   -1,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F4,        27,   91,   91,   68,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F5,        27,   91,   49,   53,      126,    -1, -1,-1,-1,-1
keymap   KEY_F5,        27,   91,   91,   69,      -1,     -1, -1,-1,-1,-1
keymap   KEY_F6,        27,   91,   49,   55,      126,    -1, -1,-1,-1,-1
keymap   KEY_F7,        27,   91,   49,   56,      126,    -1, -1,-1,-1,-1
keymap   KEY_F8,        27,   91,   49,   57,      126,    -1, -1,-1,-1,-1
keymap   KEY_F9,        27,   91,   50,   48,      126,    -1, -1,-1,-1,-1
keymap   KEY_F10,       27,   91,   50,   49,      126,    -1, -1,-1,-1,-1
keymap   KEY_F11,       27,   91,   50,   51,      126,    -1, -1,-1,-1,-1
keymap   KEY_F12,       27,   91,   50,   52,      126,    -1, -1,-1,-1,-1

keymap   KEY_META_LEFT, 27,   91,   51,    68,      -1,    -1, -1,-1,-1,-1 # gnome-terminal
keymap   KEY_META_LEFT, 27,   91,   49,    59,      51,    68, -1,-1,-1,-1 # xterm
keymap   KEY_META_LEFT, 27,   91,   49,    59,      57,    68, -1,-1,-1,-1 # mlterm
keymap   KEY_META_LEFT, 27,   79,   49,    59,      51,    68, -1,-1,-1,-1 # screen
#keymap   KEY_META_LEFT, 27,   79,   68,    -1,      -1,    -1, -1,-1,-1,-1 # iTerm

keymap   KEY_META_RIGHT,27,   91,   51,    67,      -1,    -1, -1,-1,-1,-1 # gnome-terminal
keymap   KEY_META_RIGHT,27,   91,   49,    59,      51,    67, -1,-1,-1,-1 # xterm
keymap   KEY_META_RIGHT,27,   91,   49,    59,      57,    67, -1,-1,-1,-1 # mlterm
keymap   KEY_META_RIGHT,27,   79,   49,    59,      51,    67, -1,-1,-1,-1 # screen
#keymap   KEY_META_RIGHT,27,   79,   67,    -1,      -1,    -1, -1,-1,-1,-1 # iTerm

keymap   KEY_META_UP,   27,   91,   51,    65,      -1,    -1, -1,-1,-1,-1 # gnome-terminal
keymap   KEY_META_UP,   27,   91,   49,    59,      51,    65, -1,-1,-1,-1 # xterm
keymap   KEY_META_UP,   27,   91,   49,    59,      57,    65, -1,-1,-1,-1 # mlterm
keymap   KEY_META_UP,   27,   79,   49,    59,      51,    65, -1,-1,-1,-1 # screen
#keymap   KEY_META_UP,   27,   79,   65,    -1,      -1,    -1, -1,-1,-1,-1 # iTerm

keymap   KEY_META_DOWN, 27,   91,   51,    66,      -1,    -1, -1,-1,-1,-1 # gnome-terminal
keymap   KEY_META_DOWN, 27,   91,   49,    59,      51,    66, -1,-1,-1,-1 # xterm
keymap   KEY_META_DOWN, 27,   91,   49,    59,      57,    66, -1,-1,-1,-1 # mlterm
keymap   KEY_META_DOWN, 27,   79,   49,    59,      51,    66, -1,-1,-1,-1 # screen
#keymap   KEY_META_DOWN, 27,   79,   66,    -1,      -1,    -1, -1,-1,-1,-1 # iTerm

###############################################################################
# フック
###############################################################################
def atexit_hook_default()
    save_filer_stat()
    0
end

def mloop_hook_default()
    0
end

def fdclone_type_cursor_move_hook()
    vo = view_filer()
    maxy = cursor_maxy()
    
    if vo == "all" || vo == "all2" || vo == "one_dir" then
         if cursor(adir()) >= scrolltop(adir()) + maxy then
             set_scrolltop(adir(), (cursor(adir())/maxy)*maxy )
         end
         if cursor(adir()) < scrolltop(adir()) then
             set_scrolltop(adir(), (cursor(adir())/maxy)*maxy )
         end
    elsif vo == "one_dir2" then
        if cursor(adir()) >= scrolltop(adir()) + maxy*2 then
             set_scrolltop(adir(), (cursor(adir())/(maxy*2))*(maxy*2) )
        end
        if cursor(adir()) < scrolltop(adir()) then
            set_scrolltop(adir(), (cursor(adir())/(maxy*2))*(maxy*2) )
        end
    elsif vo == "one_dir3" then
        if cursor(adir()) >= scrolltop(adir()) + maxy*3 then
             set_scrolltop(adir(), (cursor(adir())/(maxy*3))*(maxy*3) )
        end
        if cursor(adir()) < scrolltop(adir()) then
            set_scrolltop(adir(), (cursor(adir())/(maxy*3))*(maxy*3) )
        end
    elsif vo == "one_dir5" then
        if cursor(adir()) >= scrolltop(adir()) + maxy*5 then
             set_scrolltop(adir(), (cursor(adir())/(maxy*5))*(maxy*5) )
        end
        if cursor(adir()) < scrolltop(adir()) then
            set_scrolltop(adir(), (cursor(adir())/(maxy*5))*(maxy*5) )
        end
    end
end

def afu_type_cursor_move_hook()
    vo = view_filer()
    maxy = cursor_maxy()
    
    if vo == "all" || vo == "all2" || vo == "one_dir" then
         if cursor(adir()) >= scrolltop(adir()) + maxy-2 then
             set_scrolltop(adir(), cursor(adir()) -maxy+2)
         end
         if cursor(adir()) < scrolltop(adir()) then
             set_scrolltop(adir(), cursor(adir()))
         end
    elsif vo == "one_dir2" then
        if cursor(adir()) >= scrolltop(adir()) + maxy*2 then
             set_scrolltop(adir(), (cursor(adir())/(maxy*2))*(maxy*2) )
        end
        if cursor(adir()) < scrolltop(adir()) then
            set_scrolltop(adir(), (cursor(adir())/(maxy*2))*(maxy*2) )
        end
    elsif vo == "one_dir3" then
        if cursor(adir()) >= scrolltop(adir()) + maxy*3 then
             set_scrolltop(adir(), (cursor(adir())/(maxy*3))*(maxy*3) )
        end
        if cursor(adir()) < scrolltop(adir()) then
            set_scrolltop(adir(), (cursor(adir())/(maxy*3))*(maxy*3) )
        end
    elsif vo == "one_dir5" then
        if cursor(adir()) >= scrolltop(adir()) + maxy*5 then
             set_scrolltop(adir(), (cursor(adir())/(maxy*5))*(maxy*5) )
        end
        if cursor(adir()) < scrolltop(adir()) then
            set_scrolltop(adir(), (cursor(adir())/(maxy*5))*(maxy*5) )
        end
    end
end

$option_scroll_type = "fdclone"

def cursor_move_hook(i)
    if $option_scroll_type == "afu"
        afu_type_cursor_move_hook()
    elsif $option_scroll_type == "original"
        fdclone_type_cursor_move_hook()
    elsif $option_scroll_type == "fdclone"
        fdclone_type_cursor_move_hook()
    else
        fdclone_type_cursor_move_hook()
    end
end

###############################################################################
# rubyによって定義される mfiler2 API 
###############################################################################
def cmdline(cmd, cursor_pos)
    cmdline_c(cmd, cursor_pos, "enter_cursor_down()")
end

def is_adir_right()
    return !is_adir_left()
end

def is_adir_left()
    if adir() == 0
        return true
    else
        return false
    end
end

def is_adir_right()
    if adir() == 1
        return true
    else
        return false
    end
end

def toggle_xterm_next()
    xterm_next_toggle()
end

def toggle_xterm()
    xterm_toggle()
end

def excute_cursor_file()
    cmdline_c(' ./%f', 1, nil)
end

def menu_attr()
    menu('attribute')
end

def menu_grep()
    menu('grep_menu')
end

def menu_mark()
    menu('mark')
end

def menu_extra()
    menu('extra-menu')
end

def menu_sudo()
    menu('sudo-menu')
end

def menu_copy()
    menu('copy_menu')
end

def menu_move()
    menu('move_menu')
end

def menu_delete()
    menu('delete_menu')
end

def menu_sort()
    menu('sort')
end

def menu_all()
    menu('all')
end

def menu_my_commands()
    menu('my_commands')
end

def move_back()
    dir_back()
end

def mfiler2_help()
    help()
end

def tab_menu_select()
    tab_select()
end

def tab_open(num)
    open_tab(num)
end

def job_select()
    select_job()
end

def job_forground(num)
    forground_job(num)
end

def start_isearch()
    isearch()
end

def start_sisearch()
    sisearch(true)
end

def start_isearch_partmatch()
    isearch_partmatch()
end

def isearch_partmatch_toggle()
    isearch_partmatch2(!is_isearch_partmatch2)
end

def jump_by_cmdline1()
    cmdline_c("%r%Q dir_move adir(), %D", -1, nil)
end

def jump_by_cmdline2()
    cmdline_c("%r%Q dir_move adir(), ''", -1, nil)
end

defmenu("Jump",
    "(h)istory", KEY_h, "menu_dir_history()",
    "cmdline (j)ump(default current directory)", KEY_j, "jump_by_cmdline1()",
    "cmdline (J)ump(root directory)", KEY_J, "jump_by_cmdline2()"
)

def menu_jump()
    menu('Jump')
end

defmenu("sHell",
    "send cmdline to extern (s)hell($SHELL)", KEY_s, "cmdline_c('%S ', 0, nil)",
    "send cmdline to (r)uby", KEY_r, "cmdline_c('%r ', 0, nil)",
    "send cmdline to other (x)terminal with extern shell($SHELL)", KEY_x, "cmdline_c('%t ', 0, nil)", 
    "send cmdline to (m)filer2 shell", KEY_m, "cmdline_c('%s ', 0, nil)",
    "cmdline completion $PATH re(h)ash",           KEY_h, "rehash()"
)

def menu_shell()
    menu('sHell')
end

def run_file_manager()
    if `uname -s`.index("CYGWIN")
        shell('%Q cygstart . &', 'explore')
        #shell('%Q cygstart `cygpath -w -a .` &', 'explore')
    elsif `uname -s`.index("Darwin")
        shell('%Q open . &', 'Finder')
    else
        gnome = false
        kde = false
        xfce = false
        `ps ax`.each {|line|
            prog_name = line.split[4]
            if prog_name == "nautilus"
                gnome = true
            elsif prog_name == "kdeinit:"
                kde = true
            elsif prog_name == "xfdesktop"
                xfce = true
            end
        }
        if gnome
            shell('%Q nautilus file://"$PWD" 2>/dev/null &', 'nautilus')
        elsif kde
            shell('%Q konqueror "$PWD" 2>/dev/null &', 'konqueror')
        elsif xfce
            shell('%Q thunar "$PWD" 2>/dev/null &', 'thunar')
        end
    end
end

def _select_menu(title, select_str, flg_mfiler_view)
    if !mis_curses
        puts "curses is not running..."
        return
    end

    $scroll_top = 0
    $cursor = 0
    $select_str = select_str
    $title = title

    def view_hook()
        height = 0
        if $select_str.size > mgetmaxy - 2
            height = mgetmaxy - 2
        else
            height = $select_str.size+2
        end

        mbox(0,2, mgetmaxx-5, height)
        mmvprintw(0, 4, $title)
        n = $scroll_top
        while n < $select_str.size
            if $cursor == n
                mattron(MA_REVERSE)
            end

            if n - $scroll_top+2 < mgetmaxy - 2
                mmvprintw(n - $scroll_top + 1, 3, "%s", $select_str[n])
            end

            if $cursor == n
                mattroff()
            end
            
            n = n + 1
        end
    end

    while true
        ### view ###
        mclear
        if flg_mfiler_view 
            mfiler_view()
        end
        view_hook()
        mrefresh()

        ### input ###
        key = mgetch()

        if key[1] == 14 || key[1] == KEY_DOWN
            $cursor = $cursor + 1
        end
        if key[1] == 16 || key[1] == KEY_UP
            $cursor = $cursor -1
        end
        if key[1] == 4 || key[1] == KEY_PAGEDOWN
            $cursor = $cursor + mgetmaxy / 2
        end
        if key[1] == 21 || key[1] == KEY_PAGEUP
            $cursor = $cursor - mgetmaxy / 2
        end
        if key[1] == 12
            mclear
            mrefresh
        end

        if key[1] == ?q || key[1] == 3 || key[1] == 27 || key[1] == 7
            $cursor = -1
            break
        end
        
        if key[1] == 10 || key[1] == 13
            break
        end

        ### modification ###
        if $cursor < 0
            $cursor = 0
        end
        if $cursor >= $select_str.size
            $cursor = $select_str.size - 1
        end
        if $cursor < $scroll_top
             $scroll_top = $cursor
        end
        if $cursor > $scroll_top + mgetmaxy() - 5
            $scroll_top = $scroll_top + ($cursor-$scroll_top-mgetmaxy()) + 5
        end
    end

    def view_hook()
    end

    return $cursor
end

def select_menu(title, select_str)
    _select_menu(title, select_str, false)
end

def select_menu_mfiler(title, select_str)
    _select_menu(title, select_str, true)
end

def msystem(cmd)
    curses_on_off = mis_curses()

    if curses_on_off
        mendwin()
    end

    set_signal_clear()

    result = `#{cmd}`

    set_signal_mfiler2()

    if curses_on_off
        minitscr()
    end

    return result
end

def is_one_dir()
    vo = view_filer();

    return vo == "one_dir" || vo == "one_dir2" || vo == "one_dir3" || vo == "one_dir5";
end

def get_permission(mode)
    return mode & 0777
end

def enter_cursor_down()
    if $option_enter_cursor_down
        cursor_move(adir(), cursor(adir()) + 1)
    end
end

if `uname -s`.index("CYGWIN")
    def key_enter_mark_win_program(prg_name)
        cmdline = 'cmdline_c("%Q ' + prg_name;
        adir_mark.each {|fname|
            str = adir_path() + fname
            
            if str.index("'")
               cmd = 'cygpath -l -w "' + str + '"'
            else
               cmd = "cygpath -l -w '" + str + "'"
            end
            out = `#{cmd}`
            out.chomp!()
            
            i = 0
            while i < out.length()
               if (i == 0 || !( (kanjicode()=="eucjp"||kanjicode()=="sjis") && is_kanji(out[i-1]))) && out[i] == '\\'[0]
                   out.insert(i, "\\\\\\")
                   i+=3
               end
               
               i+=1
            end
            
            if out.index("'")
                cmdline = cmdline + ' \\"' + out + '\\"';
            else
                cmdline = cmdline + ' \'' + out + '\'';
            end
        }
        cmdline = cmdline + ' &", 0, nil)';
        
        eval(cmdline);
    end

    def key_enter_mark_win_program2(prg_name)
        cmdline = 'shell("%Q ' + prg_name;
        adir_mark.each {|fname|
            str = adir_path() + fname
            
            if str.index("'")
               cmd = 'cygpath -l -w "' + str + '"'
            else
               cmd = "cygpath -l -w '" + str + "'"
            end
            out = `#{cmd}`
            out.chomp!()
            
            i = 0
            while i < out.length()
               if (i == 0 || !( (kanjicode()=="eucjp"||kanjicode()=="sjis") && is_kanji(out[i-1]))) && out[i] == '\\'[0]
                   out.insert(i, "\\")
                   i+=1
               end
               
               i+=1
            end
            
            if out.index("'")
                cmdline = cmdline + ' \\"' + out + '\\"';
            else
                cmdline = cmdline + ' \'' + out + '\'';
            end
        }
        cmdline = cmdline + ' &", "' + prg_name +  '")';
        
        eval(cmdline);
    end
    
    def key_enter_win_program(prg_name)
        key_enter_mark_win_program(prg_name)
        enter_cursor_down
    end

    def key_enter_win_program2(prg_name)
        key_enter_mark_win_program2(prg_name)
        enter_cursor_down
    end
end

def original_type_pagedown()
    cursor_move(adir(), cursor(adir())+$pageup_length)
end

def original_type_pageup()
    cursor_move(adir(), cursor(adir())-$pageup_length)
end

def fdclone_type_pagedown()
    if is_one_dir() then
        cursor_move(adir(), cursor(adir())+$pageup_length)
    else
        if cursor_max(adir()) <= cursor_maxy() then
            cursor_move(adir(), cursor(adir())+$pageup_length)
        else
            n = (cursor_max(adir())/cursor_maxy())*cursor_maxy()
            if cursor(adir()) < n then
                cursor_move(adir(), cursor(adir())+cursor_maxy())
            end
        end
    end
end

def fdclone_type_pageup()
    if is_one_dir() then
        cursor_move(adir(), cursor(adir())-$pageup_length)
    else
        if cursor_max(adir()) <= cursor_maxy() then
            cursor_move(adir(), cursor(adir())-$pageup_length)
        else 
            if cursor(adir()) >= cursor_maxy() then
                cursor_move(adir(), cursor(adir())-cursor_maxy())
            end
        end
    end
end

def afu_type_pagedown()
    if is_one_dir() then
        cursor_move(adir(), cursor(adir())+$pageup_length)
    else
        if cursor_max(adir()) <= cursor_maxy() then
            cursor_move(adir(), cursor(adir())+$pageup_length)
        else
            cursor_move(adir(), cursor(adir())+cursor_maxy()-2)
        end
    end
end

def afu_type_pageup()
    if is_one_dir() then
        cursor_move(adir(), cursor(adir())-$pageup_length)
    else
        if cursor_max(adir()) <= cursor_maxy() then
            cursor_move(adir(), cursor(adir())-$pageup_length)
        else    
            cursor_move(adir(), cursor(adir())-cursor_maxy()+2)
        end
    end
end

def pagedown()
    if $option_scroll_type == "afu"
        afu_type_pagedown()
    elsif $option_scroll_type == "original"
        original_type_pagedown()
    elsif $option_scroll_type == "fdclone"
        fdclone_type_pagedown()
    else
        fdclone_type_pagedown()
    end
end

def pageup()
    if $option_scroll_type == "afu"
        afu_type_pageup()
    elsif $option_scroll_type == "original"
        original_type_pageup()
    elsif $option_scroll_type == "fdclone"
        fdclone_type_pageup()
    else
        fdclone_type_pageup()
    end
end

def cursor_up()
    cursor_move(adir(), cursor(adir())-1)
end

def cursor_down()
    cursor_move(adir(), cursor(adir())+1)
end

def move_left_directory()
    if is_one_dir() then
        if cursor_x() > 0 then
            cursor_move(adir(), cursor(adir())-cursor_maxy())
        else
            if $option_left_right_dir_up
                dir_move(adir(), '..')
            end
        end
    else
        if is_adir_left() then
            if $option_left_right_dir_up
                dir_move(adir(), '..')
            end
        else
            cursor_left()
        end
    end
end

def move_right_directory()
    if is_one_dir() then
        if cursor_x() < (cursor_maxx()-1)
            cursor_move(adir(), cursor(adir())+cursor_maxy())
        end
    else
        if is_adir_right() then
            if $option_left_right_dir_up
                dir_move(adir(), '..')
            end
        else
            cursor_right()
        end
    end
end

def cursor_top()
    cursor_move(adir(), 0)
end

def cursor_bottom()
    cursor_move(adir(), cursor_max(adir())-1)
end

def move_parent_dir()
    dir_move(adir(), '..')
end

def move_root_dir()
    dir_move(adir(), '/')
end

def move_home_dir()
    dir_move(adir(), '~')
end

def sdir_move_home_dir()
    if is_one_dir()
        set_view_filer("all")
        dir_move(sdir(), '~')
    else
        dir_move(sdir(), '~')
    end

    cursor_other()
    set_scrolltop(adir(), 0)
    cursor_move(adir(), 1)
end

def toggle_visible_dot_file()
    if mask(adir()) == "*"
        $visible_dot_dir = true
        glob_mask("{*,.*}", "*", "*", "*")
        reread(0)
        reread(1)
    else
        $visible_dot_dir = false
        glob_mask("*", "*", "*", "*")
        reread(0)
        reread(1)
    end
end

def edit_cursor_file()
    shell('%q%o $EDITOR %f', cursor_name_convert)
end

def edit_new_file()
    cmdline_c('%q $EDITOR ""', -1, nil)
end

def view_cursor_file()
    shell('%q%o $PAGER %f', cursor_name_convert)
end

def open_dir_in_other()
    if is_one_dir()
        if is_adir_left()
            dir_move(sdir(), adir_path() + cursor_name())
            set_view_filer("all")
            cursor_other()
        else
            dir_move(sdir(), adir_path())
            cursor_move(sdir(), cursor(adir()))
            set_scrolltop(sdir(), scrolltop(adir()))

            dir_move(adir(), adir_path() + cursor_name())
            set_view_filer("all")
        end
    else
        dir_move(sdir(), adir_path() + cursor_name())
    end
end

def copy_path()
    finish_virtual_directory()

    if is_one_dir()
        if File.directory?(adir_path + cursor_name)
            open_dir_in_other()
        end
    else
        if !is_one_dir()
            dir_move(adir(), sdir_path())
            cursor_move(adir(), cursor(sdir()))
            set_scrolltop(adir(), scrolltop(sdir()))
            set_sort_kind(adir(), sort_kind(sdir()))
            sort(adir())
            set_view_nameonly(adir(), view_nameonly(sdir()))
            set_view_focusback(adir(), view_focusback(sdir()))
            set_view_removedir(adir(), view_removedir(sdir()))
        end
    end
end

def copy_path2()
    finish_virtual_directory()

    if !is_one_dir()
        dir_move(sdir(), adir_path())
        cursor_move(sdir(), cursor(adir()))
        set_scrolltop(sdir(), scrolltop(adir()))
        set_sort_kind(adir(), sort_kind(sdir()))
        sort(adir())
        set_view_nameonly(adir(), view_nameonly(sdir()))
        set_view_focusback(adir(), view_focusback(sdir()))
        set_view_removedir(adir(), view_removedir(sdir()))
    end
end

def exchange_path()
    finish_virtual_directory()

    if !is_one_dir()
        d = adir_path()
        c = cursor(adir())
        s = scrolltop(adir())
        sk = sort_kind(adir())
        vno = view_nameonly(adir())
        vfb = view_focusback(adir())
        vrd = view_removedir(adir())
        
        dir_move(adir(), sdir_path())
        cursor_move(adir(), cursor(sdir()))
        set_scrolltop(adir(), scrolltop(sdir()))
        set_sort_kind(adir(), sort_kind(sdir()))
        sort(adir())
        set_view_nameonly(adir(), view_nameonly(sdir()))
        set_view_focusback(adir(), view_focusback(sdir()))
        set_view_removedir(adir(), view_removedir(sdir()))
        
        dir_move(sdir(), d)
        cursor_move(sdir(), c)
        set_scrolltop(sdir(), s)
        set_sort_kind(sdir(), sk)
        sort(sdir())
        set_view_nameonly(sdir(), vno)
        set_view_focusback(sdir(), vfb)
        set_view_removedir(sdir(), vrd)

        cursor_other()
    end
end



$list_mode = false

def toggle_list_mode()
    if !$list_mode 
        $list_mode = !$list_mode

        $list_mode_filer = view_filer()
        $list_mode_mtime = view_mtime()
        $list_mode_size = view_size()
        $list_mode_permission = view_permission()
        $list_mode_user = view_user()
        $list_mode_group = view_group()
        $list_mode_nlink = view_nlink()

        set_view_filer("one_dir")
        set_view_mtime(true)
        set_view_size(true)
        set_view_permission(true)
        set_view_user(true)
        set_view_group(true)
        set_view_nlink(true)
    else
        $list_mode = !$list_mode

        set_view_filer($list_mode_filer)
        set_view_mtime($list_mode_mtime)
        set_view_size($list_mode_size)
        set_view_permission($list_mode_permission)
        set_view_user($list_mode_user)
        set_view_group($list_mode_group)
        set_view_nlink($list_mode_nlink)
    end
end

$nameonly_mode = false

def toggle_nameonly_mode()
    if !$nameonly_mode 
        $nameonly_mode = !$nameonly_mode

        $nameonly_mode_filer = view_filer()
        $nameonly_mode_mtime = view_mtime()
        $nameonly_mode_size = view_size()
        $nameonly_mode_permission = view_permission()
        $nameonly_mode_user = view_user()
        $nameonly_mode_group = view_group()
        $nameonly_mode_nlink = view_nlink()
        $nameonly_mode_fname_divide_ext = view_fname_divide_ext()

        set_view_filer("one_dir")
        set_view_mtime(false)
        set_view_size(false)
        set_view_permission(false)
        set_view_user(false)
        set_view_group(false)
        set_view_nlink(false)
        set_view_fname_divide_ext(false)
    else
        $nameonly_mode = !$nameonly_mode

        set_view_filer($nameonly_mode_filer)
        set_view_mtime($nameonly_mode_mtime)
        set_view_size($nameonly_mode_size)
        set_view_permission($nameonly_mode_permission)
        set_view_user($nameonly_mode_user)
        set_view_group($nameonly_mode_group)
        set_view_nlink($nameonly_mode_nlink)
        set_view_fname_divide_ext($nameonly_mode_fname_divide_ext)
    end
end

defmenu("view",
   "2dir1 (a)ll", KEY_a, "set_view_filer('all')",
   "1dir(1)", KEY_1, "set_view_filer('one_dir')",
   "1dir(2)", KEY_2, "set_view_filer('one_dir2')",
   "1dir(3)", KEY_3, "set_view_filer('one_dir3')",
   "1dir(5)", KEY_5, "set_view_filer('one_dir5')",
   "toggle (s)ize", KEY_s, "set_view_size(!view_size())",
   "toggle m(t)ime", KEY_t, "set_view_mtime(!view_mtime())",
   "toggle (u)ser", KEY_u, "set_view_user(!view_user())",
   "toggle (g)roup", KEY_g, "set_view_group(!view_group())",
   "toggle nl(i)nk", KEY_i, "set_view_nlink(!view_nlink())",
   "toggle (p)ermission", KEY_p, "set_view_permission(!view_permission())",
   "toggle fname (d)ivide extension", KEY_d, "set_view_fname_divide_ext(!view_fname_divide_ext())",
   "toggle (f)ocusback", KEY_f, "set_view_focusback(adir(), !view_focusback(adir()))",
   "toggle (r)emovedir", KEY_r, "set_view_removedir(adir(), !view_removedir(adir()))",
   "toggle (l)ist mode", KEY_l, "toggle_list_mode",
   "toggle (n)ameonly mode", KEY_n, "toggle_nameonly_mode",
   "toggle (c)olor", KEY_c, "set_view_color(!view_color())",
   "toggle (P)age view way", KEY_P, "$option_page_view_way = !$option_page_view_way",
   "fil(e) size view way Normal", KEY_e, "$option_file_size_view_way = FS_NORMAL",
   "fil(E) size view way Human", KEY_E, "$option_file_size_view_way = FS_HUMAN",
   "file (S)ize view way Plane", KEY_S, "$option_file_size_view_way = FS_PLANE"
)

def menu_view()
    menu("view")
end

defmenu("filename_kanjicode",
   "filename kanjicode = '(u)tf'", KEY_u, "set_kanjicode_filename('utf8'); reread(0); reread(1)",
   "filename kanjicode = 'utf-(m)ac'", KEY_m, "set_kanjicode_filename('utf8-mac'); reread(0); rearead(1)",
   "filename kanjicode = '(e)ucj'", KEY_e, "set_kanjicode_filename('eucjp'); reread(0); reread(1)",
   "filename kanjicode = '(s)jis'", KEY_s, "set_kanjicode_filename('sjis'); reread(0); reread(1)",
   "filename kanjicode = 'unknown' (a)uto", KEY_a, "set_kanjicode_filename('unknown'); reread(0); reread(1)"
)

defmenu("sort",
   "(n)ame", KEY_n, "set_sort_kind(adir(), 'name'); sort(adir())",
   "(N)ame reverse", KEY_N, "set_sort_kind(adir(), 'name_rev'); sort(adir())",
   "(e)xtension", KEY_e, "set_sort_kind(adir(), 'extension'); sort(adir())",
   "(E)xtension reverse", KEY_E, "set_sort_kind(adir(), 'extension_rev'); sort(adir())",
   "(s)ize", KEY_s, "set_sort_kind(adir(), 'size'); sort(adir())",
   "(S)ize reverse", KEY_S, "set_sort_kind(adir(), 'size_rev'); sort(adir())",
   "(t)ime", KEY_t, "set_sort_kind(adir(), 'time'); sort(adir())",
   "(T)ime reverse", KEY_T, "set_sort_kind(adir(), 'time_rev'); sort(adir())",
   "(u)ser", KEY_u, "set_sort_kind(adir(), 'user'); sort(adir())",
   "(U)ser reverse", KEY_U, "set_sort_kind(adir(), 'user_rev'); sort(adir())",
   "(g)roup", KEY_g, "set_sort_kind(adir(), 'group'); sort(adir())",
   "(G)roup reverse", KEY_G, "set_sort_kind(adir(), 'group_rev'); sort(adir())",
   "(p)ermission", KEY_p, "set_sort_kind(adir(), 'permission'); sort(adir())",
   "(P)ermission reverse", KEY_P, "set_sort_kind(adir(), 'permission_rev'); sort(adir())",
   "(r)andom", KEY_r, "set_sort_kind(adir(), 'random'); sort(adir())",
   "none (0)", KEY_0, "set_sort_kind(adir(), 'none'); sort(adir())",
   "toggle (d)ir up", KEY_d, "$option_sort_dir_up = !$option_sort_dir_up; sort(adir()); sort(sdir())",
   "toggle (m)ark file up", KEY_m, "$option_sort_mark_file_up = !$option_sort_mark_file_up; sort(adir()); sort(sdir())"
   );

if `uname -s`.index("CYGWIN")
    defmenu("attribute",
       "ch(m)od (permission)", KEY_m, "cmdline_c('chmod  %m', 7, nil)",
       "ch(o)wn (owner)", KEY_o, "cmdline_c('chown  %m', 7, nil)",
       "ch(g)rp (group)", KEY_g, "cmdline_c('chgrp  %m', 7, nil)",
       "ch(M)od -R (permission recursive)", KEY_M, "cmdline_c('chmod -R  %m', 10, nil)",
       "ch(O)wn -R (owner recursive)", KEY_O, "cmdline_c('chown -R  %m', 10, nil)",
       "ch(G)rp -R (group recursive)", KEY_G, "cmdline_c('chgrp -R  %m', 10, nil)",
       "m(a)ttr (permission and date)", KEY_a, "shell('mattr %m', 'mattr')",
       "m(A)ttr (windows attribute)", KEY_A, "shell('mattrcyg %m', 'mattrcyg')");
else
    defmenu("attribute",
       "ch(m)od (permission)", KEY_m, "cmdline_c('chmod  %m', 7, nil)",
       "ch(o)wn (owner)", KEY_o, "cmdline_c('chown  %m', 7, nil)",
       "ch(g)rp (group)", KEY_g, "cmdline_c('chgrp  %m', 7, nil)",
       "ch(M)od -R (permission recursive)", KEY_M, "cmdline_c('chmod -R  %m', 10, nil)",
       "ch(O)wn -R (owner recursive)", KEY_O, "cmdline_c('chown -R  %m', 10, nil)",
       "ch(G)rp -R (group recursive)", KEY_G, "cmdline_c('chgrp -R  %m', 10, nil)",
       "m(a)ttr (permission and date)", KEY_a, "shell('mattr %m', 'mattr')");
end

def select_job()
    cmdline_c("%r%Q forground_job ", 0, nil);
end

def forground_job_title(title)
    n = 1
    while n < job_num()+1
        if job_title(n).index(title)
            forground_job(n)
            break
        end

        n += 1
    end
end

def add_current_path_to_directory_menu()
    cmdline_c("%r%Q add_directory_menu \"#{adir_path}\", KEY_1", 26, nil)
end

defmenu("extra-menu",
   "(f) find",   KEY_f, "menu_find()",
   "(c) copy",   KEY_c, "copy2()",
   "(x) cut",    KEY_x, "cut()",
   "(v) past",   KEY_v, "past()",
   "(s) uper isearch get cache",   KEY_s, "sisearch_get_cache()",
   "filename (k)anjicode", KEY_k, "menu('filename_kanjicode')",
   "(b)ack to previous direcotry",                KEY_b, "dir_back()",
   "(1) add cursor file to making playlist",        KEY_1, "add_cursor_file_to_making_playlist()",
   "(2) set cursor file as making playlist file",   KEY_2, "change_making_playlist()"
   );

def goto_cmdline()
    cmdline_c('', 0, nil)
end

def goto_cmdline_extern_shell()
    cmdline_c('%S ', 0, nil)
end

def excute_mark_file()
    cmdline_c('%S for i in %m; do  ./$i; done', 20, nil)
end

def excute_cursor_or_mark_file()
    if marking(adir())
        excute_mark_file()
    else
        excute_cursor_file()
    end
end

def load_cursor_file()
    cmdline_c('%r%Q load "' + cursor_name_convert + '"', 0, nil)
end

def call_shell(execute_ls)
    if execute_ls
        shell('%q echo "-+- "%D" -+-"; ls -aFG; $SHELL', "#{ENV['SHELL']}")
    else
        shell('%q $SHELL', "#{ENV['SHELL']}")
    end
end

$default_one_dir = "one_dir2"

def quit_or_close_directory()
    if is_one_dir()
        mf_exit()
    else
        if is_adir_left
            set_view_filer($default_one_dir)
        else
            cursor_other()
            set_view_filer($default_one_dir)
        end
    end
end

def quit()
    mf_exit()
end

def toggle_1directory_mode_and_2directory_mode()
    if is_one_dir()
        $default_one_dir = view_filer
        
        if is_adir_left
            dir_move(sdir(), adir_path())
            set_view_filer("all")
            cursor_other()
            set_scrolltop(adir(), 0)
            cursor_move(adir(), 1)
        else
            cursor_other()
            dir_move(adir(), sdir_path())
            set_view_filer("all")
            cursor_other()
            set_scrolltop(adir(), 0)
            cursor_move(adir(), 1)
        end
    else
        if is_adir_left
            set_view_filer($default_one_dir)
        else
            cursor_other()
            set_view_filer($default_one_dir)
        end
    end
end

def goto_2directory_mode()
    if is_one_dir()
        if $option_tab_remain_dir
            $default_one_dir = view_filer

            set_view_filer("all")
            cursor_other()
        else
            $default_one_dir = view_filer
            
            if is_adir_left
                dir_move(sdir(), adir_path())
                set_view_filer("all")
                cursor_other()
                set_scrolltop(adir(), 0)
                cursor_move(adir(), 1)
            else
                cursor_other()
                dir_move(adir(), sdir_path())
                set_view_filer("all")
                cursor_other()
                set_scrolltop(adir(), 0)
                cursor_move(adir(), 1)
            end
        end
    else
        cursor_other()
    end
end

def stack_current_directory()
    tab_new(tab_max(), adir_path(), scrolltop(adir()), cursor(adir()))
    dir_move(adir(), '~')
end

def close_current_directory()
    if tab_max() == 0
        dir_move(adir(), '~')
    else
        tab_up(tab_max()-1)
        tab_close(tab_max()-1)
    end
end

def open_tab(num)
    tab_new(tab_max(), adir_path(), scrolltop(adir()), cursor(adir()))
    tab_up(num)
    tab_close(num)
end

def unpack_cursor_file()
    if cursor_name().index(".gz")
        unpack_gz()
    elsif cursor_name().index(".bz2")
        unpack_bz2()
    elsif cursor_name().index(".tar")
        unpack_tar()
    elsif cursor_name().index(".tgz")
        unpack_tgz()
    elsif cursor_name().index(".lzh")
        unpack_lzh()
    elsif cursor_name().index(".zip")
        unpack_zip()
    end
end

def unpack_cursor_file2()
    if cursor_name().index(".gz")
        unpack_gz2()
    elsif cursor_name().index(".bz2")
        unpack_bz22()
    elsif cursor_name().index(".tar")
        unpack_tar2()
    elsif cursor_name().index(".tgz")
        unpack_tgz2()
    elsif cursor_name().index(".lzh")
        unpack_lzh2()
    elsif cursor_name().index(".zip")
        unpack_zip2()
    end
end

def minfo()
    if File.directory?(adir_path() + cursor_name())
        info_directory()
    else
        info_file()
    end
end

defmenu("all",
    "(c)opy", KEY_c, "copy_cursor_or_mark_file()",
    "(C)opy", KEY_C, "menu_copy()",
    "(m)ove", KEY_m, "move_mark_or_cursor_file()",
    "(M)ove", KEY_M,  "menu_move()",
    "(d) trashbox", KEY_d, "throw_mark_or_cursor_file()",
    "(D)elete", KEY_D, "menu_delete()",
    "(e)dit", KEY_e, "edit_cursor_file()",
    "(E)dit", KEY_E, "edit_new_file()",
    "(v)iew", KEY_v, "view_cursor_file()",
    "(r)ename", KEY_r, "rename_cursor_or_mark_file()",
    "(R)ename", KEY_R, "rename_cursor_file2()",
    "(b)ackup", KEY_b, "backup_cursor_or_mark_file()",
    "(p)ack", KEY_p, "pack_mark_or_cursor_file()",
    "(P)ack", KEY_P, "pack_mark_or_cursor_file2()",
    "ma(k)e directory", KEY_k, "make_directory()",
    "(n)ew file", KEY_n, "make_new_file_cmdline()",
    "(l)ink", KEY_l, "make_link()",
    "(L)ink", KEY_L, "make_link2()",
    "(u)npack", KEY_u, "unpack_cursor_file()",
    "(U)npack", KEY_U, "unpack_cursor_file2()",
    "(f) isearch", KEY_f, "start_isearch()",
    "(F) super isearch", KEY_F, "start_sisearch()",
    "e(x)cute", KEY_x, "excute_cursor_or_mark_file()",
    "(h) cmdline", KEY_h, "goto_cmdline()",
    "(H) cmdline menu", KEY_H, "menu_shell()",
    "mma(K)e", KEY_K, "mmake ENV['EDITOR'], '+'",
    "m(g)rep", KEY_g, "mgrep_current_directory()",
    "(G)rep", KEY_G, "menu_grep()",
    "(i)nfo", KEY_i, "minfo",
    "(a)ttribute", KEY_a, "menu_attr()",
    "(s)ort", KEY_s, "menu_sort()",
    "(V)iew menu", KEY_V, "menu_view()",
    "m(y) commands", KEY_y, "menu_my_commands()",
    "(j)ump", KEY_j, "directory_menu",
    "(J)ump", KEY_J, "menu_jump()",
    "c(o)py directory path", KEY_o, "copy_path()",
    "c(O)py directory path", KEY_O, "copy_path2()",
    "(w) exchange directory path", KEY_w, "exchange_path()",
    "(z) xterm", KEY_z, "toggle_xterm_next()",
    "(Z) xterm2", KEY_Z, "toggle_xterm()",
    "(q)uit", KEY_q, "quit_or_close_directory()",
    "(Q)uit", KEY_Q, "mf_exit()"
    )

def enter_directory()
    dir_move(adir(), cursor_name())
end

def enter_link()
    if File.directory?(cursor_name)
        dir_move(adir(), cursor_name())
    end
end

def enter_mark()
    cmdline_c(' %m', 1, nil)
end

def enter_gz()
    if cursor_name().rindex(".tar.gz")
        cmdline_c('%q tar tvfz %f | $PAGER', 0, nil)
    else
        cmdline_c('%q zcat %f | $PAGER', 0, nil)
    end

    enter_cursor_down()
end

def enter_tgz()
    cmdline_c('%q tar tvfz %f | $PAGER', 0, nil)

    enter_cursor_down()
end

def etner_bz2()
    if cursor_name().rindex(".tar.bz2")
        cmdline_c('%q tar tvfj %f | $PAGER', 0, nil)
    else
        cmdline_c('%q bzcat %f | $PAGER', 0, nil)
    end

    enter_cursor_down()
end

def enter_lzh()
    cmdline_c('%q lha l %f | $PAGER', 0, nil)
    enter_cursor_down()
end

def enter_zip()
    cmdline_c('%q zipinfo %f | $PAGER', 0, nil)
    enter_cursor_down()
end

def edit_and_load_ruby_script()
    shell("%q%s%o $EDITOR '#{ENV['MTEMP']}'/mfiler_ruby_script.rb", "mfiler_ruby_script.rb")
    s = select_menu_mfiler("Would you like to excute $MTEMP/mfiler_ruby_script.rb?", ["Yes", "No"])
    if s == 0
        if File.exist?("#{ENV['MTEMP']}/mfiler_ruby_script.rb")
            shell("%R%o load ENV['MTEMP'] + '/mfiler_ruby_script.rb'", "ruby_script")
        end
        reread(0)
        reread(1)
    end
end


###############################################################################
# ** 追加プログラム ***
###############################################################################
require "mfiler_completion"
require "mfiler_directory_history"
require "mfiler_directory_menu"
require "mfiler_file"
require "mfiler_make_new_file"
require "mfiler_mark"
require "mfiler_mask"
require "mfiler_mgrep"
require "mfiler_mmake"
require "mfiler_save_and_restore_stat"
require "mfiler_sudo"
require "mfiler_virtual_directory"

###############################################################################
# スタートアップ
###############################################################################
load_filer_stat()
































=begin
def run_emacs(file)
    if is_screen_terminal()
        shell("%Q%s emacsclient -n #{file} >/dev/null &", file)
        shell("%Q screen -X select emacs", "screen")
    else
        n = 1
        while n < job_num()+1
            if job_title(n).index("emacs")
                break
            end
            n += 1
        end

        # 初めてemacsを起動した
        if n == job_num() + 1
            shell("%q%s emacs -nw #{file}", "emacs")
        # ２回目以降
        else
            shell("%Q%s emacsclient -n #{file} >/dev/null &", file)
            forground_job_title('emacs')
        end
    end
end
=end



### mfiler2終了時のフック ###
def atexit_hook()
    return atexit_hook_default()
end

### メインループのフック ###
def mloop_hook()
    return mloop_hook_default()
end

### ファイラ画面下部の描写のフック ###
def view_hook_filer()
    function_string = ["MENU", "RENAM", "ATTR", "EDIT", "COPY", "MOVE", "LINK", "DEL", "MKDIR", "NEW", "EXCUT", "CMD"]

    maxx = mgetmaxx()
    maxy = mgetmaxy()

    i = 0
    x = 1
    while i < 12
        mattron(MA_REVERSE)
        mmvprintw(maxy-3, x, function_string[i].center((maxx-3)/12-1))
        mattroff()

        x += maxx/12 + if i == 3 || i == 7 then 1 else 0 end
        i += 1
    end

    return 1        # この返り値分ファイラが面画縦に縮む
end

### コマンドライン補完時のフック ###
def completion_hook(editing, editing_dir, editing_file, editing_before, earray, cmd, editing_position)
    $host_names = ["hogehoge.ac.jp", "hogehoge.net"]        # ホスト名
    $user_names = ["hoge"]                                  # ユーザー名
    
    ### オリジナルのコマンドライン補完 ###
    if cmd == "myoriginal"                          # コマンド名がmyoriginal
        if editing.size >= 1 && editing[0]=="-"[0]  # 現在編集している文字列の一文字目が-でTABが押された
            array = [
                ["-a", "my original option1"],
                ["-b", "my original option2"]
            ]

            completion2(array, editing, true, 5)
            return
        end
    end
    
    return completion_hook_default(editing, editing_dir, editing_file, editing_before, earray, cmd, editing_position)
end

$sisearch_except_dir = ["/media/", "/mnt/"]          # スーパーインクリメンタルサーチで検索しないディレクトリ
