#!/bin/bash

####################################################################
#
#   The file dialog routines
#
####################################################################

#
# dialog data model
#
typeset file_dialog_title
typeset file_dialog_filter

typeset file_list_height=10
typeset file_list_sel_index
typeset file_list_top_index
typeset -a file_list_array

typeset dir_list_height=10
typeset dir_list_sel_index
typeset dir_list_top_index
typeset -a dir_list_array

typeset file_dialog_dir
typeset file_dialog_file

load_file_dialog_help() {
    load_ui_res << EOF
~
~    &([Help])
~    +-----------------------------------------+
~    |     Key        |      Function          |
~    |----------------|------------------------|
~    |    Up arrow    |   Scroll up            |
~    |    Down arrow  |   Scroll down          |
~    |    Page up     |   Scroll page up       |
~    |    Page down   |   Scroll page down     |
~    |    Home        |   Scroll to first      |
~    |    End         |   Scroll to end        |
~    |    Tab         |   Change focus         |
~    |    Enter       |   Change directory     |
~    |    x           |   Cancel               |
~    |    O           |   Confirm              |
~    +-----------------------------------------+
~       Press 'x' to return
EOF
}

load_file_dialog_ui() {
    load_ui_res << EOF
O --=&(O) --
X --=&(X) --
(fff-fff/fff)=<?f_range,13?>
(ddd-ddd/ddd)=<?d_range,13?>
~
~    <?Title,-#?>################################
~    +------------------------------------------+
~    |                                          |
~    | [<?pwd,-#?>############################] |
~    |                                          |
~    |-------[Dirs]--------------[Files]--------|
~    | <?d_list[0],-#?>## | <?f_list[0],-#?>### |
~    | <?d_list[1],-#?>## | <?f_list[1],-#?>### |
~    | <?d_list[2],-#?>## | <?f_list[2],-#?>### |
~    | <?d_list[3],-#?>## | <?f_list[3],-#?>### | 
~    | <?d_list[4],-#?>## | <?f_list[4],-#?>### |
~    | <?d_list[5],-#?>## | <?f_list[5],-#?>### |
~    | <?d_list[6],-#?>## | <?f_list[6],-#?>### |
~    | <?d_list[7],-#?>## | <?f_list[7],-#?>### |
~    | <?d_list[8],-#?>## | <?f_list[8],-#?>### |
~    | <?d_list[9],-#?>## | <?f_list[9],-#?>### |
~    |---(ddd-ddd/ddd)---------(fff-fff/fff)----|
~    |                                          |
~    |     [O -- Ok]          [X -- Cancel]     |
~    |                                          |
~    +------------------------------------------+
~    
~      Press &(?) for help
EOF
}

#
# $1 -- new file or not
#
load_files() {
    unset file_list_array[*];
    file_list_sel_index=0
    file_list_top_index=0
    local -i i=0
    if [ $# -eq 1 ]; then
        if [ "$1" == "new" ]; then
            file_list_array[$i]="<CREATE NEW FILE>"
            let i++
        fi
    fi
    files="`ls -1`"
    while [ ${#files} -gt 0 ]; do
        if [ "${files%%*$'\n'*}" == "" ]; then
            file="${files%%$'\n'*}"
            files="${files#*$'\n'}"
        else
            file="$files"
            files=""
        fi
        if [ -f "$file" ]; then
            if [ "${file%%$file_dialog_filter}" == "" ]; then
                file_list_array[$i]="$file"
                let i++
            fi
        fi
    done
}

load_dirs() {
    unset dir_list_array[*];
    dir_list_sel_index=0
    dir_list_top_index=0
    local -i i=0
    dir=`pwd`
    if [ "${dir%%/cygdrive/?}" != "" ]; then 
        dir_list_array[$i]=".."
        let i++
    fi
    files="`ls -1`"
    while [ ${#files} -gt 0 ]; do
        if [ "${files%%*$'\n'*}" == "" ]; then
            file="${files%%$'\n'*}"
            files="${files#*$'\n'}"
        else
            file="$files"
            files=""
        fi
        if [ "$file" != "." ] && [ -d "$file" ]; then
            dir_list_array[$i]="$file"
            let i++
        fi
    done
    if [ -d "/cygdrive" ]; then
        cd /cygdrive
        for drive in `ls`; do
            dir_list_array[$i]="[-$drive-]"
            let i++
        done
        cd -
    fi
}

#
# $1 -- var name
# $2 -- index
#
file_dialog_get_data() {
    local name=$1
    local -i index=$2
    _DATA_="???"
    case $1 in
        Title)
            _DATA_="$file_dialog_title"
            _DATA_ATTR_=1
            ;;
        f_list)
            get_list_data "file_list" $index 
            ;;
        f_range)
            get_list_range "file_list" 13
            ;;
        d_list)
            get_list_data "dir_list" $index 
            ;;
        d_range)
            get_list_range "dir_list" 13
            ;;
        pwd)
            _DATA_=$(pwd)
            if [ "${_DATA_%%/cygdrive/*}" == "" ]; then
                _DATA_=`cygpath -w "$_DATA_"`
            fi
            ;;
    esac
}

#
# run the file dialog
#
# $1 -- title
# $2 -- initial path
# $3 -- filter
# $4 -- create new file or not
#
run_file_dialog() {
    file_dialog_title="$1"
    local org_path="`pwd`"
    if [ -d "$2" ]; then cd "$2"; fi
    file_dialog_filter="$3"
    load_file_dialog_ui
    load_dirs
    load_files "$4"
    _FOCUS_="dir_list"
    local close="false"
    while [ "$close" != "true" ]; do
        update_ui "file_dialog_get_data"
        read_key
        case $_KEY_ in
            enter)
                if [ "$_FOCUS_" == "dir_list" ]; then
                    dir="${dir_list_array[$dir_list_sel_index]}"
                    if [ "${dir:0:1}" == '[' ]; then
                        dir='/cygdrive/'${dir:2:1}
                    fi
                    cd "$dir"
                    load_dirs
                    load_files "$4"
                    _UI_UPDATED_="false"
                fi
                ;;
            O|o)
                if [ "$_FOCUS_" == "file_list" ]; then
                    file_dialog_dir="`pwd`"
                    file_dialog_file="${file_list_array[$file_list_sel_index]}"
                    close="true"
                    if [ "$file_dialog_file" == "<CREATE NEW FILE>" ]; then
                        clear
                        echo -n "creat a new file in directory: "
                        if [ "${file_dialog_dir%%/cygdrive/*}" == "" ]; then
                            cygpath -w "$file_dialog_dir"
                        else
                            echo "$file_dialog_dir"
                        fi
                        echo -n "File name: "
                        tty_restore
                        read file_dialog_file
                        tty_init
                        if [ "$file_dialog_file" == "" ]; then
                            close="false"
                        fi
                    fi
                fi
                ;;
            X|x)
                close="true"
                ;;
            up|down|pgup|pgdown|home|end)
                scroll_list $_FOCUS_ $_KEY_ 
                ;;
            tab)
                if [ "$_FOCUS_" == "file_list" ]; then
                    _FOCUS_="dir_list"
                else
                    _FOCUS_="file_list"
                fi
                _UI_UPDATED_="false"
                ;;
            '?')
                load_file_dialog_help
                update_ui
                while [ "$_KEY_" != "x" ]; do read_key; done
                load_file_dialog_ui
                ;;
        esac
    done
    cd "$org_path"
}


