#compdef GeoBase

# Examples for delimiters
DELIMITERS="(_ ',' '^' ';')"


_headers() {

    local base="$1"
    local help="$2"

    case "$base" in<% SOURCES.each do |source, config| %>
    <%= source %>)
        _arguments \
            "*:$help for <%= source %>:(<%= (['_', '__head__'] + config['headers']).join(' ') %>)"
        ;;<% end %>
    *)
        _arguments \
            "*:$help for ori_por:(<%= (['_', '__head__'] + SOURCES['ori_por']['headers']).join(' ') %>)"
        ;;
    esac
}


_key_fields() {

    local base="$1"
    local help="$2"

    case "$base" in<% SOURCES.each do |source, config| %>
    <%= source %>)
        _arguments \
            "*:$help for <%= source %>:(<%= (['_', '__none__'] + config['headers']).join(' ') %>)"
        ;;<% end %>
    *)
        _arguments \
            "*:$help for ori_por:(<%= (['_', '__none__'] + SOURCES['ori_por']['headers']).join(' ') %>)"
        ;;
    esac
}


_fields() {

    local base="$1"
    local help="$2"

    case "$base" in<% SOURCES.each do |source, config| %>
    <%= source %>)
        _arguments \
            "*:$help for <%= source %>:(<%= (['_', '__key__', '__lno__'] + config['headers']).join(' ') %>)"
        ;;<% end %>
    *)
        _arguments \
            "*:$help for ori_por:(<%= (['_', '__key__', '__lno__'] + SOURCES['ori_por']['headers']).join(' ') %>)"
        ;;
    esac
}


_fields_extended() {

    local base="$1"
    local help="$2"

    case "$base" in<% SOURCES.each do |source, config| %>
    <%= source %>)
        _arguments \
            "*:$help for <%= source %>:(<%= (['_', '__none__', '__key__', '__lno__'] + config['headers']).join(' ') %>)"
        ;;<% end %>
    *)
        _arguments \
            "*:$help for ori_por:(<%= (['_', '__none__', '__key__', '__lno__'] + SOURCES['ori_por']['headers']).join(' ') %>)"
        ;;
    esac
}


_fields_and_join() {

    local base="$1"
    local help="$2"

    case "$base" in<% SOURCES.each do |source, config| %>
    <%= source %>)
        _arguments \
            "*:$help for <%= source %>:(<%= (['_', '__key__', '__lno__'] + [config['join'].map{ |d| d['fields'] }] + config['headers']).join(' ') %>)"
        ;;<% end %>
    *)
        _arguments \
            "*:$help for ori_por:(<%= (['_', '__key__', '__lno__'] + [SOURCES['ori_por']['join'].map{ |d| d['fields'] }] + SOURCES['ori_por']['headers']).join(' ') %>)"
        ;;
    esac
}


count_opt() {
    echo $((`echo "$1" | sed 's/\\\\://g' | sed 's/[^:]//g' |wc -m` - 1))
}

get_opt_value() {

    local short_value="$1"
    local long_value="$2"

    if [[ "$short_value" = "" ]]; then
        echo "$long_value"
    else
        echo "$short_value"
    fi
}


_hello() {

    local curcontext="$curcontext" state line
    typeset -A opt_args

    _arguments \
     "(* -)"{-A,--admin}"[Administrate sources]:*: :->admin" \
     "(* -)"{-a,--ask}"[Learning mode]" \
     "(-b --base)"{-b,--base}"[Choose a different base, default is \"ori_por\"]: :->base" \
     "(-f --fuzzy)"{-f,--fuzzy}"[Fuzzy search on --fuzzy-field field. Default field is \"name\"]: :->fuzzy_value" \
     "(-F --fuzzy-field)"{-F,--fuzzy-field}"[Specify a field for fuzzy searches]: :->fuzzy_field" \
     "(-L --fuzzy-limit)"{-L,--fuzzy-limit}"[Specify a min limit for fuzzy searches, default is "0.85" (this is a percentage)]: :->fuzzy_limit" \
     "(-p --phonetic)"{-p,--phonetic}"[Phonetic search on --phonetic-field field. Default field is \"name\"]: :->phonetic_value" \
     "(-P --phonetic-field)"{-P,--phonetic-field}"[Specify a field for phonetic searches]: :->phonetic_field" \
     "(-y --phonetic-method)"{-y,--phonetic-method}"[Change phonetic matching method]: :->phonetic_method" \
     "(-e --exact)"{-e,--exact}"[Exact search on --exact-field. Default field is \"__key__\"]: :->exact_value" \
     "(-E --exact-field)"{-E,--exact-field}"[Specify a field for exact searches]: :->exact_field" \
     "(-r --reverse)"{-r,--reverse}"[When possible, reverse the logic of the filter]" \
     "(-O --or)"{-O,--or}"[Change *and* behavior to *or* behavior for multiple --exact fields]" \
     "(-n --near)"{-n,--near}"[Radius search, give an argument with \"lat, lng\" or key]: :->near_point" \
     "(-N --near-limit)"{-N,--near-limit}"[Specify a radius in km for radius searches.]: :->near_limit_km" \
     "(-c --closest)"{-c,--closest}"[Closest entries search, give an argument with \"lat, lng\" or key]: :->from_point" \
     "(-C --closest-limit)"{-C,--closest-limit}"[Number of closest points searched with --closest.]: :->closest_limit_nb" \
     "(-d --disable-grid)"{-d,--disable-grid}"[Disable grid for geographical searches]" \
     "(-t --trep)"{-t,--trep}"[OpenTrep mode]: :->trep_value" \
     "(-T --trep-format)"{-T,--trep-format}"[Specify a format for trep searches, default is \"S\".]: :->trep_format" \
     "(-o --omit)"{-o,--omit}"[Omit some fields in output]:*: :->omit" \
     "(-s --show)"{-s,--show}"[Only display some fields in output]:*: :->show" \
     "(-S --show-additional)"{-S,--show-additional}"[Display additional fields in output]:*: :->show_additional" \
     "(-l --limit)"{-l,--limit}"[Specify a limit in the number of results]: :->limit" \
     "(-i --indexation)"{-i,--indexation}"[Specify metadata for stdin data input.]:*: :->indexation" \
     "(-I --interactive-query)"{-I,--interactive-query}"[stdin data is keys for query, not data input]:*: :->interactive" \
     "(-q --quiet)"{-q,--quiet}"[Programmer friendly output]" \
     "(-Q --quiet-options)"{-Q,--quiet-options}"[Custom quiet mode]:*: :->quiet_options" \
     "(-m --map)"{-m,--map}"[Display points on a map]" \
     "(-M --map-options)"{-M,--map-options}"[Custom map display]:*: :->map_options" \
     "(-g --graph)"{-g,--graph}"[Display data on a directed graph]" \
     "(-G --graph-fields)"{-G,--graph-fields}"[Select fields to build the graph display]:*: :->graph_fields" \
     "(-W --graph-weight)"{-W,--graph-weight}"[Select field to compute weight for graph display]: :->graph_weight" \
     "(-w --with-types)"{-w,--with-types}"[For graph display, consider values typed for each field]" \
     "(-v --verbose)"{-v,--verbose}"[Provide additional informations during data loading and queries]" \
     "(* -)"{-u,--update}"[Try to update the data files]" \
     "(* -)"{-U,--update-forced}"[Force the update of all data files]" \
     "(* -)"{-h,--help}"[Show this help message and exit]" \
     "(* -)"{-V,--version}"[Display version information]" \
     "*:list of keys:()"

    # Arguments value
    admin=`get_opt_value "${opt_args[-A]}" "${opt_args[--admin]}"`
    base=`get_opt_value "${opt_args[-b]}" "${opt_args[--base]}"`
    indexation=`get_opt_value "${opt_args[-i]}" "${opt_args[--indexation]}"`
    interactive=`get_opt_value "${opt_args[-I]}" "${opt_args[--interactive-query]}"`
    quiet_options=`get_opt_value "${opt_args[-Q]}" "${opt_args[--quiet-options]}"`
    map_options=`get_opt_value "${opt_args[-M]}" "${opt_args[--map-options]}"`
    graph_fields=`get_opt_value "${opt_args[-G]}" "${opt_args[--graph-fields]}"`


    case $state in
    base)
        _arguments \
            "*:base:(<%= SOURCES.keys.sort.join(' ') %>)"
        ;;
    fuzzy_value|exact_value|phonetic_value|trep_value|near_point|from_point)
        _arguments \
            "*:value"
        ;;
    exact_field|fuzzy_field|phonetic_field)
        _fields "$base" "field"
        ;;
    show|show_additional|omit)
        _fields_and_join "$base" "field"
        ;;
    phonetic_method)
        _arguments \
            "*:phonetic method:(dmetaphone dmetaphone-strict metaphone nysiis)"
        ;;
    near_limit_km)
        _arguments \
            "*:near limit (km):(10 20 30 40 50)"
        ;;
    closest_limit_nb)
        _arguments \
            "*:closest limit (nb):(10 20 30 40 50)"
        ;;
    fuzzy_limit)
        _arguments \
            "*:fuzzy limit (%%):(0.6 0.7 0.8 0.9 0.99)"
        ;;
    limit)
        _arguments \
            "*:limit (nb):(10 15 20 25 50)"
        ;;
    trep_format)
        _arguments \
            "*:trep format:(F S I J)"
        ;;
    admin)
        case `count_opt $admin` in
        0)
            _arguments \
                "*:command:(status fullstatus drop restore edit)"
            ;;
        1)
            _arguments \
                "*:base:(<%= SOURCES.keys.sort.join(' ') %>)"
            ;;
        *)
            _arguments \
                "*:No more arguments for -A"
            ;;
        esac
        ;;
    indexation)
        case `count_opt $indexation` in
        0)
            _arguments \
                "*:delimiter:$DELIMITERS"
            ;;
        1)
            _headers "$base" "headers"
            ;;
        2)
            _key_fields "$base" "key_fields"
            ;;
        3)
            _arguments \
                "*:discard duplicates:(_ Y N)"
            ;;
        4)
            _fields "$base" "indices"
            ;;
        5)
            _fields "$base" "join"
            ;;
        *)
            _arguments \
                "*:No more arguments for -i"
            ;;
        esac
        ;;
    interactive)
        case `count_opt $interactive` in
        0)
            _fields "$base" "input field"
            ;;
        1)
            _arguments \
                "*:input type:(_ __key__ __exact__ __fuzzy__ __phonetic__)"
            ;;
        *)
            _arguments \
                "*:No more arguments for -I"
            ;;
        esac
        ;;
    quiet_options)
        case `count_opt $quiet_options` in
        0)
            _arguments \
                "*:delimiter:$DELIMITERS"
            ;;
        1)
            _arguments \
                "*:header type:(_ RH CH N)"
            ;;
        *)
            _arguments \
                "*:No more arguments for -Q"
            ;;
        esac
        ;;
    map_options)
        case `count_opt $map_options` in
        0)
            _fields_extended "$base" "label field"
            ;;
        1)
            _fields_extended "$base" "weigth field"
            ;;
        2)
            _fields_extended "$base" "color field"
            ;;
        3)
            _arguments \
                "*:icon:(_ B S auto __none__)"
            ;;
        4)
            _arguments \
                "*:link duplicates:(_ Y N)"
            ;;
        5)
            _arguments \
                "*:draw join fields:(_ Y N)"
            ;;
        *)
            _arguments \
                "*:No more arguments for -M"
            ;;
        esac
        ;;
    graph_fields)
        _fields "$base" "graph field"
        ;;
    graph_weight)
        _fields "$base" "graph weight"
        ;;
    #*)
    #    _files
    esac

}


_hello "$@"

# Magic modeline option lo use zsh coloration in vim
# <%= 'vim: ft=zsh' %>
