#!/bin/bash
export EVENT=DiVOC

TMP=/tmp/$RANDOM
BT="Intergalactic Registration Office - v0.3"



function diaBox() {
  h=8
  w=60
  if [ -n "$3" ]; then
    h=$3
  fi
  if [ -n "$4" ]; then
    w=$4
  fi
  dialog --title "$1" \
  --backtitle "$BT" \
  --msgbox "$2" $h $w
}

function ynBox() {
  h=8
  w=60
  if [ -n "$3" ]; then
    h=$3
  fi
  if [ -n "$4" ]; then
    w=$4
  fi

  dialog --title "$1" \
  --backtitle "$BT" \
  --yesno "$2" $h $w

  return $?
}

function askStr() {
  h=12
  w=60
  if [ -n "$5" ]; then
    h=$5
  fi
  if [ -n "$6" ]; then
    w=$6
  fi

  dialog --title "$2" \
  --backtitle "$BT" \
  --max-input $1 \
  --inputbox "$3" $h $w "$4" 2> $TMP
  return $?
}

function confirm() {
  h=12
  w=60
  if [ -n "$3" ]; then
    h=$3
  fi
  if [ -n "$4" ]; then
    w=$4
  fi

  dialog --title "Confirm: $1" \
  --backtitle "$BT" \
  --yesno "Please confirm those information:\n$2" $h $w
  return $?
}

function askStrThird() {
  h=12
  w=60
  if [ -n "$6" ]; then
    h=$5
  fi
  if [ -n "$7" ]; then
    w=$6
  fi

  dialog --backtitle "$BT" \
    --max-input $1 \
    --title "$2" \
    --extra-button --extra-label "$4" \
    --inputbox "$3" $h $w "$5" 2> $TMP
  return $?
}

function gpgSearch() {
  askStr 255 "GPG Search" "Type in the mail address you'd like to look up on keys.openpgp.org."
  if [ $? -eq 0 ]; then
    if [[ "$(cat $TMP)" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$ ]]; then
      clear
      echo "Searching for GPG key..."
      gpg --keyserver "hkps://keys.openpgp.org" --search "$(cat $TMP)"
      if [ $? -eq 0 ]; then
        export FFP=$(gpg -k "$(cat $TMP)" | head -n 2 | tail -n 1 | awk '{print $1}' | sed 's/.\{4\}/& /g;s/^\(.*\) $/\1/g')
        gpg --batch --delete-key "$FFP"
        return 0
      else
        gpgSearch
      fi
    else
      gpgSearch
    fi
  fi
  return 1
}

function enterGPG() {
  askStrThird 49 "GPG Fingerprint" "Enter GPG fingerprint WITH SPACES. E.g.:\n 1234 5678 9ABC DEF0 1234 5678 9ABC DEF0 1234 5678" "Search..." "$1"

  ret=$?
  case $ret in
    0)
      FP=$(cat $TMP)
      rm $TMP
      if ! [[ $FP =~ ^([[:xdigit:]]{4} ){9}[[:xdigit:]]{4}$ ]]; then
        diaBox "GPG Fingerprint" "This does not match the RegEx of a GPG fingerprint.\nPlease type in the whole fingerprint."
        enterGPG
      fi
      FP=$(echo "$FP" | tr [a-f] [A-F])
      ;;
    1)
      return 1
      ;;
    3)
      gpgSearch
      if [ $? -eq 0 ]; then
        enterGPG "$FFP" "no-confirm"
      fi
      return
      ;;
  esac

  if [ "$2" == "no-confirm" ]; then
    return 0
  else
    confirm "GPG Fingerprint" "  GPG:\n    $FP"
    return $?
  fi
}

function printGPG() {
  askForField "GPG fingerprint" "$1"
  if [ $? -eq 0 ]; then
    diaBox "Insert Passport" "Please insert passport (Visas) into the printer."
    cd "$1"
    ./gpgkey $FIELD $FP
    cd ..
    return 0
  else
    return 1
  fi
}

function printReg() {
  diaBox "Insert Passport" "Please insert passport (First page, name, place) into the printer."
  cd "$1"
  ./reg "$FNAME" "$SNAME" "$PLANET"
  cd ..
  return 0
}

function printIROStamp() {
  askForField "IRO stamp" "$1"
  if [ $? -eq 0 ]; then
    diaBox "Insert Passport" "Please insert passport (Visas) into the printer."
    cd "$1"
    ./iro $FIELD
    cd ..
    return 0
  else
    return 1
  fi
}

function askForField() {
  declare -A layout
  declare -A maxfield
  text="$1: Please choose a free field on the passport.\n"

  layout[jhp]="
  ------------------\n 
  | Archievements  |\n
  ==================\n
  | 0 | 1 || 6 | 7 |\n
  |---|---||---|---|\n
  | 2 | 3 || 8 | 9 |\n
  |---|---||---|---|\n
  | 4 | 5 || 10| 11|\n
  ==================\n
  "
  
  layout[adafruit]="
  ------------------\n 
  | VISAS || VISAS |\n
  ==================\n
  | 0 | 1 || 4 | 5 |\n
  |---|---||---|---|\n
  | 2 | 3 || 6 | 7 |\n
  ==================\n
  "

  maxfield[jhp]=11
  maxfield[adafruit]=7

  askStr 2 "Select a field" "$text ${layout[$2]}" "" 18
  if [ $? -eq 1 ]; then
    return 1
  fi
  FIELD=$(cat $TMP)
  if ! [[ "$FIELD" =~ ^[0-9]+$ ]] || [ -z "$FIELD" ] || [ $FIELD -lt 0 ] || [ $FIELD -gt ${maxfield[$2]} ]; then
    askForField "$1" "$2"
  else 
    return 0
  fi
}


function askReg() {
  # Max length of passport fields
  declare -A MAXLENGTH
  MAXLENGTH[jhp]=25
  MAXLENGTH[adafruit]=17

  askStr ${MAXLENGTH[$1]} "Forename/Nickname" "Enter forename/nickname"
  if [ $? -eq 1 ]; then
    return 1
  fi
  FNAME=$(cat $TMP)

  askStr ${MAXLENGTH[$1]} "Surename" "Enter surename"
  if [ $? -eq 1 ]; then
    return 1
  fi
  SNAME=$(cat $TMP)

  askStr ${MAXLENGTH[$1]} "Place" "Enter place"
  if [ $? -eq 1 ]; then
    return 1
  fi
  PLANET=$(cat $TMP)

  confirm="  Forename:  $FNAME\n  Surename:  $SNAME\n  Place:    $PLANET"

  ynBox "IRO Stamp" "Does this being want to have a IRO stamp?"
  if [ $? -eq 0 ]; then
    STAMP=true
  else
    STAMP=false
  fi

  ynBox "GPG" "Does the being have a GPG key to register?"
  if [ $? -eq 0 ]; then
    enterGPG "" no-confirm
    if [ $? -eq 0 ]; then
      confirm="$confirm\n  GPG:\n    $FP"
    fi
  fi

  confirm "Everything" "$confirm"
  return $?

}

function menuFor() {
  dialog --backtitle "$BT" \
  --menu "Select ID type:" 14 40 3 \
  1 "Registration" \
  2 "IRO Stamp" \
  3 "GPG" \
  9 "Back" 2> $TMP
 
  choice=$(cat $TMP)

  case $choice in
    1)  askReg "$1"
        if [ $? -eq 0 ]; then
          printReg "$1"
          if [ "$STAMP" == "true" ]; then
            printIROStamp "$1"
          fi
          if [ -n "$FP" ]; then
            printGPG "$1"
          fi
        fi
        ;;
    2)  printIROStamp "$1"
        ;;
    3)  enterGPG
        if [ $? -eq 0 ]; then
          printGPG "$1"
        fi
        ;;
        
  esac
  unset FNAME
  unset SNAME
  unset PLANET
  unset FP
  unset FIELD
  unset FFP
}

while [ true ]; do

  dialog --backtitle "$BT" \
    --menu "Select ID type:" 10 40 3 \
    1 "Junghackerpass" \
    2 "New Adafruit passport" \
    9 "Exit" 2> $TMP

  if [ $? -eq 9 ]; then
    break
  fi
  
  TYPE=$(cat $TMP)


  case $TYPE in
    1)  menuFor jhp
        ;;
    2)  menuFor adafruit
        ;;
    9)  exit 0
        ;;
  esac
done

rm $TMP
clear