#by wiebe @ quakenet

#add dcc cmd



#bind pub fvlomn|fvlomn !showtopic showtopic:pub

proc showtopic:pub { nick uhost handle chan text } {
  global showtopic
  if { ![validchan $chan] } { return 0 }
  set chan [string tolower $chan]
  set c [string tolower [lindex [split [lindex [split $text] 0] ,] 0]]
  if { [validchan $c] && [botonchan $c] && [showtopic:lower $c] != [showtopic:lower $chan] && [string match *s* [lindex [split [getchanmode $c]] 0]] } {
    lappend output "TOPIC: can not retrieve topic from channel $c"
  } elseif { [string equal $c ""] } {
    lappend output "Usage: showtopic <channel>"
  } elseif { [info exists showtopic($chan)] } {
    lappend output "A request is already in progress."
  } elseif { ![string match -nocase \#* $c] } {
    lappend output $c\017 is an invalid channel."
  } else {
    set showtopic($chan) $c
    puthelp "TOPIC $c"
    lappend output "Retrieving topic from channel $c"
  }
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  return 1
}



#raw
bind raw -|- "331" showtopic:raw
bind raw -|- "332" showtopic:raw
bind raw -|- "333" showtopic:raw
bind raw -|- "403" showtopic:raw
bind raw -|- "442" showtopic:raw

proc showtopic:raw { server numeric text } {
  global showtopic
  set msg ""

#331 me #channel :No topic is set.
  if { $numeric == "331" } {
    set c [lindex [split $text] 1]
    set cl [showtopic:lower $c]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showtopic($chan)] && [botonchan $chan] && [showtopic:lower $showtopic($chan)] == $cl } {
        set msg "TOPIC: channel $c has no topic set."
        if { [string match *c* [lindex [split [getchanmode $chan]] 0]] } { set msg [stripcodes bcru $msg] }
        puthelp "PRIVMSG $chan :$msg"
        unset showtopic($chan)
      }
    }

#332 me #channel :welcome to #channel
  } elseif { $numeric == "332" } {
    set c [lindex [split $text] 1]
    set cl [showtopic:lower $c]
    set topic [string trimleft [join [lrange [split $text] 2 end]] :]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showtopic($chan)] && [botonchan $chan] && [showtopic:lower $showtopic($chan)] == $cl } {
        set showtopic($chan) "$showtopic($chan) $topic"
      }
    }

#333 me #channel john 1084528186
  } elseif { $numeric == "333" } {
    set c [lindex [split $text] 1]
    set cl [showtopic:lower $c]
    set nick [lindex [split $text] 2]
    set ctime [lindex [split $text] 3]
    set ago [showtopic:ts $ctime]
    set ctime [ctime $ctime]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showtopic($chan)] && [botonchan $chan] && [showtopic:lower [lindex [split $showtopic($chan)] 0]] == $cl } {
        set topic [join [lrange [split $showtopic($chan)] 1 end]]
        set len [string length $topic]
        set msg "TOPIC: on $c set by $nick on $ctime ($ago ago), topic: ' $topic \017' ($len chars)"
        if { [string match *c* [lindex [split [getchanmode $chan]] 0]] } { set msg [stripcodes bcru $msg] }
        puthelp "PRIVMSG $chan :$msg"
        unset showtopic($chan)
      }
    }

#403 me #channel :No such channel
  } elseif { $numeric == "403" } {
    set c [lindex [split $text] 1]
    set cl [showtopic:lower $c]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showtopic($chan)] && [botonchan $chan] && [showtopic:lower $showtopic($chan)] == $cl } {
        set msg "TOPIC: channel $c does not exist."
        if { [string match *c* [lindex [split [getchanmode $chan]] 0]] } { set msg [stripcodes bcru $msg] }
        puthelp "PRIVMSG $chan :$msg"
        unset showtopic($chan)
      }
    }

#442 me #channel :You're not on that channel
  } elseif { $numeric == "442" } {
    set c [lindex [split $text] 1]
    set cl [showtopic:lower $c]
    foreach chan [channels] {
      set chan [string tolower $chan]
      if { [info exists showtopic($chan)] && [botonchan $chan] && [showtopic:lower $showtopic($chan)] == $cl } {
        set msg "TOPIC: can not retrieve topic from channel $c"
        if { [string match *c* [lindex [split [getchanmode $chan]] 0]] } { set msg [stripcodes bcru $msg] }
        puthelp "PRIVMSG $chan :$msg"
        unset showtopic($chan)
      }
    }
  }
  return 0
}



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


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


#rfc1459 compare
proc showtopic: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 showtopic: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]]
}

