#!/hint/zsh

# import math functions
autoload -Uz zmathfunc
zmathfunc

local tmp_dir=${TMPPREFIX:-/tmp/zsh}-fzf-tab-$USER
[[ -d $tmp_dir ]] || command mkdir $tmp_dir

local ftb_preview_init
ftb_preview_init=$(<"$FZF_TAB_HOME/lib/-ftb-preview.tpl")

# Inject resolved paths (these MUST refer to the correct pid used to create the files)
local compcap_file="$tmp_dir/compcap.$$"
local groups_file="$tmp_dir/groups.$$"

ftb_preview_init=${ftb_preview_init//__FTB_COMPCAP__/${(q)compcap_file}}
ftb_preview_init=${ftb_preview_init//__FTB_GROUPS__/${(q)groups_file}}

# Inject the dump of 'words'
ftb_preview_init=${ftb_preview_init//__FTB_WORDS_DUMP__/$(typeset -p words)}

# command substitution strips all trailing newlines from the output
ftb_preview_init+=$'\n'

local default_binds=tab:down,btab:up,change:top,ctrl-space:toggle,bspace:backward-delete-char/eof,ctrl-h:backward-delete-char/eof
local fzf_command fzf_flags fzf_preview debug_command tmp switch_group active_group_style fzf_pad fzf_min_height binds
local ret=0

-ftb-zstyle -s fzf-command fzf_command || fzf_command=fzf
-ftb-zstyle -a fzf-bindings-default tmp && binds=${(j:,:)tmp} || binds=$default_binds
-ftb-zstyle -a fzf-bindings tmp && binds+=,${(j:,:)tmp}
-ftb-zstyle -a fzf-flags fzf_flags
-ftb-zstyle -s fzf-preview fzf_preview
-ftb-zstyle -a switch-group switch_group || switch_group=(F1 F2)
-ftb-zstyle -s fzf-pad fzf_pad || fzf_pad=2
-ftb-zstyle -s fzf-min-height fzf_min_height || fzf_min_height=0
-ftb-zstyle -b use-fzf-default-opts use_fzf_default_opts || use_fzf_default_opts="no"
-ftb-zstyle -a active-group-style active_group_style || active_group_style=(bold)

-ftb-zstyle -a debug-command debug_command && {
  ${(eX)debug_command} $fzf_flags
  return
}

local -a _active_style_lower=(${(L)active_group_style})
local -a _active_style_valid=(${(M)_active_style_lower:#(bold|underline|none)})
local -a _active_style_sorted=(${(ou)_active_style_valid})
local normalized_active_group_style=${${(j:,:)_active_style_sorted}:-none}

print -rl -- $_ftb_compcap > $tmp_dir/compcap.$$
print -rl -- $_ftb_groups  > $tmp_dir/groups.$$
print -r -- ${ftb_preview_init/{f}/\$1} > $tmp_dir/ftb_preview_init.$$

binds=${binds//{_FTB_INIT_}/. $tmp_dir/ftb_preview_init.$$ {f} $'\n'}

local -i header_lines=$#_ftb_headers
local -i lines=$(( $#_ftb_compcap + fzf_pad + header_lines ))
local reload_command="$commands[zsh] -f $FZF_TAB_HOME/lib/ftb-switch-group $$ $header_lines $normalized_active_group_style $tmp_dir"

# detect if we will use tmux popup
local use_tmux_popup=0
if [[ $fzf_command == "ftb-tmux-popup" ]]; then
  use_tmux_popup=1
fi

if (( ! use_tmux_popup )); then
  # fzf will cause the current line to refresh, so move the cursor down.
  echoti cud1 >/dev/tty
  # reset cursor before call fzf
  echoti cnorm >/dev/tty 2>/dev/null
fi

command cat > $tmp_dir/completions.$$

local fzf_default_opts=''
if [[ "$use_fzf_default_opts" == "yes" ]]; then
  fzf_default_opts=$FZF_DEFAULT_OPTS
fi

FZF_DEFAULT_OPTS=$fzf_default_opts SHELL=$ZSH_NAME ${(z)fzf_command} \
  --ansi \
  --bind=$binds \
  --bind="${switch_group[1]}:reload($reload_command -1),${switch_group[2]}:reload($reload_command 1)" \
  --cycle \
  --delimiter='\x00' \
  --expect=$continuous_trigger,$print_query,$accept_line \
  --header-lines=$header_lines \
  --height=${FZF_TMUX_HEIGHT:=$(( min(max(lines, fzf_min_height), LINES / 3 * 2)  ))} \
  --layout=reverse \
  --multi \
  --nth=2,3 \
  --print-query \
  --query=$_ftb_query \
  --tiebreak=begin \
  ${fzf_preview:+--preview=${ftb_preview_init}$fzf_preview} \
  $fzf_flags < $tmp_dir/completions.$$ || ret=$?

if (( ! use_tmux_popup )); then
  echoti civis >/dev/tty 2>/dev/null
  echoti cuu1 >/dev/tty
fi

command rm $tmp_dir/*.$$ 2>/dev/null
return $ret
