###############################################################################
#  Name:   					Ping
#  Author: 					kriptik@fieldsofnoise.org
#  Eggdrop Version:	1.6.x

###############################################################################
#  Description

#  Gives an eggdrop the ability to respond to the public command:
#  ping [target]
#  If target is not specified the person triggering the script
#  will be targeted.  The script also allows you to customise the result of the
#  ping request by using the tokens described below.

###############################################################################
#  Version History

#  0.1 First Release
#  0.2 Complete re-write
#  0.3 Only +f users can use the script now

###############################################################################
#  Getting Started

#  1) Put this script in your scripts directory.
#  2) Edit your eggdrop configuration file to include this file
#     Something like: source scripts/ping.tcl
#  3) Customise gPingFormat below, if you wish.

###############################################################################
#  User Configuration

#  Avalible tokens:
#  %botnick%          Nickname of the bot
#  %requester%        Person who requested the ping
#  %target%           Target nickname
#  %period%           Ping time as a string
#  %period_numeric%   Ping time as an integer
#  %b%                Bold styled text
#  %u%                Underline styled text
#  %isare%            If the period is plural this is 'are' otherwise 'is'

# gPingFormat <string>
# Defines how the ping result is displayed
# Historically the format has been:
#  set gPingFormatString "%b%%botnick%%b%  <-- %period% -->  %b%%target%%b%"

set gPingFormatString "There %isare% %period% of lag between me and %target%"

# gRoundTrip <boolean>
# If set to 1 pings are reported as roundtrips (Normal IRC behavior)
set gRoundTrip 1

###############################################################################
#  You shouldn't need to edit below here.

bind pub   f  ping doPing
bind ctcr  -  PING onPingReply
bind raw   -  401  noSuchNick

set gTheScriptVersion "0.3"

if {[array exists gNickRecord]} { unset gNickRecord }
array set gNickRecord ""

proc note {msg} {
  putlog "% $msg"
}

proc noSuchNick {from keyword text} {
  global gNickRecord
  set theNick [string tolower [lindex $text 1]]
  if {[info exists gNickRecord($theNick)]} {
    set theChannel [lindex $gNickRecord($theNick) 1]
    putserv "PRIVMSG $theChannel :$theNick does not exist."
    unset gNickRecord($theNick)
  }
}

proc doPing {nick uhost hand chan arg} {
  global gNickRecord
  if {[llength $arg] > 0} {
    set theNick [string tolower [lindex [split $arg] 0]]
  } else {
    set theNick [string tolower $nick]
  }
  note "Pinging $theNick (Requested by $nick on $chan)"
  set gNickRecord($theNick) [subst {[unixtime] $chan $nick}]
  putserv "PRIVMSG $theNick :\001PING [unixtime]\001"
}

proc onPingReply {nick uhost hand dest key arg} {
  global botnick gNickRecord gRoundTrip
  set theNick [string tolower $nick]
  if {[info exists gNickRecord($theNick)]} {
    set theTimeStamp [lindex $gNickRecord($theNick) 0]
    set thePeriod [expr ([unixtime] - $theTimeStamp)]
    if {$gRoundTrip != 1} {
      set thePeriod [expr $thePeroid/2]
    }
    set theChannel [lindex $gNickRecord($theNick) 1]
    set theRequester [lindex $gNickRecord($theNick) 2]
    set theMessage [formatPingString $thePeriod $botnick $theRequester $theNick]
    putserv "PRIVMSG $theChannel :$theMessage"
    unset gNickRecord($theNick)
  }
}

proc formatPingString {thePeriod theBotNick theRequester theTarget} {
  global gPingFormatString
  if {$thePeriod == 0} {
    set thePeriodString "less than a second"
    set theIsAre "is"
  } elseif {$thePeriod == 1} {
    set thePeriodString "1 second"
    set theIsAre "is"
  } else {
    set thePeriodString "$thePeriod seconds"
    set theIsAre "are"
  }
  set resultString $gPingFormatString
  regsub -all "%botnick%" $resultString $theBotNick resultString
  regsub -all "%requester%" $resultString $theRequester resultString
  regsub -all "%target%" $resultString $theTarget resultString
  regsub -all "%period%" $resultString $thePeriodString resultString
  regsub -all "%period_numeric%" $resultString $thePeriod resultString
  regsub -all "%isare%" $resultString $theIsAre resultString
  regsub -all "%b%" $resultString "\002" resultString
  regsub -all "%u%" $resultString "\037" resultString
  return $resultString
  # :-( map is sexy but doesn't work with older tcl
  # set theTokens [subst {%botnick% $theBotNick %requester% $theRequester %target% $theTarget %period% $thePeriodString %period_numeric% $thePeriod %isare% $theIsAre %b% \002 %u% \037}]
  # return [string map $theTokens $gPingFormatString]
}

###############################################################################

note "ping$gTheScriptVersion: loaded";
