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

setudef flag unknown

####################################################
# help:pubm
####################################################
bind pubm -|- "% ${botnet-nick} help" help:pubm
bind pubm fvlomn|fvlomn "% ${botnet-nick} help help" help:pubm
proc help:pubm { n u h c t } {
  if {![validchan $c]} { return 0 }
  if {[matchattr $h bkZ]} { return 0 }
  if {![matchattr $h fvlomn|fvlomn $c]} {
    if {![channel get $c unknown]} { return 0 }
    if {![botisop $c] && ![botishalfop $c]} { return 0 }
    if {![string equal [info procs matchignore] ""] && [matchignore $n!$u]} { return 0 }
    if {[matchban $n!$u $c]} { return 0 }
    if {[expr [clock seconds] - [getchanjoin $n $c]] < 30 && ![isvoice $n $c] && ![ishalfop $n $c] && ![isop $n $c]} { return 0 }
  }
  set t [lindex [split $t] 2]
  if {[string equal -nocase $t "help"]} {
    lappend o "help: usage help \[<command>\]"
    lappend o "help: lists all channel commands available to you or shows help for the specified channel command"
    lappend o "help: where \002f\002=friend \002v\002=voice \002l\002=halfop \002o\002=op \002m\002=master \002n\002=owner, upper case means global flag (commands available in the channel and in private differ)"
  } else { set o [help:cmdpub $c $h] }
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "help: " } }
  return 1
}


####################################################
# help:msgm
####################################################
bind msgm fvlomn|fvlomn "help" help:msgm; bind msgm fvlomn|fvlomn "help help" help:msgm
bind msgm fvlomn|fvlomn "help #*" help:msgm; bind msgm fvlomn|fvlomn "help &*" help:msgm
proc help:msgm { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  set c [lindex [split $t] 1]
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  if {[string equal -nocase $c "help"]} {
    lappend o "help: usage help \[<command>|<chan>\]"
    lappend o "help: lists all private commands available to you, channel commands for the given channel, or shows help for the specified private command"
    lappend o "help: where \002f\002=friend \002v\002=voice \002l\002=halfop \002o\002=op \002m\002=master \002n\002=owner, upper case means global flag (commands available in the channel and in private differ)"
  } elseif {[validchan $c] && [matchattr $h fvlomn|fvlomn $c]} { set o [help:cmdpub $c $h]
  } elseif {![string equal $c ""]} { lappend o "help: no access or unknown channel $c"
  } else { set o [help:cmdmsg $h] }
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "help: " } }
  return 1
}


####################################################
# help:dcc
####################################################
bind dcc -|- help2 help:dcc
proc help:dcc { h i t } {
  if {![valididx $i]} { return 0 }
  set o [help:cmddcc $h]
  foreach l $o { putidx $i $l }
  return 1
}


####################################################
# help:cmdpub
####################################################
proc help:cmdpub { c h } {
  foreach a [split "a all cf cv cl co cm cn gF gV gL gO gM gN rest"] { set z($a) "" }
  set x [help:getchanflags $c $h]; set y [help:getglobflags $h]; set o ""
  foreach b [binds pubm] {
    set g [split [lindex $b 1] |]; set s [lindex $b 2]
    set p (\[[lindex $g 1]\]); set q (\[[lindex $g 0]\]); set r [lindex [split $s] 2]
    if {![string equal [lsearch $z(a) $r] "-1"]} { continue }
    if {![string match "% ${::botnet-nick} *" $s]} { continue }
    if {[string equal $r ""]} { continue }
    if {![string equal [join [lrange [split $s] 3 end]] ""]} { continue }
    lappend z(a) $r
    if {![string equal $x ""] && [regexp $p $x f f]} {
      if {[string match {[fvlomn]} $f]} { lappend z(c$f) $r } else { lappend z(rest) $r }
    } elseif {![string equal $y ""] && [regexp $q $y f f]} {
      if {[string match {[fvlomn]} $f]} { set f [string toupper $f]; lappend z(g$f) $r
      } else { lappend z(rest) $r }
    } elseif {[string equal $g "-"] || [string equal $g "- -"] } { lappend z(all) $r }
  }
  if {[string equal $z(a) ""]} { lappend o "help: no commands available to you"
  } else { lappend o "help: listing commands available to you on $c" }
  foreach a [split "all cf cv cl co cm cn gF gV gL gO gM gN rest"] {
    if {[string equal $z($a) ""]} { continue }
    set z($a) [lsort -dictionary $z($a)]
    if {[string equal $a "all"]} { set u "all"
    } elseif {[string equal $a "rest"]} { set u "rest"
    } else { set u [string range $a 1 1] }
    lappend o "\002$u\002: [join $z($a)]"
  }
  return $o
}


####################################################
# help:cmdmsg
####################################################
proc help:cmdmsg { h } {
  foreach a [split "a all cf cv cl co cm cn gF gV gL gO gM gN rest"] { set z($a) "" }
  set x [help:getanychanflags $h]; set y [help:getglobflags $h]; set o ""; lappend z(cf) "help"
  foreach b [binds msg] {
    set g [split [lindex $b 1] |]; set r [lindex $b 2]
    set p (\[[lindex $g 1]\]); set q (\[[lindex $g 0]\])
    if {![string equal [lsearch $z(a) $r] "-1"]} { continue }
    lappend z(a) $r
    if {![string equal $x ""] && [regexp $p $x f f]} {
      if {[string match {[fvlomn]} $f]} { lappend z(c$f) $r } else { lappend z(rest) $r }
    } elseif {![string equal $y ""] && [regexp $q $y f f]} {
      if {[string match {[fvlomn]} $f]} { set f [string toupper $f]; lappend z(g$f) $r
      } else { lappend z(rest) $r }
    } elseif {[string equal $g "-"] || [string equal $g "- -"] } { lappend z(all) $r }
  }
  if {[string equal $z(a) ""]} { lappend o "help: no commands available to you"
  } else { lappend o "help: listing commands available to you" }
  foreach a [split "all cf cv cl co cm cn gF gV gL gO gM gN rest"] {
    if {[string equal $z($a) ""]} { continue }
    set z($a) [lsort -dictionary $z($a)]
    if {[string equal $a "all"]} { set u "all"
    } elseif {[string equal $a "rest"]} { set u "rest"
    } else { set u [string range $a 1 1] }
    lappend o "\002$u\002: [join $z($a)]"
  }
  return $o
}


####################################################
# help:cmddcc
####################################################
proc help:cmddcc { h } {
  foreach a [split "a all cf cv cl co cm cn gF gV gL gO gM gN rest"] { set z($a) "" }
  set x [help:getanychanflags $h]; set y [help:getglobflags $h]; set o ""; lappend z(cf) "help"
  foreach b [binds dcc] {
    set g [split [lindex $b 1] |]; set r [lindex $b 2]
    set p (\[[lindex $g 1]\]); set q (\[[lindex $g 0]\])
    if {![string equal [lsearch $z(a) $r] "-1"]} { continue }
    lappend z(a) $r
    if {![string equal $x ""] && [regexp $p $x f f]} {
      if {[string match {[fvlomn]} $f]} { lappend z(c$f) $r } else { lappend z(rest) $r }
    } elseif {![string equal $y ""] && [regexp $q $y f f]} {
      if {[string match {[fvlomn]} $f]} { set f [string toupper $f]; lappend z(g$f) $r
      } else { lappend z(rest) $r }
    } elseif {[string equal $g "-"] || [string equal $g "- -"] } { lappend z(all) $r }
  }
  if {[string equal $z(a) ""]} { lappend o "help: no commands available to you"
  } else { lappend o "help: listing commands available to you" }
  foreach a [split "all cf cv cl co cm cn gF gV gL gO gM gN rest"] {
    if {[string equal $z($a) ""]} { continue }
    set z($a) [lsort -dictionary $z($a)]
    if {[string equal $a "all"]} { set u "all"
    } elseif {[string equal $a "rest"]} { set u "rest"
    } else { set u [string range $a 1 1] }
    lappend o "$u: [join $z($a)]"
  }
  return $o
}


####################################################
# help:getanychanflags
####################################################
proc help:getanychanflags { h } {
  if {![validuser $h]} { return "" }
  set f 0; set v 0; set l 0; set o 0; set m 0; set n 0
  foreach c [channels] {
    set a [chattr $h $c]
    if {[string match "*n*" $a]} { return "fvlomn"
    } elseif {[string match "*m*" $a]} { set m 1
    } elseif {[string match "*o*" $a]} { set o 1
    } elseif {[string match "*l*" $a]} { set l 1
    } elseif {[string match "*v*" $a]} { set v 1
    } elseif {[string match "*f*" $a]} { set f 1 }
  }
  if {$m} { return "fvlom" }
  if {$o} { return "fvlo" }
  if {$l} { return "fvl" }
  if {$v} { return "fv" }
  if {$f} { return "f" }
}


####################################################
# help:getchanflags
####################################################
proc help:getchanflags { c h } {
  if {![validuser $h]} { return "" }
  if {![validchan $c]} { return "" }
  set f 0; set v 0; set l 0; set o 0; set m 0; set n 0; set f [chattr $h $c]
  if {[string match "*n*" $f]} { return "fvlomn" }
  if {[string match "*m*" $f]} { return "fvlom" }
  if {[string match "*o*" $f]} { return "fvlo" }
  if {[string match "*l*" $f]} { return "fvl" }
  if {[string match "*v*" $f]} { return "fv" }
  if {[string match "*f*" $f]} { return "f" }
}


####################################################
# help:getglobflags
####################################################
proc help:getglobflags { h } {
  if {![validuser $h]} { return "" }; set f [chattr $h]
  if {[string match "*n*" $f]} { return "fvlomn" }
  if {[string match "*m*" $f]} { return "fvlom" }
  if {[string match "*o*" $f]} { return "fvlo" }
  if {[string match "*l*" $f]} { return "fvl" }
  if {[string match "*v*" $f]} { return "fv" }
  if {[string match "*f*" $f]} { return "f" }
}


set scriptdb(help) {
  "provides help command for listing all available commands. +unknown (allows unknown users to use the command on the channel)."
}

