####################################################
# by wiebe @ QuakeNet
#
####################################################

# broadcast [<chan>] c <target> <msg> [<hash>]
# broadcast [<chan>] f <flags> <msg> [<hash>]
# broadcast [<chan>] m <mask> <msg> [<hash>]

####################################################
# broadcast:help:msg
####################################################
bind msgm mn|mn "help broadcast" broadcast:help:msgm
proc broadcast:help:msgm { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
  lappend o "broadcast: broadcasts a message to a channel, users with matching flags or nicks matching mask"
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "broadcast: " } }
  putcmdlog "($n!$u) !$h! help broadcast"
  return 1
}


####################################################
# broadcast:msg
####################################################
bind msg mn|mn broadcast broadcast:msg
proc broadcast:msg { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  if {[string equal $t ""]} {
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
  } else { set o [broadcast:broadcast $h $t] }
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "broadcast: " } }
  return 1
}


####################################################
# broadcast:dcc
####################################################
bind dcc -|- broadcast broadcast:dcc
proc broadcast:dcc { h i t } {
  if {[string equal $t ""]} {
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
    lappend o "broadcast: broadcasts a message to a channel, users with matching flags or nicks matching mask"
  } else { set o [broadcast:broadcast $h $t] }
  foreach l $o { putidx $i $l }
  return 1
}


####################################################
# broadcast:broadcast
####################################################
proc broadcast:broadcast { h t } {
# broadcast [@+][<chan>] [c @+_][f <flags>][m <mask>] <msg> [<hash>]
  set t [split $t]; set c [lindex $t 0]
  if {[string match -nocase {[cfm]} $c]} {
    set y [string tolower $c]; set c ""; set m [lindex $t 1]; set s [lrange $t 2 end]
  } elseif {![string equal $c ""]} {
    set y [string tolower [lindex $t 1]]; set m [lindex $t 2]; set s [lrange $t 3 end]
  }
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  set x [lindex $s end]; set z [string range [md5 "$h$c$y$m[join [lrange $s 0 end-1]]"] 0 5]
  if {[string equal $x $z]} { set s [join [lrange $s 0 end-1]]
  } else { set s [join $s]; set z [string range [md5 "$h$c$y$m$s"] 0 5] }
# nothing
  if {[string equal $c ""] && [string equal $y ""]} {
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
# no type
  } elseif {[string equal $y ""]} {
    lappend o "broadcast: no type specified"
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
# invalid type
  } elseif {![string match {[cmf]} $y]} {
    lappend o "broadcast: invalid type specified (must be c, f or m)"
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
# no chan, cant do global
  } elseif {[string equal $c ""] && ![matchattr $h mn]} {
    lappend o "broadcast: no access for global broadcast"
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
# unknown chan or no access
  } elseif {![string equal $c ""] && (![validchan $c] || ![matchattr $h mn|mn])} {
    lappend o "broadcast: no access or unknown channel $c"
    lappend o "broadcast: usage broadcast \[<chan>\] \[c <target>\]\[f <flags>\]\[m <mask>\] <message>"
# not on chan
  } elseif {![string equal $c ""] && ![botonchan $c]} {
    lappend o "broadcast: I am not on channel $c"
# not opped chan
  } elseif {![string equal $c ""] && ![botisop $c] && ![botishalfop $c]} {
    lappend o "broadcast: I am not opped on channel $c"
# no target
  } elseif {[string equal $y "c"] && [string equal $m ""]} {
    lappend o "broadcast: no target specified (@ for ops, + for ops & voices, _ for all)"
    lappend o "broadcast: usage broadcast \[<chan>\] c <target> <message>"
# invalid status
  } elseif {[string equal $y "c"] && ![string match {[@+_]} $m]} {
    lappend o "broadcast: invalid status specified (@ for ops, + for ops & voices, _ for all)"
    lappend o "broadcast: usage broadcast \[<chan>\] c <target> <message>"
# no flags
  } elseif {[string equal $y "f"] && [string equal $m ""]} {
    lappend o "broadcast: no flags specified"
    lappend o "broadcast: usage broadcast \[<chan>\] f <flags> <message>"
# invalid flags
  } elseif {[string equal $y "f"] && ![regexp {^([a-zA-Z\-])+(([|&])?([a-zA-Z\-])+)?$} $m]} {
    lappend o "broadcast: invalid flags specified (\[\[globalflags\]\{&/|\}\[chanflags\])"
    lappend o "broadcast: usage broadcast \[<chan>\] f <flags> <message>"
# no mask
  } elseif {[string equal $y "m"] && [string equal $m ""]} {
    lappend o "broadcast: no mask specified (nick!user@host format)"
    lappend o "broadcast: usage broadcast \[<chan>\] m <mask> <message>"
# no message
  } elseif {[string equal $s ""]} {
    lappend o "broadcast: no message specified"
    if {[string equal $c ""]} { lappend o "broadcast: usage broadcast $y $m <message>"
    } else { lappend o "broadcast: usage broadcast $c $y $m <message>" }
# md5
  } elseif {![string equal $x $z]} {
    if {[string equal $c ""]} {
      lappend o "broadcast: WARNING! this will broadcast to $m, to confirm this use:"
      lappend o "broadcast: to confirm this, use broadcast $y $m $s $z"
    } else {
      lappend o "broadcast: WARNING! this will broadcast to $m on $c, to confirm this use:"
      lappend o "broadcast: broadcast $c $y $m $s $z"
    }
# c broadcast
  } elseif {[string equal $y "c"]} {
    set s "(cBroadcast) $s"; set d [lindex [split [getchanmode $c]] 0]; set w "puthelp"
    if {[string match "*N*" $d]} { set w "putquick"; $w "MODE $c -N" }
    if {[string equal $m "_"]} {
      if {[string equal [info procs notice] ""]} { $w "NOTICE $c :$s"
      } else { notice $c $s $w "" }
    } elseif {[string equal $m "+"]} {
      if {[string equal [info procs wallvoices] ""]} { $w "WALLVOICES $c :$s"
      } else { wallvoices $c $s $w "" }
    } elseif {[string equal $m "@"]} {
      if {[string equal [info procs wallchops] ""]} { $w "NOTICE @$c :$s"
      } else { wallchops $c $s $w "" }
    }
    if {[string match "*N*" $d]} { $w "MODE $c +N" }
    if {[string equal $m "@"]} { set c "@$c" } elseif {[string equal $m "+"]} { set c "+$c" }
    lappend o "broadcast: message broadcasted to $c"
# f broadcast
  } elseif {[string equal $y "f"]} {
    set s "(fBroadcast) $s"; set n ""
    if {![string equal $c ""]} {
      foreach e [chanlist $c $m] {
        if {[onchansplit $e $c]} { continue }
        if {[isbotnick $e]} { continue }
        lappend n $e
      }
      set n [join $n ,]
      if {![string equal $n ""]} {
        if {[string equal [info procs notice] ""]} { puthelp "NOTICE $n :$s"
        } else { notice $n $s puthelp "" }
        lappend o "broadcast: message broadcasted to $m users on $c"
      } else { lappend o "broadcast: no users found with $m flags on $c" }
    } else {
      set u [userlist $m]
      if {[llength $u] > 0} {
        foreach c [channels] {
          if {![botisop $c] && ![botishalfop $c]} { continue }
          foreach e [chanlist $c] {
            if {[onchansplit $e $c]} { continue }
            if {[isbotnick $e]} { continue }
            if {[string equal [lsearch -exact $u [nick2hand $e $c]] "-1"]} { continue }
            if {[string equal [lsearch -exact $n $e] "-1"]} { lappend n $e }
          }
        }
        set n [join $n ,]
        if {![string equal $n ""]} {
          if {[string equal [info procs notice] ""]} { puthelp "NOTICE $n :$s"
          } else { notice $n $s puthelp "" }
          lappend o "broadcast: message broadcasted to $m users"
        } else { lappend o "broadcast: no users found with $m flags" }
      } else { lappend o "broadcast: no users found with $m flags" }
    }
# m broadcast
  } elseif {[string equal $y "m"]} {
    set s "(mBroadcast) $s"; set n ""
    regsub -all {[][\\]} $m {\\\0} b
    if {![string equal $c ""]} {
      foreach e [chanlist $c] {
        if {[onchansplit $e $c]} { continue }
        if {[isbotnick $e]} { continue }
        if {![string match -nocase $b "$e![getchanhost $e $c]"]} { continue }
        lappend n $e
      }
      set n [join $n ,]
      if {![string equal $n ""]} {
        if {[string equal [info procs notice] ""]} { puthelp "NOTICE $n :$s"
        } else { notice $n $s puthelp "" }
        lappend o "broadcast: message broadcasted to $m on $c"
      } else { lappend o "broadcast: no users found matching $m on $c" }
    } else {
      foreach c [channels] {
        if {![botisop $c] && ![botishalfop $c]} { continue }
        foreach e [chanlist $c] {
          if {[onchansplit $e $c]} { continue }
          if {[isbotnick $e]} { continue }
          if {![string match -nocase $b "$e![getchanhost $e $c]"]} { continue }
          if {[string equal [lsearch -exact $n $e] "-1"]} { lappend n $e }
        }
      }
      set n [join $n ,]
      if {![string equal $n ""]} {
        if {[string equal [info procs notice] ""]} { puthelp "NOTICE $n :$s"
        } else { notice $n $s puthelp "" }
        lappend o "broadcast: message broadcasted to $m"
      } else { lappend o "broadcast: no users found matching $m" }
    }
  } else { lappend o "broadcast: eek, something must have gone wrong :(" }
  return $o
}


set scriptdb(broadcast) {
  "provides broadcast command for broadcasting messages to channels, flag pattern and masks"
}

