@ ms.mpl = 4

alias ychannel {@ function_return = filter(?$N $channel($*))}

alias mv mass voice
alias mop mass op
alias mdeop mass deop
alias mdop mass deop
alias mreop mass reop
alias reop mass reop
alias mub mass unban
alias munban mass unban
alias lk mass kick
alias mlk mass kick
alias mknu mass kick
alias mka mass kick -a
alias mdv mass dv

^on ^set "max_wallnicks *" {
  if (![$1]) {
    echo $fparse(format_set max_wallnicks $(max_wallnicks))} else {
    ^assign max_wallnicks $1}}

^set max_wallnicks 8

alias wall wallmsg
alias wallmsg {
  ^local w.
  @ w.c = ([$0] =~ [#*] || [$0] =~ [&*]) ? [$0] : C
  @ w.u = strip(@*+. $pattern(*@* $ychannel($w.c)))
  @ w.ua = strip(@*+. $ychannel($w.c))
  @ w.x = common($split(, $after(- $pattern(-* $beforew($leftw(1 $filter(-* $*))) $*))) / $w.ua)
  @ w.a = common($split(, $after(+ $pattern(+* $beforew($leftw(1 $filter(+* $*))) $*))) / $w.ua)
  @ w.m = remw(-$w.x $remw(+$w.a ${ischannel($0) ? [$1-] : [$*]}))
  if (w.m =~ [%: *]) {
    @ w.nc = _compnick($before(1 : $w.m))
    @ w.m = leftw(1 $w.nc) ? stripansicodes($fparse(format_nick_comp $rightw(${#w.nc-1} $w.nc)  $rightw(${#w.m-1} $w.m))) : w.m}
  @ w.u = diff($w.x / $w.u) ## (w.a ? [ $w.a] :)
  @ w.z = 0
  fe ($w.u) w.i {
    @ w.z++
    @ w.q = w.q ? w.q ## [,$w.i] : w.i
    if (w.z == max_wallnicks) {
      push w.s NOTICE $w.q \:[wall/$(w.c)] $(w.m)
      @ w.q = w.z = []}}
  @ w.q ? push(w.s NOTICE $w.q \:[wall/$(w.c)] $(w.m)) :
  ^hook ra w $N $tolower($Z) $w.c $N ! $w.m
  ^addtab /wall $C${w.x ? [ -$(w.x)]:}
  echo $fparse(format_bwall $tolower($Z) $w.c $N ! $w.m)
  ^quote $w.s}

alias gmode {
  ^local g.
  fe ($3-) g.n {
    @ push(g.nx $g.n)
    if (#g.nx == ms.mpl) {
      @ setitem(gm $numitems(gm) $1$repeat($#g.nx $2) $g.nx)
      @ g.nx = []}}
  if (g.nx) {@ setitem(gm $numitems(gm) $1$repeat($#g.nx $2) $g.nx)}
  for (@ g.c = 0, g.c < numitems(gm), @ g.c++) {
     @ g.str #= [mode $0 ] ## getitem(gm $g.c) ## [
]
  }
  quote $g.str
  @ delarray(gm)}

alias mass {
  ^local m.
  switch ($0) {
    (o) (-o) (op) {
      @ m.c = [$1] ? [$1] : C
      if (common($m.c / $mychannels())) {
        ge mass-opping users on $(m.c)...
        @ m.u = strip(.+*@ $filter(*@* $ychannel($m.c)))
        ^gmode $m.c + o $m.u} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl)}}
    (d) (do) (-d) (-do) (deop) {
      @ m.c = [$1] ? [$1] : C
      if (common($m.c / $mychannels())) {
        ge mass-deopping users on $(m.c)\; use /mass reop to re-op.
        @ delarray(usr.$m.c)
        @ setitem(usr.$m.c 0 $strip(.+*@ $pattern(*@* $ychannel($m.c))))
        ^gmode $m.c - o $getitem(usr.$m.c 0)} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl)}}
    (v) (-v) (voice) {
      @ m.c = [$1] ? [$1] : C
      if (common($m.c / $mychannels())) {
        ge mass-voicing users on $(m.c)...
        @ m.u = strip(.+*@ $pattern(*.* $ychannel($m.c)))
        ^gmode $m.c + v $m.u} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl)}}
    (dv) (-dv) (devoice) {
      @ m.c = [$1] ? [$1] : C
      if (common($m.c / $mychannels())) {
        ge mass-devoicing users on $(m.c)...
        @ m.u = strip(.+*@ $pattern(*+* $ychannel($m.c)))
        ^gmode $m.c - v $m.u} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl)}}
    (i) (-i) (invite) {
      @ m.cspec = leftw(2 $pattern(#* $1-))
      @ m.c = #m.cspec == 1 ? m.cspec : leftw(1 $m.cspec)
      @ m.ic = #m.cspec == 1 ? C : rightw(1 $m.cspec)
      if (common($m.ic / $mychannels())) {
        @ m.f = leftw(1 $pattern(-* $filter(#* $1-)))
        switch ($m.f) {
          (-o) {@ m.u = strip(.+*@ $pattern(*@* $ychannel($m.c)))}
          (-n) {@ m.u = strip(.+*@ $filter(*@* $ychannel($m.c)))}
          (*)  {@ m.u = strip(.+*@ $ychannel($m.c))}}
        fe ($m.u) m.ii { 
          wait for {invite $m.ii $m.ic}}} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl)}}
    (r) (ro) (-r) (-ro) (reop) {
      @ m.c = [$1] ? [$1] : C
      if (common($m.c / $mychannels())) {
        if (getitem(usr.$m.c 0)) {
          ge reopping mass-deopped users on $(m.c)...
          ^gmode $m.c + o $getitem(usr.$m.c 0)
          @ delarray(usr.$m.c)} else {
          ge error: no memorized mass deop!}} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl)}}
    (k) (lk) (-k) (-lk) (kick) {
      @ m.c = pattern(#* $*) ? pattern(#* $*) : C
      @ m.ka = match(-a $*) : 1 : 0
      if (common($m.c / $mychannels())) {
        if (m.ka) {
          ge kicking all users off $(m.c)...
          @ m.u = strip(.+*@ $ychannel($m.c))
          fe ($m.u) m.n {
            kick $m.c $m.n $filter(#* $1-)}} else {
          ge kicking non-verified users from $(m.c)...
          @ m.u = strip(.+*@ $pattern(*.* $ychannel($m.c)))
          fe ($m.u) m.n {
            kick $m.c $m.n $filter(#* $1-)}}} else {
        ge error: you are not on that channel. $(c.hk)\($(c.lc)$m.c$(c.hk)\)$(cl).}}
    (ub) (-ub) (unban) {
      @ m.c = [$1] ? [$1] : C
      if (common($m.c / $mychannels())) {
        ge removing all bans from $(m.c)...
        unban $m.c}}
    (*) {ausage mass}}}
