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


####################################################
# chanlev:help:msg
####################################################
bind msgm vlomn|vlomn "help chanlev" chanlev:help:msgm
proc chanlev:help:msgm { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "chanlev: usage chanlev <chan> \[<nick>|<#account> \[<flags>\]\]"
  lappend o "chanlev: to view the chanlev list for the channel, to view the flags for nick/#account on the channel, or to change flags for the user on the channel given. A +v|l|o user can change +g|y|a flags on himself without needing +m."
  lappend o "chanlev: a=auto-op d=deny-op f=friend g=auto-voice k=auto-kickban l=halfop m=master n=owner o=op q=deny-voice r=deny-halfop v=voice y=auto-halfop"
  if {![string equal [info procs userflag:get] ""]} {
    set r [userflag:get]; if {![string equal $r ""]} { lappend o "chanlev: $r" }
  }
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "chanlev: " } }
  putcmdlog "($n!$u) !$h! help chanlev"
  return 1
}


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


####################################################
# chanlev:dcc
####################################################
bind dcc -|- chanlev chanlev:dcc
proc chanlev:dcc { h i t } {
  if {![valididx $i]} { return 0 }
  set c [lindex [split [console $i]] 0]
  if {![validchan $c]} { set c "" }
  set o [chanlev:chanlev $h $t $c]
  lappend o "chanlev: where a=auto-op b=bot d=deny-op f=friend g=auto-voice k=auto-kickban l=halfop m=master n=owner o=op p=party-line q=deny-voice r=deny-halfop u=unshared v=voice y=auto-halfop"
  if {![string equal [info procs userflag:get] ""]} {
    set r [userflag:get]; if {![string equal $r ""]} { lappend o "chanlev: $r" }
  }
  foreach l $o { putidx $i $l }
  return 1
}


####################################################
# chanlev:chanlev
####################################################
proc chanlev:chanlev { h t {c ""} } {
  if {![string equal $t ""] || [string equal $c ""]} {
    set t [split $t]; set c [lindex $t 0]; set f [lindex $t 2]; set t [lindex $t 1]
  }
  if {![validchan $c] && ![string equal [info procs whichchan] ""]} { set c [whichchan $h $c] }
  if {[string match "#*" $t]} {
    set a [string range $t 1 end]; if {[validuser $a]} { set s "account '[getuser $a HANDLE]'" }
  } else { set a [nick2hand $t]; set s "user $t (account $a)" }
  if {[string equal $a "*"]} { set a "" }
# no chan
  if {[string equal $c ""]} {
    lappend o "chanlev: usage chanlev <chan> \[<nick>|<#account> \[<flags>\]\]"
# no access
  } elseif {![validchan $c] || ![matchattr $h vlomn|vlomn $c]} {
    lappend o "chanlev: no access or unknown channel $c"
# show chanlev list
  } elseif {[string equal $t ""]} {
    set r 0; set T 0; set N 0; set M 0; set O 0; set L 0; set V 0; set F 0; set K 0; set R 0
    foreach u [lsort -dictionary [userlist]] {
      if {![haschanrec $u $c]} { continue }
      set f [lindex [split [chattr $u $c] |] 1]
      if {[string equal $f "-"]} { delchanrec $u $c; continue }
      if {!$r} { lappend o "chanlev: listing chanlev for $c"; set r 1 }; incr T
      if {[string match *n* $f]} { incr N } elseif {[string match *m* $f]} { incr M
      } elseif {[string match *o* $f]} { incr O } elseif {[string match *l* $f]} { incr L
      } elseif {[string match *v* $f]} { incr V } elseif {[string match *f* $f]} { incr F 
      } elseif {[string match *k* $f]} { incr K } else { incr R }
      set x [string repeat " " [expr 20 - [string length $u]]]; set l [getuser $u LASTON $c]
      if {[string equal $l 0]} { set l "" }
      set m ""; if {![string equal $l ""]} { set m [clock format $l -format %d/%m/%y] }
      set d [clock format [clock seconds] -format %d/%m/%y]; set f "+$f"
      if {[handonchan $u $c]} { set l "on channel"
      } elseif {[string equal $m $d]} {
        set g "[chanlev:ts $l] ago"; set l "[clock format $l -format %H:%M]"
        set g "[string repeat " " [expr 23 - [string length $g] - [string length $l]]] $g"
        append l $g
      } elseif {![string equal $l ""]} {
        set g "[chanlev:ts $l] ago"; set l "[clock format $l -format %d/%m/%y]"
        set g "[string repeat " " [expr 23 - [string length $g] - [string length $l]]] $g"
        append l $g
      } else { set l never }
      set y [string repeat " " [expr 15 - [string length $f]]]
      lappend o "$u$x$f$y$l"

    }
    if {$r} {
      lappend o "total: $T (owner: $N, master: $M, op: $O, halfop: $L, voice: $V, friend: $F, kickban: $K, rest: $R)"
      lappend o "chanlev: end of chanlev list for $c"
    } else { lappend o "chanlev: no users known on $c" }

# unknown account
  } elseif {[string match "#*" $t] && ![validuser $a]} {
    lappend o "chanlev: unknown account $a"
# unknown user
  } elseif {![string match "#*" $t] && [string equal $a ""]} {
    lappend o "chanlev: unknown user $t"
# no flags, show flags for given user
  } elseif {[string equal $f ""]} {
    set f [lindex [split [chattr $a $c] |] 1]
    if {![string equal $f -]} {
      set l [getuser $a LASTON $c]
      if {[string equal $l 0]} { set l "" }
      set m ""; if {![string equal $l ""]} { set m [clock format $l -format %d/%m/%y] }
      set d [clock format [clock seconds] -format %d/%m/%y]; set f "+$f"
      if {[handonchan $a $c]} { set l "on channel"
      } elseif {[string equal $m $d] } {
        set g "[chanlev:ts $l] ago"; set l "last seen [clock format $l -format %H:%M]     $g"
      } elseif {![string equal $l ""]} {
        set g "[chanlev:ts $l] ago"
        set l "last seen [clock format $l -format %d/%m/%y]      $g"
      } else { set l never }
      lappend o "chanlev: $s has flags $f on $c      $l"
    } else { lappend o "chanlev: $s is not known on $c" }
# cannot change flags
  } elseif {![matchattr $h -|vlo $c] && ![matchattr $h mn|mn $c]} {
    lappend o "chanlev: no access to change flags on $c"
# can only change flags on self
  } elseif {![matchattr $h mn|mn $c] && ![string equal -nocase $h $a]} {
    lappend o "chanlev: no access to change flags for other users on $c"
# invalid flags
  } elseif {![string equal $f ""] && ![matchattr $h n] && [regexp {^[^-+]|[^-+adfgklmnoqrvyIOVNSRX]} $f]} {
    lappend o "chanlev: invalid flags specified"
    lappend o "chanlev: a=auto-op d=deny-op f=friend g=auto-voice k=auto-kickban l=halfop m=master n=owner o=op q=deny-voice r=deny-halfop v=voice y=auto-halfop"
    if {![string equal [info procs userflag:get] ""]} {
      set r [userflag:get]; if {![string equal $r ""]} { lappend o "chanlev: $r" }
    }
# only allow gyaI
  } elseif {![matchattr $h mn|mn $c] && [matchattr $h -|o $c] && [regexp {^[^-+]|[^-+gyaI]} $f]} {
    lappend o "chanlev: no access to change flags other than 'g y a I' for yourself on $c"
    lappend o "chanlev: g=auto-voice y=auto-halfop a=auto-op I=auto invite"
# only allow gyI
  } elseif {![matchattr $h mn|omn $c] && [matchattr $h -|l $c] && [regexp {^[^-+]|[^-+gyI]} $f]} {
    lappend o "chanlev: no access to change flags other than 'g y I' for yourself on $c"
    lappend o "chanlev: g=auto-voice y=auto-halfop I=auto invite"
# only allow gI
  } elseif {![matchattr $h mn|lomn $c] && [matchattr $h -|v $c] && [regexp {^[^-+]|[^-+gI]} $f]} {
    lappend o "chanlev: no access to change flags other than 'g I' for yourself on $c"
    lappend o "chanlev: g=auto-voice I=auto invite"
# master cant change mn flags
  } elseif {![matchattr $h n|n $c] && [string match {[mn]} $f]} {
    lappend o "chanlev: no access to change master or owner flags on $c"
# master cant change flags for other master or owner
  } elseif {![matchattr $h n|n $c] && [matchattr $a mn|mn $c]} {
    lappend o "chanlev: no access to change flags for other master or owner on $c"
# warning, new owner
  } elseif {![matchattr $a -|n $c] && ![string equal $f "+n"] && [regexp {\+[^-]*n} $f]} {
    lappend o "chanlev: WARNING! this will make $a owner of $c"
    lappend o "chanlev: if you really want to do this, use 'chanlev $c $t +n'"
# do it
  } else {
    set y [lindex [split [chattr $a $c] |] 1]; set z [lindex [split [chattr $a |$f $c] |] 1]
    if {[string equal $z "-"]} { set z "<none>" } else { set z "+$z" }
    if {[string equal $y "-"]} { set y "<none>" } else { set y "+$y" }
    if {[string equal -nocase $h $a]} {
      lappend o "chanlev: your flags on $c are now $z"
    } else { lappend o "chanlev: flags for $s on $c are now $z" }
    if {![string equal [info procs ircconsole] ""] && ![string equal $y $z]} {
      ircconsole $c a CHANLEV "$h changes flags ($f) for $s to $z (was $y)"
    }
  }
  return $o
}


####################################################
# chanlev:ts
####################################################
proc chanlev:ts { t } {
  if {![string is digit $t]} { return 0 }
  set n [clock seconds]; set t [expr $t - $n]; if {$t < 0} { set t [expr $t * -1] }
  set t [duration $t]
  set t [string map "seconds s second s minutes m minute m hours h hour h" $t]
  set t [string map "days d day d weeks w week w years y year y" $t]
  return [join [lrange [split $t] 0 3] ""]
}


set scriptdb(chanlev) {
  "provides chanlev command for viewing channel access list and changing a user's access on the channel"
}

