####################################################
# by wiebe @ QuakeNet
#
# can use chase.tcl when available
####################################################

####################################################
# voice:help:pubm
####################################################
bind pubm vlomn|vlomn "% ${botnet-nick} help voice" voice:help:pubm
proc voice:help:pubm { n u h c t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "voice: usage voice \[<chan> .. <chan>\]"
  lappend o "voice: voices you on the current or given channels"
  lappend o "voice: usage voice \[<chan>\] <nick> \[<nick> .. <nick>\]"
  lappend o "voice: voices users on the current or given channel"
  lappend o "voice: usage voice \[<chan>\] -host <nick!user@host>"
  lappend o "voice: voices users matching mask on the current or given channel"
  lappend o "voice: usage voice \[<chan>\] -flag \[<globalflags>\[&|<chanflags>\]\]"
  lappend o "voice: voices users with matching flags on the current or given channel"
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "voice: " } }
  putloglev c $c "help: $n $u $h $c voice"
  return 1
}


####################################################
# voice:help:msgm
####################################################
bind msgm vlomn|vlomn "help voice" voice:help:msgm
proc voice:help:msgm { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "voice: usage voice \[<chan> .. <chan>\]"
  lappend o "voice: voices you on all or the given channels"
  lappend o "voice: usage voice <chan> <nick> \[<nick> .. <nick>\]"
  lappend o "voice: voices users on the given channel"
  lappend o "voice: usage voice <chan> -host <nick!user@host>"
  lappend o "voice: voices users matching mask on the given channel"
  lappend o "voice: usage voice <chan> -flag \[<globalflags>\[&|<chanflags>\]\]"
  lappend o "voice: voices users with matching flags on the given channel"
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "voice: " } }
  putcmdlog "($n!$u) !$h! help voice"
  return 1
}


####################################################
# voice:pubm
####################################################
bind pubm vlomn|vlomn "% ${botnet-nick} voice" voice:pubm
bind pubm vlomn|vlomn "% ${botnet-nick} voice *" voice:pubm
proc voice:pubm { n u h c t } {
  if {![validchan $c]} { return 0 }
  if {[matchattr $h bkZ]} { return 0 }
  set t [join [lrange [split $t] 2 end]]
  set o [voice:voice $h $t $n $c]
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "voice: " } }
  putloglev c $c "voice: $n $u $h $c $t"
  return 1
}


####################################################
# voice:msg
####################################################
bind msg vlomn|vlomn voice voice:msg
proc voice:msg { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  set o [voice:voice $h $t $n]
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "voice: " } }
  return 1
}


####################################################
# voice:dcc
####################################################
bind dcc -|- voice2 voice:dcc
proc voice:dcc { h i t } {
  set o [voice:voice $h $t]
  foreach l $o { putidx $i $l }
  return 1
}


####################################################
# voice:voice
####################################################
proc voice:voice { h t {n ""} {c ""} } {
  set t [split $t]
# pub
  if {![string equal $c ""]} {
    set v [lindex $t 0]
# voice user on chan $c 3
    if {[string equal $v ""]} {
      set o [voice:voice3 $h $n $c]
# voice host on chan $c 4
    } elseif {[string equal -nocase $v "-host"]} {
      set o [voice:voice4 $h $c [lrange $t 1 end]]
# voice flag on chan $c 5
    } elseif {[string equal -nocase $v "-flag"]} {
      set o [voice:voice5 $h $c [lrange $t 1 end]]
# change chan
    } elseif {[string match {[#&]*} $v]} {
      set c $v; set v [lindex $t 1]
# voice user on given chans 2
      if {[string equal $v ""] || [string match {[#&]*} $v]} {
        set o [voice:voice2 $h $t $n]
# voice host on chan $c 4
      } elseif {[string equal -nocase $v "-host"]} {
        set o [voice:voice4 $h $c [lrange $t 2 end]]
# voice flag on chan $c 5
      } elseif {[string equal -nocase $v "-flag"]} {
        set o [voice:voice5 $h $c [lrange $t 2 end]]
# voice users on chan $c 1
      } else { set o [voice:voice1 $h $c [lrange $t 1 end]] }
# voice users on chan $c 1
    } else { set o [voice:voice1 $h $c $t] }

# msg
  } elseif {![string equal $n ""]} {
    set c [lindex $t 0]; set v [lindex $t 1]
# voice user on all chans 3
    if {[string equal $c ""]} {
      set o [voice:voice3 $h $n]
# voice user on given chans 2
    } elseif {[string equal $v ""] || [string match {[#&]*} $v]} {
      set o [voice:voice2 $h $t $n]
# voice host on chan $c 4
    } elseif {[string equal -nocase $v "-host"]} {
      set o [voice:voice4 $h $c [lrange $t 2 end]]
# voice flag on chan $c 5
    } elseif {[string equal -nocase $v "-flag"]} {
      set o [voice:voice5 $h $c [lrange $t 2 end]]
# voice users on chan $c 1
    } else { set o [voice:voice1 $h $c [lrange $t 1 end]] }

# dcc
  } else {
    set c [lindex $t 0]; set v [lindex $t 1]
# voice handle on all chans 3
    if {[string equal $c ""]} {
      set o [voice:voice3 $h]
# voice handle on given chans 2
    } elseif {[string equal $v ""] || [string match {[#&]*} $v]} {
      set o [voice:voice2 $h $t]
# voice host on chan $c 4
    } elseif {[string equal -nocase $v "-host"]} {
      set o [voice:voice4 $h $c [lrange $t 2 end]]
# voice flag on chan $c 5
    } elseif {[string equal -nocase $v "-flag"]} {
      set o [voice:voice5 $h $c [lrange $t 2 end]]
# voice users on chan $c 1
    } else { set o [voice:voice1 $h $c [lrange $t 1 end]] }
  }
  return $o
}


####################################################
# voice:voice1 voice other users
####################################################
proc voice:voice1 { h c t } {
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  if {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
    lappend o "voice: no access or unknown channel $c"
  } elseif {![botonchan $c]} {
    lappend o "voice: unable to voice on $c (I am not there)"
  } elseif {![botisop $c] && ![botishalfop $c]} {
    lappend o "voice: unable to voice on $c (I am not opped)"
  } elseif {![matchattr $h mn|mn $c]} {
    set f ""; set s ""
    foreach n $t {
      if {![onchan $n $c]} {
        if {![string equal [info procs chase] ""]} { set d [chase $n] }
        if {![string equal $d ""]} { set n $d }
      }
      if {![onchan $n $c]} { lappend f "'$n not onchan'"; continue }
      if {[onchansplit $n $c]} { lappend f "'$n split'"; continue }
      if {[isvoice $n $c]} { lappend f "'$n is voice'"; continue }
      if {![string equal -nocase $h [nick2hand $n $c]]} { lappend f "'$n not you'"; continue }
      if {[matchattr $h q|q $c]} { lappend f "'$n deny voice'"; continue }
      pushmode $c +v $n; lappend s $n
    }
    if {![string equal $s ""]} { lappend o "voice: voiced on $c '[join $s "   "]'" }
    if {![string equal $f ""]} { lappend o "voice: failed to voice on $c [join $f "   "]" }
  } else {
    set f ""; set s ""
    foreach n $t {
      if {[string equal $n ""]} { continue }
      if {![onchan $n $c]} {
        if {![string equal [info procs chase] ""]} { set d [chase $n] }
        if {![string equal $d ""]} { set n $d }
      }
      if {![onchan $n $c]} { lappend f "'$n not onchan'"; continue }
      if {[onchansplit $n $c]} { lappend f "'$n split'"; continue }
      if {[isvoice $n $c]} { lappend f "'$n is voice'"; continue }
      set u [nick2hand $n $c]
      if {[matchattr $u Zkq|kq $c]} { lappend f "'$n deny voice'"; continue }
      pushmode $c +v $n; lappend s $n
    }
    if {![string equal $s ""]} { lappend o "voice: voiced on $c '[join $s "   "]'" }
    if {![string equal $f ""]} { lappend o "voice: failed to voice on $c [join $f "   "]" }
  }
  return $o
}


####################################################
# voice:voice2 voice user on given channels
####################################################
proc voice:voice2 { h t {n ""} } {
  set f ""; set s ""
  if {[string equal $n ""]} {
    foreach c $t {
      if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
      if {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
        lappend f "'$c no access'"; continue
      }
      if {![botonchan $c]} { lappend f "'$c I am not there'"; continue }
      if {![botisop $c] && ![botishalfop $c]} { lappend f "'$c I am not opped'"; continue }
      if {![handonchan $h $c]} { lappend f "'$c you are not there'"; continue }
      lappend s $c
      foreach n [chanlist $c] {
        if {![string equal -nocase $h [nick2hand $n $c]]} { continue }
        if {[onchansplit $n $c]} { continue }
        if {[isvoice $n $c]} { continue }
        pushmode $c +v $n
      }
    }
    if {![string equal $s ""]} { lappend o "voice: voiced you on '[join $s "   "]'" }
    if {![string equal $f ""]} { lappend o "voice: failed to voice you on [join $f "   "]" }
  } else {
    foreach c $t {
      if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
      if {[string equal $c ""]} { continue }
      if {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
        lappend f "'$c no access'"; continue
      }
      if {![botonchan $c]} { lappend f "'$c I am not there'"; continue }
      if {![botisop $c] && ![botishalfop $c]} { lappend f "'$c I am not opped'"; continue }
      set m [lindex [split [getchanmode $c]] 0]
      if {![onchan $n $c] || [onchansplit $n $c]} {
        if {[string match "*d*" $m]} { puthelp "MODE $c +v $n"; lappend s $c
        } else { lappend f "'$c you are not there'" }
        continue
      }
      pushmode $c +v $n; lappend s $c
    }
    if {![string equal $s ""]} { lappend o "voice: voiced you on [join $s "   "]" }
    if {![string equal $f ""]} { lappend o "voice: failed to voice you on [join $f "   "]" }
  }
  return $o
}


####################################################
# voice:voice3 voice user on all channels
####################################################
proc voice:voice3 { h {n ""} {c ""} } {
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  set o ""
# pub
  if {![string equal $c ""] && ![string equal $n ""]} {
    if {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
      lappend o "voice: no access or unknown channel $c"
    } elseif {![botonchan $c]} {
      lappend o "voice: unable to voice $c (I am not there)"
    } elseif {![botisop $c] && ![botishalfop $c]} {
      lappend o "voice: unable to voice $c (I am not opped)"
    } elseif {![onchan $n $c]} {
      lappend o "voice: unable to voice $c (you are not there)"
    } elseif {[onchansplit $n $c]} {
      lappend o "voice: unable to voice $c (you are split)"
    } elseif {[isvoice $n $c]} {
      lappend o "voice: unable to voice $c (you are voiced)"
    } else { pushmode $c +v $n }
# msg
  } elseif {![string equal $n ""]} {
    set s ""
    foreach c [channels] {
      if {![botisop $c] && ![botishalfop $c]} { continue }
      if {[isvoice $n $c]} { continue }
      if {![onchan $n $c]} { continue }
      if {[onchansplit $n $c]} { continue }
      if {![matchattr $h vlomn|vlomn $c]} { continue }
      if {[matchattr $h Zkq|kq $c]} { continue }
      pushmode $c +v $n; lappend s $c
    }
    if {[string equal $s ""]} { lappend o "voice: no channels found to voice you on"
    } else { lappend o "voice: voiced you on [join $s "   "]" }
# dcc
  } else {
    set s ""
    foreach c [channels] {
      if {![botisop $c] && ![botishalfop $c]} { continue }
      if {![handonchan $h $c]} { continue }
      if {![matchattr $h vlomn|vlomn $c]} { continue }
      if {[matchattr $h Zkq|kq $c]} { continue }
      lappend s $c
      foreach n [chanlist $c] {
        if {![string equal -nocase $h [nick2hand $n $c]]} { continue }
        if {[isvoice $n $c]} { continue }
        if {[onchansplit $n $c]} { continue }
        pushmode $c +v $n
      }
    }
    if {[string equal $s ""]} { lappend o "voice: no channels found to voice you on"
    } else { lappend o "voice: voiced you on [join $s "   "]" }
  }
  return $o
}


####################################################
# voice:voice4 voice host t on c
####################################################
# 4 t = #chan -host mask (voice users matching mask on given chan)
proc voice:voice4 { h c t } {
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  set m [lindex $t 0]; set z 0; regsub -all {[][\\]} $m {\\\0} m
  if {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
    lappend o "voice: no access or unknown channel $c"
  } elseif {![botonchan $c]} {
    lappend o "voice: unable to voice on $c (I am not there)"
  } elseif {![botisop $c] && ![botishalfop $c]} {
    lappend o "voice: unable to voice on $c (I am not opped)"
  } elseif {![matchattr $h mn|mn $c]} {
    lappend o "voice: need to be master or owner to voice based on host"
  } elseif {[string equal $m ""]} {
    lappend o "voice: usage -host <nick!user@host>"
  } else {
    foreach n [chanlist $c] {
      if {[isvoice $n $c]} { continue }
      if {[onchansplit $n $c]} { continue }
      if {![string match -nocase $m $n![getchanhost $n $c]]} { continue }
      set u [nick2hand $n $c]
      if {[matchattr $u qk|qk $c]} { continue }
      pushmode $c +v $n; incr z
    }
    set m [lindex $t 0]
    if {!$z} {
      lappend o "voice: no users to voice matching '$m' on $c with at least +f"
    } else { lappend o "voice: voiced $z users matching '$m' on $c with at least +f" }
  }
  return $o
}


####################################################
# voice:voice5 voice flag t on c
####################################################
# 5 t -|- (voice user with the given flags)
proc voice:voice5 { h c t } {
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  set x [lindex $t 0]; set z 0
  if {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
    lappend o "voice: no access or unknown channel $c"
  } elseif {![botonchan $c]} {
    lappend o "voice: unable to voice on $c (I am not there)"
  } elseif {![botisop $c] && ![botishalfop $c]} {
    lappend o "voice: unable to voice on $c (I am not opped)"
  } elseif {![matchattr $h mn|mn $c]} {
    lappend o "voice: need to be master or owner to voice based on flags"
  } elseif {[string equal $x ""]} {
    lappend o "voice: usage -flag \[<globalflags>\[&|<chanflags>\]\]"
    lappend o "voice: match users the given flags, the & means AND, the | means OR, - and + can also be used."
  } else {
    foreach n [chanlist $c $x] {
      if {[isvoice $n $c]} { continue }
      if {[onchansplit $n $c]} { continue }
      set u [nick2hand $n $c]
      if {[matchattr $u qk|qk $c]} { continue }
      pushmode $c +v $n; incr z
    }
    if {!$z} {
      lappend o "voice: no users to voice with flags matching '$x' on $c"
    } else { lappend o "voice: voiced $z users with flags matching '$x' on $c" }
  }
  return $o
}


set scriptdb(voice) {
  "provides voice command"
}

