# All these aliases take commands as arguments and have the property that
# they will not exand those commands prior to execution, making them safe.
#
# This may require some explanation:
#
# The ircii language has the concept of "expansion", whereby variable
# references are replaced with the variable values and escaped characters
# are unescaped.  This is one of the side effects of an eval.  In the
# following two commands, if entered from the command line, the first will
# whois the nick "\\`anderer", and the second will whois "\`anderer",
# because the eval will unescape it.
#
#  /whois \\`anderer
#  /eval whois \\`anderer
#
# This is from the command line.  If these commands are executed from an
# alias, the first command will whois "\`anderer", and the second will
# whois "`anderer".  This is because commands within an alias are always
# expanded prior to execution.  There is no way to stop this, but you can
# control it by passing a variable to the whois command instead of the raw
# text.  Since expansion only occurs once, the variables expansion will
# "shelter" the text from being expanded.
#
# If you wish to add more levels of expansion, you use more evals.  If you
# wish to have _no_ expansion, you keep all your text in variables, and
# avoid using eval.
#
# It is easy to see that there may be occasions where you may want to whois
# someone from within a hook without having to worry about expansion.  This
# is easy enough.  /whois does not expand its arguments, however, hooks can
# generate floods, so you put the whois in a timer say.  The problem with
# this is that /timer _does_ expand its arguments, so you end up with an
# extra level of expansion to deal with.
#
# These aliases solve these problems.  Commands are given as arguments and
# are normally not expanded, just as if they had been given to a built in
# command.  If you wish to have them expanded when they are run, precede
# them with /eval, or use a /timer or a /queue instead.

package qcmd

#
# Usage:
#  scmd [server [command]]
#
# Execute command on server _without_ expanding command.
#
alias scmd xeval -s $0 {$1-}

#
# Usage:
#  1cmd [time [command]]
#
# command will not be executed if the same command has been executed in
# the last time seconds.
#
alias 1cmd {
	@ :foo = encode($tolower($1-))
	@ :eserv = encode($tolower($servername()))
	if (time() - last[1cmd][$eserv][$foo] >= [$0]) {
		@ last[1cmd][$eserv][$foo] = time()
		$1-
	}
	if ((!rand(10)) && time() != last[1cmd][$eserv]) {
		@ last[1cmd][$eserv] = time()
		foreach last[1cmd][$eserv] bar {
			if (last[1cmd][$eserv][$bar] < time()) {
				@ last[1cmd][$eserv][$bar] = []
			}
		}
	}
}

#
# Usage:
#  qcmd [queue [command]]
#  fqcmd [queue [command]]
#
# Queue command, and schedule a timer for later execution.  Prevents flooding.
# fqcmd adds the command to the beginning of the queue instead of the end.
#
#  q1cmd [time [queue [command]]]
#  fq1cmd [time [queue [command]]]
#
# The same as "1cmd {time} qcmd {queue} {command}", only, the command also
# won't be scheduled if the same command is already scheduled.
#
fe (q push fq unshift) cmd op {
	alias ${cmd}1cmd unless (match("$2-" $qcmd[$servernum()][$1]))\{1cmd \$0 ${cmd}cmd \$1-\}
	alias ${cmd}cmd {
		if (servernum() < 0) {
			$1-
		} elsif (1 < #) {
			@ :bar = [$1-]
			@ ${op}(qcmd.${servernum()}.$0 \"$msar(gr/\\/\\\\/\"/\\\"/bar)\")
			^timer -ref qcmd.$servernum() 5 qcmd
		} else {
			if (isconnected()) {
				@ :foo = []
				if (1 == #) {
					@ foo = [$0]
				} elsif (0 == #) {
					foreach qcmd[$servernum()] bar {
						@ foo = bar
						break
					}
				}
				if (@foo) {
					^timer -ref qcmd.$servernum() 5 qcmd
					@ :bar = shift(qcmd[$servernum()][$foo])
					$msar(gr/\\\\/\\/\\\"/\"/bar)
				}
			}
		}
	}
	@ aliasctl(alias set ${cmd}cmd $sar(g/\${op}/${op}/$aliasctl(alias get ${cmd}cmd)))
}
