alias away if (!#) { back } {
    xme is away -- $0- -- messages will be saved.
    Light.setAway 0 $S $0-
}

alias back {
    if (#) { xme $0- } { xme $LIGHT.Msgs.back }
    Light.setBack $S
}

alias aaway if (!#) { aback } {
    ame is away -- $0- -- messages will be saved.
    Light.setAway 0 * $0-
}

alias aback {
    if (#) { ame $0- } { ame $LIGHT.Msgs.back }
    Light.setBack *
}

alias quietaway if (!#) { quietback } {
    Light.setAway 0 $S $0-
}

alias quietback {
    Light.setBack $S
}

alias aquietaway if (!#) { aquietback } {
    Light.setAway 0 * $0-
}

alias aquietback {
    Light.setBack *
}

alias showmessages if (1 == fexist($LIGHT.Data.away.log.name)) {
    @:fd = open($LIGHT.Data.away.log.name r)
    if ([] == fd) {
        lecho ! An error occured while trying to open the saved message log.
        return
    }

    @:out = getset(OUTPUT_REWRITE)
    ^set -output_rewrite

    lecho A Saved message log:
    @:line = read($fd)
    while (!eof($fd)) {
        xecho -- $line
        @:line = read($fd)
    }
    @close($fd)

    unless ([] == out) {
        ^set output_rewrite $out
    }
} {
    lecho A No saved messages to show.
}

alias clearmessages {
    ^set -status_user2
    if (!LIGHT.Data.away.log.name) { return }

    Light.closeLog
    @unlink($LIGHT.Data.away.log.name)
    Light.purge LIGHT.Data.away.log
    Light.awayClean

    foreach LIGHT.Data.away.servers xx {
        Light.recordAway $key
    }
    if ([] == LIGHT.Data.away.log.fd) { Light.purge LIGHT.Data.away.log }
}

alias Light.openLog (void) {
    if ([] != LIGHT.Data.away.log.fd) { return }
    @LIGHT.Data.away.log.name  = [~/.Light/messages.$pid()]
    @LIGHT.Data.away.log.fd    = open($LIGHT.Data.away.log.name w)
    @LIGHT.Data.away.log.count = 0
}

alias Light.closeLog (void) {
    @close($LIGHT.Data.away.log.fd)
    ^assign -LIGHT.Data.away.log.fd
}

alias Light.writeToLog (what) {
    if ([] == LIGHT.Data.away.log.fd) { return }

    @write($LIGHT.Data.away.log.fd $what)
    @LIGHT.Data.away.log.count++
    if (LIGHT.Data.away.log.count > 0) {
        ^set status_user2  [Saved: $LIGHT.Data.away.log.count]
    }
}

alias Light.recordAway (key) {
    Light.openLog
    @LIGHT.Data.away.log.count--
    Light.writeToLog >> set away at $LIGHT.Data.away.servers[$key][time] on $LIGHT.Data.away.servers[$key][name] - $LIGHT.Data.away.servers[$key][reason] <<
}

alias Light.setAway (auto, serv, reason) if ([*] == serv) {
    fe ($myservers()) xx {
        Light.setAway $auto $xx $reason
    }
} {
    @:key = lencode($serv)
    if (auto && [] != LIGHT.Data.away.servers[$key].name && !LIGHT.Data.away.servers[$key].auto) { return }
    ^//xeval -server $servernum($serv) { ^//away $reason }
    @LIGHT.Data.away.servers[$key].auto   = auto
    @LIGHT.Data.away.servers[$key].name   = serv
    @LIGHT.Data.away.servers[$key].time   = Z
    @LIGHT.Data.away.servers[$key].reason = reason
    Light.recordAway $key
}

alias Light.setBack (serv) {
    ^//away -all
    Light.purge LIGHT.Data.away.servers
    showmessages
    if (LIGHT.Data.away.log.count) {
        input "Clear saved messages? \[y/N\] " {
            if ([y] == [$0]) { clearmessages }
        }
    } { clearmessages }
}

alias Light.autoAway if ([] != LIGHT.Msgs.aaway) {
	@LIGHT.Data.away.auto = 1
	Light.setAway 1 * $LIGHT.Msgs.aaway
}

alias Light.tryAutoBack (wrd, target) {
	if (!LIGHT.Data.away.auto) { return }
	if ([] == wrd) { return }
	if (rmatch($wrd /desc /descr /descri /describ /describe /m /ms /msg /notic /notice)) {
		if (left(1 $target) == [=]) { return }
	} elsif (rmatch($wrd / /me /say /ame /asay)) {
		if (left(1 $Q) == [=]) { return }
	} elsif (left(1 $wrd) == [/]) { return }
	if (left(1 $Q) == [=]) { return }
	^assign -LIGHT.Data.away.auto
	if (isconnected()) {
		@:key = lencode($S)
		if ([] != LIGHT.Data.away.servers[$key].name && LIGHT.Data.away.servers[$key].auto) { defer LIGHT.setBack $S }
	}
}

alias Light.awayClean (skey) {
	^local auto,notauto 0
	if (skey) { Light.purge LIGHT.Data.away.servers.$skey }
	foreach LIGHT.Data.away.servers key {
		if (LIGHT.Data.away.servers[$key].auto) {
			if (!isconnected($servernum($decode($key)))) {
				@serverctl(set $servernum($decode($key)) away)
				Light.purge LIGHT.Data.away.servers.$key
			} { @:auto++ }
		} { @:notauto++ }
	}
	unless (auto || notauto) {
		Light.closeLog
		Light.purge LIGHT.Data.away.servers
	}
}

alias Light.forgetAutoAway (serv) {
	@:key = lencode($serv)
	if ([] == LIGHT.Data.away.servers[$key].name || !LIGHT.Data.away.servers[$key].auto) { return }
	Light.writeToLog >> disconnected from $LIGHT.Data.away.servers[$key][name] at $Z <<
	Light.purge LIGHT.Data.away.servers.$key
	@serverctl(set $servernum($serv) away)
}

alias Light.checkNewServerAutoAway (serv) {
	Light.awayClean
	if (LIGHT.Data.away.auto && [] != LIGHT.Msgs.aaway) {
		Light.setAway 1 $serv $LIGHT.Msgs.aaway
	}
}

alias Light.checkIncomingAway (serv) {
	if ([] == LIGHT.Data.away.servers[$lencode($serv)].name) {
		push ::LIGHT.Data.away.suppress $serv
		^//xeval -server $servernum($serv) ^//away
		return 0
	} {
		return 1
	}
}

alias Light.isAway (serv) {
	if ([] == serv) { return ${!!aliasctl(assign pmatch LIGHT.Data.away.servers.*)} }
	if (isnumber($serv)) { @:serv = servername($serv) }
	@function_return = !!LIGHT.Data.away.servers[$lencode($serv)].name
}

alias Light.awayExitCleanup if ([] != LIGHT.Data.away.log.fd) {
	Light.closeLog
	if (!LIGHT.Data.away.log.count) { @unlink($LIGHT.Data.away.log.name) }
}

