#by wiebe @ quakenet
#add dcc cmd



#bind pub fvlomn|fvlomn !showmode showmode:pub

proc showmode:pub { nick uhost handle chan text } {
  global showmode
  if { ![validchan $chan] } { return 0 }
  set chan [string tolower $chan]
  set c [string tolower [lindex [split [lindex [split $text] 0] ,] 0]]
  if { [info exists showmode($chan)] } {
    lappend output "A request is already in progress."
  } elseif { [string equal $c ""] } {
    lappend output "Usage: showmode <channel>"
  } elseif { ![string match -nocase \#* $c] } {
    lappend output "Invalid channel $c"
  } else {
    set showmode($chan) $c
    puthelp "MODE $c"
    lappend output "Retrieving modes from channel $c"
  }
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  return 1
}




bind raw -|- "324" showmode:raw
bind raw -|- "329" showmode:raw
bind raw -|- "403" showmode:raw

proc showmode:raw { server numeric text } {
  global showmode
  set msg ""

#324 me #channel +tncCNul 30
  if { [string equal $numeric 324] } {
    set c [lindex [split $text] 1]
    set cl [showmode:lower $c]
    set mode [string trimleft [join [lrange [split $text] 2 end]] :]
    set mode [showmode:key $cl $mode]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showmode($chan)] && [botonchan $chan] && [string equal -nocase [showmode:lower $showmode($chan)] $cl] } {
        set showmode($chan) "$showmode($chan) $mode"
      }
    }

#329 me #channel 1068641412
  } elseif { [string equal $numeric 329] } {
    set c [lindex [split $text] 1]
    set cl [showmode:lower $c]
    set ctime [lindex [split $text] 2]
    set ago [showmode:ts $ctime]
    set ctime [ctime $ctime]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showmode($chan)] && [botonchan $chan] && [string equal -nocase [showmode:lower [lindex [split $showmode($chan)] 0]] $cl] } {
        set mode [join [lrange [split $showmode($chan)] 1 end]]
        puthelp "PRIVMSG $chan :MODE: $c created $ctime ($ago ago) modes: $mode"
        unset showmode($chan)
      }
    }

#403 me #channel :No such channel
  } elseif { [string equal $numeric 403] } {
    set c [lindex [split $text] 1]
    set cl [showmode:lower $c]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showmode($chan)] && [botonchan $chan] && [string equal -nocase [showmode:lower $showmode($chan)] $cl] } {
        set msg "MODE: channel $c does not exist."
        if { [string match *c* [lindex [split [getchanmode $chan]] 0]] } { set msg [stripcodes bcru $msg] }
        puthelp "PRIVMSG $chan :$msg"
        unset showmode($chan)
      }
    }
  }
  return 0
}



#connect
bind evnt -|- init-server showmode:connect

proc showmode:connect { type } {
  global showmode
  if { [info exists showmode] } {
    unset showmode
  }
}



#join
bind join -|- * showmode:join

proc showmode:join { nick uhost handle chan } {
  global showmode
  if { [isbotnick $nick] && [info exists showmode($chan)] } {
    unset showmode($chan)
  }
}



#rfc1459 compare
proc showmode:lower { text } {
  set text [string map [list "\{" "\[" "search" "replace" "search" "replace"] $text]
  set text [string map [list "\}" "\]" "search" "replace" "search" "replace"] $text]
  set text [string map [list "\~" "\^" "search" "replace" "search" "replace"] $text]
  set text [string map [list "\\" "\|" "search" "replace" "search" "replace"] $text]
  set text [string tolower $text]
  return $text
}



#give timestamp, returns duration since/to in Xy Xw Xd Xh Xm Xs format
proc showmode:ts { ts } {
  if { ![string is digit $ts] } { return 0 }
  if { $ts > [unixtime] } {
    set ts [duration [expr $ts - [unixtime]]]
  } else {
    set ts [duration [expr [unixtime] - $ts]]
  }
  set ts [string map [list " seconds" "s" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " second" "s" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " minutes" "m" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " minute" "m" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " hours" "h" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " hour" "h" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " days" "d" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " day" "d" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " weeks" "w" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " week" "w" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " years" "y" "search" "replace" "search" "replace"] $ts]
  set ts [string map [list " year" "y" "search" "replace" "search" "replace"] $ts]
  return [join [lrange [split $ts] 0 1]]
}



#mask channel key
proc showmode:key { chan modes } {
  if { ![validchan $chan] } { return $modes }
  if { ![botonchan $chan] } { return $modes }
  if { ![botisop $chan] } { return $modes }
  set mode [lindex [split $modes] 0]
  if { ![string match *k* $modes] } { return $modes }
  set params [join [lrange [split $modes] 1 end]]
  if { [string equal [llength $params] 1] } { return "$mode *" }
  set k 0
  foreach m [split $mode ""] {
    if { [string equal $m k] } { break }
    if { [string equal $m l] } { incr k 1 }
  }
  set params [join [lreplace [split $params] $k $k *]]
  return "$mode $params"
}

