#!/bin/sh -efu

. shell-error

PATH="/usr/lib/alterator-x11:$PATH"
BEST_DPI='96'

DDCPROBE="${DDCPROBE:-/usr/sbin/ddcprobe}"
DDCDUMP_FILE="${DDCDUMP_FILE:-/var/cache/alterator/ddcdump}"

show_help(){
cat <<EOF
monitor_ddc -- get monitor parameters using ddcdump

Usage: monitor_ddc <action>

Actions:
    dump    -- dump ddcprobe data
    clean   -- clean ddcprobe cache
    size    -- print monitor size
    reslist -- print resolution list
    resbest -- print best resolution (for ${BEST_DPI}dpi)
    name    -- print monitor name
    eisa    -- print monitor EISA code
    hsync   -- print horizontal refrash rate
    vsync   -- print vertical refrash rate

EOF
exit 1
}

##############################

ddcdump(){
  if [ ! -f "$DDCDUMP_FILE" ]; then
    timeout 5 $DDCPROBE > "$DDCDUMP_FILE" ||
      fatal "can't get ddc data"
    cat "$DDCDUMP_FILE"
  else
    cat "$DDCDUMP_FILE" ||
      fatal "can't get ddc data"
  fi
}

ddcsize(){
  ddcdump |
    sed -nr\
      -e 's/^screensize:[[:space:]]([0-9]+)[[:space:]]([0-9]+).*/\1 \2/p'\
      -e 'T;q' # get only first line
}

ddcreslist(){
  ddcdump |
    sed -n -r \
        -e 's,^[c]?timing:[[:space:]]+([^@]+)@.*,\1,p' \
        -e 's,^modeline:[[:space:]]+"([^@]+)@.*,\1,p' |
    sort -r -un -k1,1 -k2,2 -tx
}

near_size(){ # convert cm to pixels
  echo "$(( ($1 * $BEST_DPI * 100) / 254 ))"
}
delta(){
  local z=$(($1 - $2))
  echo "${z#-}"
}
ddcresbest(){
  local size="$(ddcsize)"

  [ -n "$size" ] || return 0

  local near_x=$(near_size "${size%% *}")
  local near_y=$(near_size "${size##* }")

  local best_d=
  local best_x=
  local best_y=
  ddcreslist | {
    while IFS='x' read x y;do
      d="$(( $(delta "$x" "$near_x") + $(delta "$y" "$near_y")))"
      if [ -z $best_d ] || [ $d -le $best_d ] ;then
        best_d=$d
        best_x=$x
        best_y=$y
      fi
    done
    [ -n "$best_x" ] && printf '%sx%s\n' $best_x $best_y ||:
  }
}

ddceisa(){
  ddcdump |
    sed -n -r \
        -e 's,",,g'\
        -e 's,^eisa:[[:space:]]*(.*),\L\1,p'\
        -e 'T;q'
}
ddcname()
{
  ddcdump |
    sed -r -n\
        -e 's,",,g'\
        -e 's,[[:space:]]$,,'\
        -e 's,monitorname:[[:space:]]*(.*),\1,p'\
        -e 'T;q'
}

ddchsync(){
  ddcdump |
    sed -n -r \
      -e 's/^horizsync:[[:space:]]*//p'\
      -e 'T;q'
}

ddcvsync(){
  ddcdump |
    sed -n -r \
        -e 's/^vertrefresh:[[:space:]]*//p'\
        -e 'T;q'
}

##############################

[ "$#" = 1 ] || show_help
action="$1"

case "$action" in
  dump)    ddcdump ;;
  clean)   rm -f "$DDCDUMP_FILE" ;;
  size)    ddcsize ;;
  reslist) ddcreslist ;;
  resbest) ddcresbest ;;
  eisa)    ddceisa ;;
  name)    ddcname ;;
  hsync)   ddchsync ;;
  vsync)   ddcvsync ;;
  *)       show_help  ;;
esac
