
$visible_dot_dir = true

def set_glob_mask_hook()
    def mask_hook_ldir(fname, kind, uid, gid, permission)
        if mask(0) == "{*,.*}"
            return nil
        end

        if fname == nil
            return true
        end

        if !File.exist?(ldir_path() + fname)
            return false
        end
        
        if $mask_user
            begin
                usr = Etc.getpwnam($mask_user)
            rescue
                usr = -1
            end
        else
            usr = -1
        end

        if $mask_group
            begin
                grp = Etc.getgrnam($mask_group)
            rescue
                grp = -1
            end
        else
            grp = -1
        end

        if fname == ".."
            return true
        elsif !$visible_dot_dir && (kind == 1 || kind == 3) && fname[0] == "."[0]
            return false
        elsif kind == 1 || kind == 3
            return true
        else
            if usr == -1 || uid == usr.uid
                if grp == -1 || gid == grp.gid
                    if $mask_permission == nil || $mask_permission == permission
                        if File.fnmatch?(mask(0), fname)
                            return true
                        end
                    end
                end
            end

            return false
        end
    end

    def mask_hook_rdir(fname, kind, uid, gid, permission)
        if mask(1) == "{*,.*}"
            return nil
        end

        if fname == nil
            return true
        end

        if !File.exist?(rdir_path() + fname)
            return false
        end

        if $mask_user
            begin
                usr = Etc.getpwnam($mask_user)
            rescue
                usr = -1
            end
        else
            usr = -1
        end

        if $mask_group
            begin
                grp = Etc.getgrnam($mask_group)
            rescue
                grp = -1
            end
        else
            grp = -1
        end

        if fname == ".."
            return true
        elsif !$visible_dot_dir && (kind == 1 || kind == 3) && fname[0] == "."[0]
            return false
        elsif kind == 1 || kind == 3
            return true
        else
            if usr == -1 || uid == usr.uid
                if grp == -1 || gid == grp.gid
                    if $mask_permission == nil || $mask_permission == permission
                        if File.fnmatch?(mask(1), fname)
                            return true
                        end
                    end
                end
            end

            return false
        end
    end
end

def glob_mask(mask, user, group, permission)
    if user == "*"
        $mask_user = nil
    else
        $mask_user = user
    end

    if group == "*"
        $mask_group = nil
    else
        $mask_group = group
    end

    if permission == "*"
        $mask_permission = nil
    else
        $mask_permission = permission
    end

    set_glob_mask_hook()
    set_mask(adir(), mask)
    set_mask(sdir(), mask)
    reread(0)
    reread(1)

    i = 0
    while i < cursor_max(adir())
        fname = file_name(adir(), i)

        if !File.directory?(adir_path() + fname)
            cursor_move(adir(), i)
            break
        end

        i += 1
    end
end

def set_regex_mask_hook()
    def mask_hook_ldir(fname, kind, uid, gid, permission)
        if mask(0) == "{*,.*}"
            return nil
        end

        if fname == nil
            return true
        end

        if !File.exist?(ldir_path() + fname)
            return false
        end

        if $mask_user
            begin
                usr = Etc.getpwnam($mask_user)
            rescue
                usr = -1
            end
        else
            usr = -1
        end

        if $mask_group
            begin
                grp = Etc.getgrnam($mask_group)
            rescue
                grp = -1
            end
        else
            grp = -1
        end

        if fname == ".."
            return true
        elsif !$visible_dot_dir && (kind == 1 || kind == 3) && fname[0] == "."[0]
            return false
        elsif kind == 1 || kind == 3
            return true
        else
            if usr == -1 || uid == usr.uid
                if grp == -1 || gid == grp.gid
                    if $mask_permission == nil || $mask_permission == permission
                        begin
                            if fname =~ /#{mask(0)}/
                                return true
                            else
                                return false
                            end
                        rescue
                            return false
                        end
                    end
                end
            end

            return false
        end
    end

    def mask_hook_rdir(fname, kind, uid, gid, permission)
        if mask(1) == "{*,.*}"
            return nil
        end

        if fname == nil
            return true
        end

        if !File.exist?(rdir_path() + fname)
            return false
        end

        if $mask_user
            begin
                usr = Etc.getpwnam($mask_user)
            rescue
                usr = -1
            end
        else
            usr = -1
        end

        if $mask_group
            begin
                grp = Etc.getgrnam($mask_group)
            rescue
                grp = -1
            end
        else
            grp = -1
        end

        if fname == ".."
            return true
        elsif !$visible_dot_dir && (kind == 1 || kind == 3) && fname[0] == "."[0]
            return false
        elsif kind == 1 || kind == 3
            return true
        else
            if usr == -1 || uid == usr.uid
                if grp == -1 || gid == grp.gid
                    if $mask_permission == nil || $mask_permission == permission
                        begin
                            if fname =~ /#{mask(1)}/
                                return true
                            else
                                return false
                            end
                        rescue
                            return false
                        end
                    end
                end
            end

            return false
        end
    end
end

def regex_mask(mask, user, group, permission) 
    if user == "*"
        $mask_user = nil
    else
        $mask_user = user
    end

    if group == "*"
        $mask_group = nil
    else
        $mask_group = group
    end

    if permission == "*"
        $mask_permission = nil
    else
        $mask_permission = permission
    end

    set_regex_mask_hook()
    set_mask(0, mask)
    set_mask(1, mask)
    reread(0)
    reread(1)

    i = 0
    while i < cursor_max(adir())
        fname = file_name(adir(), i)

        if !File.directory?(adir_path() + fname)
            cursor_move(adir(), i)
            break
        end

        i += 1
    end
end

def glob_filter(glob, uname, gname, permission, directory, symlink, regular_file)
    i = 0
    max = cursor_max(adir())
    while i < max
        match = false
        
        if file_name(adir(), i) == ".."
            match = true
        else
            if uname == "*" || file_user(adir(), i) == uname
                if gname == "*" || file_group(adir(), i) == gname
                    if permission == "*" || file_permission(adir(), i) == permission
                        if file_kind(adir(), i) == 0 && regular_file || file_kind(adir(), i) == 1 && directory || file_kind(adir(), i) == 2 && symlink
                            if File.fnmatch?(glob, file_name(adir(), i))
                                match = true
                            end
                        end
                    end
                end
            end
        end

        if !match
            delete_file_from_file_list(adir(), i)
            i -= 1
            max -= 1
        end

        i += 1
    end

    set_scrolltop(adir(), 0)
    cursor_move(adir(), 0)

    mfiler_view()
end

def regex_filter(regex, uname, gname, permission, directory, symlink, regular_file)
    i = 0
    max = cursor_max(adir())
    while i < max
        match = false
        
        if file_name(adir(), i) == ".."
            match = true
        else
            if uname == "*" || file_user(adir(), i) == uname
                if gname == "*" || file_group(adir(), i) == gname
                    if permission == "*" || file_permission(adir(), i) == permission
                        if file_kind(adir(), i) == 0 && regular_file || file_kind(adir(), i) == 1 && directory || file_kind(adir(), i) == 2 && symlink
                            if file_name(adir(), i) =~ /#{regex}/
                                match = true
                            end
                        end
                    end
                end
            end
        end

        if !match
            delete_file_from_file_list(adir(), i)
            i -= 1
            max -= 1
        end

        i += 1
    end

    set_scrolltop(adir(), 0)
    cursor_move(adir(), 0)

    mfiler_view()
end

defmenu("grep_menu",
    "(g)rep current directory",     KEY_g,      "grep_current_directory()",
    "(G)rep recursive",             KEY_G,      "grep_recursive()",
    "(m)grep current directory",    KEY_m,      "mgrep_current_directory()",
    "(M)grep recursive",            KEY_M,      "mgrep_recursive()"
)

defmenu("mask",
   "glob (f)ilter", KEY_f, "cmdline_c(\"%Q%r glob_filter '*', '*', '*', '*', true, true, true # glob, user, group, permission, directory, symlink, regular_file\", 20, nil)",
   "regex (F)ilter", KEY_F, "cmdline_c(\"%Q%r regex_filter '', '*', '*', '*', true, true, true # regex, user, group, permission, directory, symlink, regular_file\", 20, nil)",
   "glob (m)ask", KEY_m, "if is_remain_marks() then cmdline_c(\"%Q%r glob_mask '*', '*', '*', '*' # glob, user, group, permission\", 18, nil); else cmdline_c(\"%Q%r%o glob_mask '*', '*', '*', '*' # glob, user, group, permission\", 20, nil); end",
   "regex (M)ask", KEY_M, "if is_remain_marks() then cmdline_c(\"%Q%r regex_mask '', '*', '*', '*' # glob, user, group, permission\", 18, nil); else cmdline_c(\"%Q%r%o regex_mask '', '*', '*', '*' # regex, user, group, permission\", 20, nil); end"
)

def menu_mask()
    menu("mask")
end
