#!/bin/bash
# Bash library for timing functions

# Calculates the duration between two time spots
lmti_duration() {
  # Takes time spots as parameters 1 and 2 (chronological!) and the output
  # format as parameter 3
  # Output format may be hours, minutes, seconds as well as HH:MM:SS or HHMMSS.
  # It will be rounded down if necessary
  # Returns 0 on success
  # Returns 1 on errors
  # Sets LMTI_TIME to duration
  
  # Fetch parameters
  local START="$1"
  local END="$2"
  local FORMAT="$3"
  
  # Reformat times to HHMMSS
  if lmti_formatspot "$START" "HHMMSS"
    then
      START="$LMTI_TIME"
    else
      return 1
  fi
  if lmti_formatspot "$END" "HHMMSS"
    then
      END="$LMTI_TIME"
    else
      return 1
  fi
  
  # Recalculate to seconds
  START=$(( ${START:0:2} * 3600 + ${START:2:2} * 60 + ${START:4:2} ))
  END=$(( ${END:0:2} * 3600 + ${END:2:2} * 60 + ${END:4:2} ))
  
  # Calculate duration
  if [ "$START" -le "$END" ]
    then
      local DURATION=$(( END - START ))
    else
      # Jumping the midnight boundary; adding 24 hours to END
      local DURATION=$(( 86400 + END - START ))
  fi
  
  # Set output format
  case "$FORMAT" in
    hours)
      LMTI_TIME=$(( DURATION / 3600 ))
      ;;
    minutes)
      LMTI_TIME=$(( DURATION / 60 ))
      ;;
    seconds)
      LMTI_TIME="$DURATION"
      ;;
    *)
      # Calculate hours, minutes and seconds
      local HOURS=$(( DURATION / 3600 ))
      local OVERHANG=$(( DURATION - HOURS * 3600 ))
      local MINUTES=$(( OVERHANG / 60 ))
      local SECONDS=$(( OVERHANG - MINUTES * 60 ))
      # Fill decimals
      if [ "$HOURS" -lt "10" ]
        then
          HOURS="0$HOURS"
      fi
      if [ "$MINUTES" -lt "10" ]
        then
          MINUTES="0$MINUTES"
      fi
      if [ "$SECONDS" -lt "10" ]
        then
          SECONDS="0$SECONDS"
      fi
      # Decide on format
      if [ "$FORMAT" = "HHMMSS" ]
        then
          LMTI_TIME="$HOURS$MINUTES$SECONDS"
      elif [ "$FORMAT" = "HH:MM:SS" ]
        then
          LMTI_TIME="$HOURS:$MINUTES:$SECONDS"
        else
          LMTI_TIME=""
          return 1
      fi
      ;;
  esac
  return 0
}

# Reformats time spots to single number
lmti_formatspot() {
  # Takes time as parameter 1 and output format as parameter 2
  # Works with input formats HHMMSS, HH:MM:SS, HHMM, HH:MM
  # Returns 0 on success
  # Returns 1 on errors
  # Sets LMTI_TIME to input time with output format
  local INPUT="$1"
  local FORMAT="$2"
  
  # Split input time into hour, minute and second
  if echo "$INPUT" | grep -E "^[0-9]{2}(:[0-9]{2}){1,2}$" > /dev/null
    then
      local HOUR="${INPUT:0:2}"
      local MINUTE="${INPUT:3:2}"
      local SECOND="${INPUT:6:2}"
  elif echo "$INPUT" | grep -E "^([0-9]{4}|[0-9]{6})$" > /dev/null
    then
      local HOUR="${INPUT:0:2}"
      local MINUTE="${INPUT:2:2}"
      local SECOND="${INPUT:4:2}"
    else
      return 1
  fi
  # Check if times were set, and set them to 00 if not
  if [ "$HOUR" = "" ]
    then
      HOUR="00"
  fi
  if [ "$MINUTE" = "" ]
    then
      MINUTE="00"
  fi
  if [ "$SECOND" = "" ]
    then
      SECOND="00"
  fi
  # Set to output format
  case "$FORMAT" in
    HHMM)
      LMTI_TIME="$HOUR$MINUTE"
      ;;
    HH:MM)
      LMTI_TIME="$HOUR:$MINUTE"
      ;;
    HHMMSS)
      LMTI_TIME="$HOUR$MINUTE$SECOND"
      ;;
    HH:MM:SS)
      LMTI_TIME="$HOUR:$MINUTE:$SECOND"
      ;;
    *)
      LMTI_TIME=""
      return 1
      ;;
  esac
  return 0
}

# Calculate if the current time fits the configured time frame
lmti_nowin() {
  # Takes start time as parameter 1 and end time as parameter 2
  # Works with formats HHMMSS, HH:MM:SS, HHMM, HH:MM
  # Returns 0 on yes
  # Returns 1 on no or errors
  
  # Fetch parameters
  local START="$1"
  local END="$2"
  
  # Get current time
  local TIME=$(date +'%H%M%S')
  
  # Calculate
  if lmti_timein "$START" "$END" "$TIME"
    then
      return 0
    else
      return 1
  fi
}

# Calculate if the set time fits the configured time frame
lmti_timein() {
  # Takes start time as parameter 1 and end time as parameter 2, as well as
  # the time to check as parameter 3
  # Works with formats HHMMSS, HH:MM:SS, HHMM, HH:MM
  # Returns 0 on yes
  # Returns 1 on no or errors
  
  # Fetch parameters
  local START="$1"
  local END="$2"
  local TIME="$3"
  
  # Reformat times to HHMMSS
  if lmti_formatspot "$START" "HHMMSS"
    then
      START="$LMTI_TIME"
    else
      return 1
  fi
  if lmti_formatspot "$END" "HHMMSS"
    then
      END="$LMTI_TIME"
    else
      return 1
  fi
  if lmti_formatspot "$TIME" "HHMMSS"
    then
      TIME="$LMTI_TIME"
    else
      return 1
  fi
  
  # Calcluate chronological position and handle returns
  if [ "$START" -le "$END" ]
    then
      if [ "$TIME" -ge "$START" -a "$TIME" -lt "$END" ]
        then
          return 0
        else
          return 1
      fi
    else
      if [ "$TIME" -ge "$END" -a "$TIME" -lt "$START" ]
        then
          return 1
        else
          return 0
      fi
  fi
}
