#!/usr/bin/env bash

DIALOG_CANCEL=1
DIALOG_ESC=255
HEIGHT=0
WIDTH=0
SketchHexpath="/build/arduino.avr.nano/"
SketchHexExt=".ino.hex"
SetFile="PathSetup.txt"
avrFile="?"
filePath="?"
MainPath="?"
HexfilesFolder=""
TmpModFile="FileMod.txt"
vbl=""
vblcnt=0


Get_PathFileHelp() { 
  exec 3>&1
  selection=$(dialog \
  --title "" \
  --clear \
  --cancel-label "Exit" \
  --menu "" $HEIGHT $WIDTH 0 \
  "" "        $SetFile Layout Help       " \
  "" "" \
  "" "$SetFile has two entries: Line 1:" \
  "" "" \
  "" "Path to the Arduino Main Sketch Folder containing" \
  "" "various Sketch folders, starts and ends with: /" \
  "" "" \
  "" "Line 2 is:" \
   "" "" \
   "" "Path and Folder for other *.hex files that don't" \
  "" "have a Sketch folder, it also starts and ends with /" \
  "" "" \
  "" "IE: $SetFile would look something like:" \
  "" "" \
  "" "  /home/mark/Arduino/" \
  "" "  /home/mark/coding/HexFiles/" \
  2>&1 1>&3)
  exit_status=$?
   exec 3>&-
   case $exit_status in
     $DIALOG_ESC)
     break
    esac
  }

Verify_Code() { 
  clear
  if test -f $MainPath$avrFile 
  then 
    avrdude -c usbasp -p m328P -F $vbl -V -U flash:w:$MainPath$avrFile 
    read xx
  fi 
 }

Program_Hex() {
   clear
    if test -f $MainPath$avrFile 
    then 
      avrdude -c usbasp -p m328P -F $vbl -U flash:v:$MainPath$avrFile
      read xx
    fi 
}

Read_Fuses() {
  clear 
  Tempstr=$(avrdude -c usbasp-clone -p m328p -F -U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h -U lock:r:-:h)
  result="_____Reading Fuses_____\n\n$Tempstr\n\nResult should be\n\n0xFF 0xD7 0xFD 0xFF"  
  display_result "FUSES"  
} 

Program_Fuses() {
  clear
  echo " Program Fuses"
  echo  
  echo 
  echo " Y to Program n to Abort"
  read xx
  if [ $xx == "Y" ]; then
    echo 
    echo 
    avrdude -c usbasp-clone -p m328p -F -U lock:w:0xFF:m -U lfuse:w:0xFF:m -U hfuse:w:0xD7:m -U efuse:w:0xFD:m   
    echo "Any Key to continue"
    read xx 
  fi 
}

Check_Programmer() {
  clear
  Tempstr=$(lsusb | grep "Van Ooijen")
  substring="Van Ooijen"
  if [[ $Tempstr == *"$substring"* ]]; then
    result="The USBasp device string is Present\n\n$Tempstr"  
    display_result "INFO" 
    clear  
    echo "Now Unplug the USBasp device, wait a few second"
    echo "then plug in back in and enter the password"
    echo 
    Tempstr=$(sudo dmesg | tail -f | grep USBasp) 
    substring="USBasp"
    if [[ $Tempstr == *"$substring"* ]]; then
      result="The USBasp device is Present\n\n$Tempstr"  
      display_result "INFO"  
    else
      result="The USBasp device was not Detected\n\nTry removing the USB Device, wait a few seconds, then plug it back in and run this test again "  
      display_result "ERROR"  
    fi            
  else
    result="The USBasp device string is Missing\n"  
    display_result "INFO" 
  fi   
  clear 
 }

display_result() {
  dialog --title "$1" \
   --no-collapse \
   --msgbox "\n$result" 0 0
}

Check_SetupFile() {
 if ! [ -f $SetFile ] 
  then
    exec 3>&1
    selection=$(dialog \
    --title "Menu" \
    --clear \
    --cancel-label "Close" \
    --menu "" $HEIGHT $WIDTH 0 \
    "" "WARNING !! $SetFile is missing! " \
    "" "" \
    "Make" "Make New empty file: $SetFile" \
    "" "" \
    "" "If you are unsure of the $SetFile contents" \
    "" "or usage, select item 1 Help in the menu" \
    2>&1 1>&3)
    exit_status=$?
    exec 3>&-
    case $exit_status in
     $DIALOG_CANCEL)
       clear
       break ;;
     $DIALOG_ESC)
       clear
       break ;;
    esac

   case $selection in
     Make)
      if [ -f $SetFile ] ; then
       result="$SetFile already exists\n"  
       display_result "ERROR"      
      else
       echo "MAKE NEW $SetFile FILE  Y"
       read x
       if [ $x == "Y" ]; then 
         touch $SetFile
       fi
      fi 
   esac    
 fi
}

CheckStart_USB() {
  Tempstr=$(lsusb | grep "Van Ooijen")
  substring="Van Ooijen"

  if ! [[ $Tempstr == *"$substring"* ]]; then
    result="The USBasp device not Detected\n"  
    display_result "ERROR"  
  fi
}

# get paths from PathSetup.txt user file

Get_FilePaths() { 
 cnt=0
 ftime2=""
   if [ -e $SetFile ] ; then
   while read -r  fc ; do
      cnt=$((cnt + 1))
      case $cnt in
       1)
         filePath=$fc ;;
       2)
         HexfilesFolder=$fc ;;
       esac
    done < $SetFile
    else
    ftime2="!!!!! $SetFile ERROR see menu item 1 for Help"
  fi
    fchg="-"
    fdat="-"
    fchg1=-""
    fdat1="-"
    fchg2="-"
    fdat2="-"
    ftime="No File selected, Missing Folder or Incorrect Path"    
    ftime1="-"    
  }
  
 Get_FileDates() { 
   if test -f $MainPath$avrFile
   then
    cnt=0
    stat $MainPath$avrFile | (grep -C1 Modify) > $TmpModFile
     while read -r  fc fd ft; do
      cnt=$((cnt + 1))
      case $cnt in
       1)
         fchg=$fc
         fdat=$fd
         ftime=$ft ;;
        2)
         fchg1=$fc
         fdat1=$fd
         ftime1=$ft ;;
       3)
         fchg2=$fc
         fdat2=$fd
         ftime2=$ft ;;
       esac
     done < $TmpModFile
  else
      if [ $avrFile != "?" ] ; then  # if ? bypass script at startup
      result=$(echo "$MainPath\n\n$avrFile\n\nInvalid File or Path")  
      display_result "ERROR"
      avrFile="-"
     fi
  fi
} 
   
 # get Sketch folder from path and get hex file
Get_Sketch_Hex() { 
    clear
    cnt=0
    for file in $(ls "$filePath") 
      do
      cnt=$((cnt + 1))
      fc="$file"
      case $cnt in
      1)
        hex1=$fc ;;
      2)
        hex2=$fc ;;
      3)
        hex3=$fc ;;
      4)
        hex4=$fc ;;
      5)
        hex5=$fc ;;
      6)
        hex6=$fc ;;  
      7)
        hex7=$fc ;;
      8)
        hex8=$fc ;;
      9)
        hex9=$fc ;;
      10)
        hex10=$fc ;;
      11)
        hex11=$fc ;;
      12)
        hex12=$fc ;;           
      13) 
        hex13=$fc ;;   
      14) 
        hex14=$fc ;;                     
      esac
     done
    clear
    
   while true; do
     exec 3>&1
     selection=$(dialog \
      --title "Select Sketch Folder" \
      --cancel-label "Cancel" \
      --clear \
      --menu "" $HEIGHT $WIDTH 0 \
      "1" "$hex1" \
      "2" "$hex2" \
      "3" "$hex3" \
      "4" "$hex4" \
      "5" "$hex5" \
      "6" "$hex6" \
      "7" "$hex7" \
      "8" "$hex8" \
      "9" "$hex9" \
      "A" "$hex10" \
      "B" "$hex11" \
      "C" "$hex12" \
      "D" "$hex13" \
      "E" "$hex14" \
   2>&1 1>&3)
   exit_status=$?
   exec 3>&-
   case $exit_status in
     $DIALOG_CANCEL)
       break ;;
     $DIALOG_ESC)
       break ;;
  esac
     avrFile=""
     case $selection in
      1)
        avrFile=$hex1 ;;
      2)
        avrFile=$hex2 ;;
      3)
        avrFile=$hex3 ;;
      4)
        avrFile=$hex4 ;;
      5)
        avrFile=$hex5 ;;
      6)
        avrFile=$hex6 ;;
      7)
        avrFile=$hex7 ;;
      8)
        avrFile=$hex8 ;;
      9)
        avrFile=$hex9 ;;
      A)
        avrFile=$hex10 ;;
      B)
        avrFile=$hex11 ;;
      C)
        avrFile=$hex12 ;;
      D)
        avrFile=$hex13 ;;
      E)
        avrFile=$hex14 ;;            
      esac   
    if ! [ $avrFile ] ; then avrFile="???" ; fi
    MainPath=$filePath$avrFile$SketchHexpath
    avrFile=$avrFile$SketchHexExt
    break
  done 
}    

 #----Get Other HEX files-------------------
 
Get_OtherHex_File() { 
  clear
  cnt=0
  for file in $(ls "$HexfilesFolder") 
   do
   cnt=$((cnt + 1))
   fc="$file"
   case $cnt in
    1)
      shex1=$fc ;;
    2)
      shex2=$fc ;;
    3)
      shex3=$fc ;;
    4)
      shex4=$fc ;;
    5)
      shex5=$fc ;;
    6)
      shex6=$fc ;;  
    7)
      shex7=$fc ;;
    8)
      shex8=$fc ;;
    9)
      shex9=$fc ;;
    10)
      shex10=$fc ;;
    11)
      shex11=$fc ;;
    12)
      shex12=$fc ;;           
     13) 
      shex13=$fc ;;   
     14) 
     shex14=$fc ;;                     
    esac
  done
 while true; do
  exec 3>&1
  selection=$(dialog \
   --title "Select a *.Hex file" \
   --cancel-label "Cancel" \
   --clear \
   --menu "" $HEIGHT $WIDTH 0 \
    "1" "$shex1" \
    "2" "$shex2" \
    "3" "$shex3" \
    "4" "$shex4" \
    "5" "$shex5" \
    "6" "$shex6" \
    "7" "$shex7" \
    "8" "$shex8" \
    "9" "$shex9" \
    "A" "$shex10" \
    "B" "$shex11" \
    "C" "$shex12" \
    "D" "$shex13" \
    "E" "$shex14" \
    2>&1 1>&3)
    exit_status=$?
    exec 3>&-
    case $exit_status in
     $DIALOG_CANCEL)
       break ;;
     $DIALOG_ESC)
       break ;;
    esac
    case $selection in
      1)
        avrFile=$shex1 ;;
      2)
        avrFile=$shex2 ;;
      3)
        avrFile=$shex3 ;;
      4)
        avrFile=$shex4 ;;
      5)
        avrFile=$shex5 ;;
      6)
        avrFile=$shex6 ;;
      7)
        avrFile=$shex7 ;;
      8)
        avrFile=$shex8 ;;
      9)
        avrFile=$shex9 ;;
      A)
        avrFile=$shex10 ;;
      B)
        avrFile=$shex11 ;;
      C)
        avrFile=$shex12 ;;
      D)
        avrFile=$shex13 ;;
      E)
        avrFile=$shex14 ;;
    esac    
   if ! [ $avrFile ] ; then avrFile="???" ; fi
   MainPath=$HexfilesFolder 
   break 
 done 
}
 
 #-------------------Main menu---------------------------  

 Check_SetupFile

 CheckStart_USB
 
while true; do
 
 clear
  
 Get_FilePaths
 
 Get_FileDates
 
   exec 3>&1
   selection=$(dialog \
    --title "Avrdude Programmer" \
    --cancel-label "Exit" \
    --menu "" $HEIGHT $WIDTH 0 \
   "1" "Help for Sketch and Hex $SetFile Layout" \
   "" "" \
   "2" "Select an Arduino Sketch folder in $filePath" \
    "3" "Select directly from $HexfilesFolder ?.hex" \
   "" "" \
   "4" "Program Hex code into the Nano" \
   "5" "Verify uploaded Nano Hex code" \
   "" "" \
   "6" "Avrdude Verbose output level: Current = $vblcnt" \
   "7" "Check USBasp hardware programming device status" \
   "" "" \
   "8" "Read and display the Nano fuse values" \
   "9" "Program Nano fuses for safe usage in an Inverter" \
   "" "" \
   "" "Path: $MainPath" \
   ""  "" \
   ""  "File: $avrFile" \
   "" "" \
   "" "$fchg $fdat $ftime" \
   "" "$fchg1 $fdat1 $ftime1" \
   "" "$fchg2 $fdat2 $ftime2" \
   2>&1 1>&3)
    
   exit_status=$?
   exec 3>&-
     case $exit_status in
     $DIALOG_CANCEL)
      clear
      exit  ;;
     $DIALOG_ESC)
      clear
      exit 1 ;;
   esac
   
   case $selection in
      1)
        Get_PathFileHelp ;;
      2)
        Get_Sketch_Hex ;; 
      3)
        Get_OtherHex_File ;;
      4)
        Verify_Code ;;
      5)
        Program_Hex ;;
        6) 
        case $vblcnt in
           0 )
             vbl="-v" 
             vblcnt=1 ;;
           1 )
             vbl="-v -v"
              vblcnt=2 ;;
           2 )
             vbl=" "
             vblcnt=0 ;;
         esac ;;
      7)
        Check_Programmer ;; 
      8)
        Read_Fuses ;;
      9)
        Program_Fuses ;;
  esac
done

