function inArray() {
    declare -a arr1=("${!1}")
    declare -a arr2=("${!2}")

    for i in ${arr1[@]}; do 
        for j in ${arr2[@]}; do
            if [[ $i == $j ]] ; then
                echo $i
                break
            fi
        done
    done
    echo ""
}

_ctt() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # ctt available commands
    cmds="listprojects track report"

    # current command, if the user supplied any
    curr_cmd=$(inArray COMP_WORDS[@] cmds[@])

    # various options, 
    # generics and command specific 
    declare -A cmdopts
    opts="--help --debug --verbose "
    cmdopts[_shared]="--start --end "
    cmdopts[report]="--all --regexp --ignorecase --format "
    cmdopts[report]+=${cmdopts[_shared]}
    cmdopts[track]="--no-comment "
    cmdopts[track]+=${cmdopts[_shared]}
    cmdopts[listprojects]=""

    # expand options based on given command
    # or only generic ones
    if [[ "$cur" == -* ]]; then
        if [ ! -z $curr_cmd ]; then
            COMPREPLY=( $(compgen -W "${opts} ${cmdopts[${curr_cmd}]}" -- ${cur}) )
        else
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        fi
        return 0
    fi

    # expand project names if a 
    # suitable command is specified
    # also do not expand more than one project if one already expanded
    if [[ ! -z $curr_cmd ]]; then
        projects=$(for p in ~/.ctt/*; do basename "$p"; done )
        curr_proj=$(inArray COMP_WORDS[@] projects[@])
        if [ ! -z $curr_proj ]; then
            return 0
        fi
        case "${curr_cmd}" in
            track)
                COMPREPLY=( $(compgen -W "${projects}" -- ${cur}) )
            ;;
            report)
                COMPREPLY=( $(compgen -W "${projects}" -- ${cur}) )
                ;;
            listprojects)
                COMPREPLY=( $(compgen -W "" -- ${cur}) )
            ;;
        esac
    else
        COMPREPLY=( $(compgen -W "${cmds}" -- ${cur}) )
    fi

    return 0
}
complete -F _ctt ctt 
