#!/bin/bash
#---------------------------------------------------------------------
##
## @Synopsis Set of functions used by the internal sorcery scripts
##
## Functions used to manage triggers. Used both by spells
## and by the sorcery scripts.
##
## @Copyright Original version Copyright 2002 by the Source Mage Team
##
#---------------------------------------------------------------------


#---------------------------------------------------------------------
## Checks for a TRIGGERS file in SCRIPT_DIRECTORY, and if it is
## executable, runs it.
#---------------------------------------------------------------------
function run_triggers() {
  debug "libtriggers" "Starting run_triggers() on $SPELL"

  if [ -x $SCRIPT_DIRECTORY/TRIGGERS ]; then
    persistent_load
    . $SCRIPT_DIRECTORY/TRIGGERS
    persistent_save
  fi

}

#---------------------------------------------------------------------
## @param spell
##
## Remove's all of a spell's triggers from the list of registered 
## triggers.
##
#---------------------------------------------------------------------
function remove_triggers ()
{ 
  debug "libtriggers" "remove_triggers - $*"

  [ -f $TRIGGER_LIST ] || return 0
  tTRIGGER_LIST=`lock_start_transaction $TRIGGER_LIST`
  [ -f $tTRIGGER_LIST ] || return 0
  grep -v "^$SPELL:" $TRIGGER_LIST > $tTRIGGER_LIST
  lock_commit_transaction $TRIGGER_LIST
  return $?
}

#---------------------------------------------------------------------
## @param event
## @param [spell]
## @Globals SPELL if \$2 is omitted
##
## @Stdout Query and warnings
## @Stdin y/n
## Triggers an event and performs necessary actions. Argument 2 is 
## optional. If omitted, the value of SPELL will be used.
##
#---------------------------------------------------------------------
function trigger ()
{ 
  debug "libtriggers" "trigger - $*"

  local spell TRIGGER action
  action=$1
  spell=`esc_str ${SPELL:-$4}`

  [ -f $TRIGGER_LIST ] || return 0
  iterate do_trigger $'\n' "`grep "^[^:]*:$spell:on_$action" $TRIGGER_LIST`"
}

#---------------------------------------------------------------------
## Get the triggerees of a given spell event and action
#---------------------------------------------------------------------
function get_triggerees() {
  local spell=$1
  local event=$2
  local each
  # get all the cast/check_self triggers
  [ -f $TRIGGER_LIST ] || return 0
  for each in $3 ; do
    grep "[^:]*:$spell:$event:$each" $TRIGGER_LIST|cut -f1 -d:
  done|sort|uniq|grep -v '^$'
}

#---------------------------------------------------------------------
## Get the run_script triggers from $spell on $target when theres a
## $action
#---------------------------------------------------------------------
function get_run_script_triggers() {
  local spell=$1
  local event=$2
  local target=$3
  grep "$target:$spell:$event:run_script" $TRIGGER_LIST|cut -f4 -d:
}

#---------------------------------------------------------------------
## @param event
## @param causing-spell
## @param action
## @param subject-spell
## Registers a trigger in the list of triggers. Also verifies that 
## the trigger and action exist.
##
#---------------------------------------------------------------------
function set_trigger ()
{ #1==trigger to set, $2==spell that triggers it, $3=action, $4==(optional)spell this is for

  debug "libtriggers" "set_trigger - $*"

  local str spell
  [[ $4 ]] || [[ $SPELL ]] || return 1
  case $3 in
    cast_self|dispel_self|check_self|run_script*)
      ;;
    *)
      message "${PROBLEM_COLOR}$3 is not a valid trigger action.${DEFAULT_COLOR}"
      return 1
      ;;
  esac
  case $1 in
    on_cast|on_pre_cast|on_dispel|on_pre_dispel)
      ;;
    *)
      message "${PROBLEM_COLOR}$1 is not a valid trigger.${DEFAULT_COLOR}"
      return 1
      ;;
  esac
  #perhaps a check to make sure that $2 exists?
  
  spell=${SPELL:-$4}
  str="$spell:$2:$1:$3"
  
  lock_file $TRIGGER_LIST
  if ! test -f $TRIGGER_LIST || ! grep -q "$str" $TRIGGER_LIST ; then
    echo "$str" >> $TRIGGER_LIST
  fi
  unlock_file $TRIGGER_LIST
}

#---------------------------------------------------------------------
## @Type API
## @param spell that triggers
## @param action
##
## Used by spells to make adding triggerse nice.
##
#---------------------------------------------------------------------
function real_on_cast () {
  set_trigger "on_cast" "$1" "$2"
}

#---------------------------------------------------------------------
## @Type API
## @param spell that triggers
## @param action
##
## Used by spells to make adding triggers nice.
##
#---------------------------------------------------------------------
function real_on_dispel () {
  set_trigger "on_dispel" "$1" "$2"
}

#---------------------------------------------------------------------
## @Type API
## @param spell that triggers
## @param action
##
## Used by spells to make adding triggerse nice.
##
#---------------------------------------------------------------------
function real_on_pre_dispel () {
  set_trigger "on_pre_dispel" "$1" "$2"
}


function do_trigger () {
  TRIGGER=()
  explode "$1" ":" TRIGGER
  local DC="$DEFAULT_COLOR"
  message "${SPELL_COLOR}${TRIGGER[1]}${DC}${QUERY_COLOR}" \
          "being $action has triggered a" \
          "\"${DC}${FILE_COLOR}${TRIGGER[3]}${DC}${QUERY_COLOR}\"" \
          "on spell ${DC}${SPELL_COLOR}${TRIGGER[0]}${DC}."
  query "Proceed? " "y"
  [[ $? != 0 ]] && return

  (
    unset CAST_PASS D_LOG
    function run_script() { eval $@ ; }
    #Ok, now do the required action:
    case ${TRIGGER[3]} in
      cast_self)
        cast -c "${TRIGGER[0]}"
        ;;
      dispel_self)
        dispel "${TRIGGER[0]}"
        ;;
      check_self)
        cleanse --nofix_quick "${TRIGGER[0]}" ||
        cast -c "${TRIGGER[0]}"
        ;;
      run_script*)
        eval "${TRIGGER[3]}"
        ;;
      *) message "${PROBLEM_COLOR}${TRIGGER[3]} is not" \
                 "a known kind of trigger.${DEFAULT_COLOR}"
    esac
  )
}
