// Saved by ViRC 2.0 at 3/26/2002 11:55:49 PM

// Jesse McGrew (Mr2001)

// nicklist.vsc - adds new features to ViRC's nick list:
// - supports additional flag types (+u)
// - new flag types can be added dynamically:
//       add flag:  /nladdflag o @
//    delete flag:  /nldelflag o
//     list flags:  /nlflags
//set /names mark:  /nlnamesmark o @
// - each flag can have a color, style, prefix, suffix,
//   and bitmap:
//   /nlcolor <flag> <color>
//      ^K colors:  /nlcolor o 4       (red)
//    color names:  /nlcolor v clBlue  (blue)
//     hex colors:  /nlcolor h 00007F  (dk. red)
//   /nlstyle <flag> <style>
//           bold:  /nlstyle o [fsBold]
//      the works:  /nlstyle o [fsBold,fsUnderline,fsItalic]
//   /nlprefix <flag> <prefix>
//     use prefix:  /nlprefix o <<
//      no prefix:  /nlprefix o none
//   /nlsuffix <flag> <suffix>
//     use suffix:  /nlsuffix o >>
//      no suffix:  /nlsuffix o none
//   /nlbitmap <flag> <filename>
//     use bitmap:  /nlbitmap o op.bmp
//      no bitmap:  /nlbitmap v none
// - set precedence:
//                  /nlprec ohv
//
// - NOTE: bitmaps are NOT working at this time.


MenuTree MT_CHANNELTEXTPOPUP__MERGE
  M_NLENABLE    <none> %_nicklist_isexcluded 0 Use enhanced nick list
  M_NLDISABLE   <none> !%_nicklist_isexcluded 0 Use standard nick list
EndMenuTree

MenuItem M_NLENABLE on MT_CHANNELTEXTPOPUP__MERGE
  @l $exclude = $nicklist_exclude[$networkid()]
  @s $nicklist_exclude[$networkid()] = $listremove($listquote($C) $exclude)
  
  @l $nicklist = $nicklist_objectbychan[$getwindowid(.) $lower($C)]
  @p $nicklist.Style = lbOwnerDrawFixed
EndMenuItem
MenuHint M_NLENABLE on MT_CHANNELTEXTPOPUP__MERGE = Enable the enhanced nick list from nicklist.vsc

MenuItem M_NLDISABLE on MT_CHANNELTEXTPOPUP__MERGE
  @l $exclude = $nicklist_exclude[$networkid()]
  @s $nicklist_exclude[$networkid()] = $listcat($listquote($C) $exclude)
  
  @l $nicklist = $nicklist_objectbychan[$getwindowid(.) $lower($C)]
  @p $nicklist.Style = lbStandard
EndMenuItem
MenuHint M_NLDISABLE on MT_CHANNELTEXTPOPUP__MERGE = Disable the enhanced nick list from nicklist.vsc
MergeMenu MT_CHANNELTEXTPOPUP__MERGE after MT_CHANNELTEXTPOPUP addsep clobber move


Event <OnCreateWindow_nicklistvsc> "TChannelForm *"
  @l $nicklist = $mapobject($1:NickList)
  
  if $getsetting(nicklist_enabled) && !$_nicklist_isexcluded($1)
    @p $nicklist.Style = lbOwnerDrawFixed
  endif
  
  @p $nicklist.ItemHeight = $nicklist.Canvas.TextHeight(j|l)
  @e $nicklist.OnDrawItem = _NICKLIST_DRAWITEM
  
  // set OnDestroy handler to unmap the nick list
  @l $win = $mapobject($1)
  Eval @e+ $win.OnDestroy = nicklist, _NICKLIST_UNMAP $getwindowid(.) $1
  UnmapObject $win
  
  // don't unmap, so $Sender will work in the event handler
  //UnmapObject $nicklist
  
  @ $nicklist_chanbyobject[$nicklist] = $1
  @ $nicklist_objectbychan[$getwindowid(.) $1] = $nicklist
EndEvent

Event MODE_nicklist -after "% MODE *"
  halt if !$ischannel($2)
  
  // :n!u@h MODE #chan +stolv Mr2001 123 scribbler
  @l $params = $listfromwords($4-)
  @l $paramidx = 0
  @l $pol = +
  // process each character of the mode change
  for (@l $i = 1; $i <= $length($3); $i++)
    @l $ch = $substr($3 $i 1)
    @l $info = $nicklist_flaginfo[$ch]
    if ([$ch] == [+]) || ([$ch] == [-])
      @l $pol = $ch
    else if ([$ch] == [k]) || ([$pol$ch] == [+l])
      // skip a parameter
      $paramidx++
    else if [$info] != []
      // set or unset the flag
      @l $nick = $listindex($paramidx $params)
      $paramidx++
      @l $theirflags = $nicklist_flags[$getwindowid(.) $lower($2) $nickcase($nick)]
      if [$theirflags] == []
        @l $theirflags = []
      endif
      if [$pol] == [+]
        @l $theirflags = $addtoset($theirflags [$asc($ch)])
      else
        @l $theirflags = $removefromset($theirflags [$asc($ch)])
      endif
      @ $nicklist_flags[$getwindowid(.) $lower($2) $nickcase($nick)] = $theirflags
    endif
  endfor
  
  // redraw nicklist
  @l $nicklist = $mapobject($2:NickList)
  $nicklist.Invalidate
  UnmapObject $nicklist
EndEvent

Event NamesListing_nicklist -after "% 353 *"
  // :server 353 mynick = chan :@nick1 +nick2...
  
  foreach ($i; $strtrim($5-))
    @l $found = 1
    @l $flags = []
    while $found
      @l $found = 0
      @l $ch = $substr($i 1 1)
      foreach ($flag, $info; $nicklist_flaginfo)
        if [$substr($i 1 1)] == [$info[namesflag]]
          @l $flags = $addtoset($flags [$asc($flag)])
          @l $i = $substr($i 2 9999)
          @l $found = 1
          break
        endif
        // workaround for RC2 array bug...
        -@l $info
      endforeach
    endwhile
    @ $nicklist_flags[$getwindowid(.) $lower($4) $nickcase($i)] = $flags
  endforeach
EndEvent

Event EndOfNames_nicklist -after "% 366 *"
  // redraw nicklist
  @l $nicklist = $mapobject($3:NickList)
  $nicklist.Invalidate
  UnmapObject $nicklist
EndEvent

Event PART_nicklist -after "% PART *"
  if [$nick] == [$N]
    // delete stored flags for users on the channel
    @l $sid = $getwindowid(.)
    @l $chan = $2
    foreach ($key; $arraykeys($nicklist_flags))
      parse $key
        if ([$0] == [$sid]) && ([$1] == [$chan])
         -@ $nicklist_flags[$key]
         endif
      endparse
    endforeach
  else
    // only delete this user's flags
    -@ $nicklist_flags[$getwindowid(.) $lower($2) $nickcase($nick)]
  endif
EndEvent

Event <OnDisconnect_nicklist> "*"
  // delete all stored user flags for this server
  @l $sid = $getwindowid(.)
  foreach ($key; $arraykeys($nicklist_flags))
    parse $key
      if [$0] == [$sid]
        -@ $nicklist_flags[$key]
      endif
    endparse
  endforeach
EndEvent

Event <OnUserSetupOK_nicklist> "*"
  OnAll _NICKLIST_ENABLE $getsetting(nicklist_enabled)
EndEvent


Alias _NICKLIST_DRAWITEM
  @l $canvas = $mapprop($Sender.Canvas)
  @l $nick = $nicktrim($Sender.Items.GetString($Index))
  @l $nc = $nickcase($nick)
  @l $chan = $nicklist_chanbyobject[$Sender]
  
  @l $appearance = $_nicklist_nickappear($nc $chan)
  
  // clear
  $canvas.FillRect $X1,$Y1 $X2,$Y2
  // draw
  @p $canvas.Font.Color = $appearance[color]
  @p $canvas.Font.Style = $appearance[style]
  $canvas.TextOut $X1,$Y1 $appearance[prefix]$nick$appearance[suffix]
  
  UnmapObject $canvas
EndAlias

Alias NICKCASE
  @l $out = $null
  for (@l $i = 1; $i <= $length($1-); $i++)
    @l $ch = $asc($substr($1- $i 1))
    if $ch >= $asc(a) && $ch <= $asc(z)
      @l $out = $out$upper($char($ch))
    else if $ch == $asc([)
      @l $out = $out{
    else if $ch == $asc(\)
      @l $out = $out|
    else if $ch == $asc(])
      @l $out = $out]
    else
      @l $out = $out$char($ch)
    endif
  endfor
  
  @ $fresult = $out
EndAlias

Alias _NICKLIST_APPEARANCE
  // $_nicklist_appearance(flagset)
  
  for (@l $i = 1; $i <= $length($nicklist_precedence); $i++)
    @l $flag = $substr($nicklist_precedence $i 1)
    if $isinset([$asc($flag)] $1-)
      @ $fresult = $nicklist_flaginfo[$flag]
      halt
    endif
  endfor
  
  @ $fresult = color ecNickListFG style [] bitmap none prefix "" suffix ""
EndAlias

Alias NLADDFLAG
  // NLAddFlag <flag> <prefix>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLADDFLAG <flag> </names flag>
  else if [$nicklist_flaginfo[$1]] != []
    TextOut ecError *** Flag already exists: $1
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
    
    @l $temp = $null
    @l $temp[color] = ecNickListFG
    @l $temp[style] = []
    @l $temp[namesflag] = $2
    @l $temp[prefix] = $2
    @l $temp[suffix] = $null
    
    @s $nicklist_flaginfo[$1] = $temp
    if $strpos($1 $nicklist_precedence) == 0
      @s $nicklist_precedence = ${nicklist_precedence}$1
    endif
    TextOut ecScript *** Flag added: $1
  endif
EndAlias

Alias NLDELFLAG
  // NLDelFlag <flag>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLDELFLAG <flag>
  else if [$nicklist_flaginfo[$1]] == []
    TextOut ecError *** Flag does not exist: $1
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
  
    -@s $nicklist_flaginfo[$1]
    TextOut ecScript *** Flag deleted: $1
  endif
EndAlias

Alias NLSTYLE
  // NLStyle <flag> <style>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLSTYLE <flag> <style>
  else if [$nicklist_flaginfo[$1]] == []
    TextOut ecError *** Flag does not exist: $1
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
  
    @l $info = $nicklist_flaginfo[$1]
    @l $info[style] = $2-
    @s $nicklist_flaginfo[$1] = $info
    TextOut ecScript *** Flag '$1' style set to $2-
  endif
EndAlias

Alias NLCOLOR
  // NLColor <flag> <style>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLCOLOR <flag> <color>
  else if [$nicklist_flaginfo[$1]] == []
    TextOut ecError *** Flag does not exist: $1
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
  
    @l $info = $nicklist_flaginfo[$1]
    @l $info[color] = $parsecolor($2 dec)
    @s $nicklist_flaginfo[$1] = $info
    TextOut ecScript *** Flag '$1' color set to $parsecolor($2)
  endif
EndAlias

Alias NLPREFIX
  // NLPrefix <flag> <prefix>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLPREFIX <flag> <prefix>
  else if [$nicklist_flaginfo[$1]] == []
    TextOut ecError *** Flag does not exist: $1
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
  
    if [$2] == [none]
      @l $prefix = $null
    else
      @l $prefix = $2
    endif
    @l $info = $nicklist_flaginfo[$1]
    @l $info[prefix] = $prefix
    @s $nicklist_flaginfo[$1] = $info
    TextOut ecScript *** Flag '$1' prefix set to $2
  endif
EndAlias

Alias NLSUFFIX
  // NLSuffix <flag> <suffix>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLSUFFIX <flag> <suffix>
  else if [$nicklist_flaginfo[$1]] == []
    TextOut ecError *** Flag does not exist: $1
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
  
    if [$2] == [none]
      @l $suffix = $null
    else
      @l $suffix = $2
    endif
    @l $info = $nicklist_flaginfo[$1]
    @l $info[suffix] = $suffix
    @s $nicklist_flaginfo[$1] = $info
    TextOut ecScript *** Flag '$1' suffix set to $2
  endif
EndAlias

Alias NLPREC
  // NLPrec [list]
  
  if [$1] == []
    TextOut ecScript *** Flag precedence: $nicklist_precedence
  else
    // invalidate appearance cache
    -@ $nicklist_appearcache
  
    @l $prec = $1
    foreach ($flag; $arraykeys($nicklist_flaginfo))
      if $strpos($flag $prec) == 0
        @l $prec = $prec$flag
      endif
    endforeach
    @s $nicklist_precedence = $prec
    TextOut ecScript *** Flag precedence set to $prec
  endif
EndAlias

Alias NLNAMESFLAG
  // NLNamesFlag <flag> <ircd prefix>
  
  if ([$1] == []) || ([$2] == [])
    TextOut ecError *** Usage: NLPREFIX <flag> <prefix>
  else if [$nicklist_flaginfo[$1]] == []
    TextOut ecError *** Flag does not exist: $1
  else
    @l $info = $nicklist_flaginfo[$1]
    @l $info[namesflag] = $2
    @s $nicklist_flaginfo[$1] = $info
    TextOut ecScript *** Flag '$1' /names marker set to $2
  endif
EndAlias

Alias NLFLAGS
  // NLFlags
  
  TextOut ecScript Nicklist flags:
  
  if [$nicklist_flaginfo] != [$$nicklist_flaginfo]
    foreach ($flag,$info; $nicklist_flaginfo)
      @l $color = $_nicklist_hexcolor($info[color])
      TextOut ecScript Flag: \b$flag\b  /names prefix: \b$info[namesflag]\b  Appearance: \d$color$info[prefix]nick$info[suffix]\d  Color: $color ($info[color])
      // work around RC2 array bug
      -@l $info
    endforeach
  endif
  
  TextOut ecScript --end--
EndAlias

Alias _NICKLIST_HEXCOLOR
  // $_nicklist_hexcolor(decimal-color)
  
  // convert to hex
  @l $hexdigits = 0123456789ABCDEF
  @l $hex = $null
  @l $dec = $1
  
  // this works backwards...
  // Delphi colors are reversed (BBGGRR), i.e. red = 255 = $0000FF
  // but we have to return RRGGBB for \d to work
  
  while $dec > 0
    // process two digits at once, the bytes are reversed but the nybbles aren't
  
    @l $digit = $(($dec & 15) + 1)
    @l $first = $substr($hexdigits $digit 1)
    @l $dec = $($dec >> 4)
    
    @l $digit = $(($dec & 15) + 1)
    @l $second = $substr($hexdigits $digit 1)
    @l $dec = $($dec >> 4)
    
    @l $hex = $hex$second$first
  endwhile
  
  // pad or trim to 6 characters
  switch $length($hex)
    case 0:
      @l $hex = 000000
    case 2:
      @l $hex = ${hex}0000
    case 4:
      @l $hex = ${hex}00
    case is > 6
      @l $hex = $substr($hex 1 6)
  endswitch
  
  @ $fresult = $hex
EndAlias

Alias _NICKLIST_UNMAP
  // _nicklist_unmap <serverid> <chan>
  
  @l $obj = $nicklist_objectbychan[$1-]
  UnmapObject $obj
  
  -@ $nicklist_objectbychan[$1-]
  -@ $nicklist_chanbyobject[$obj]
EndAlias

Alias _NICKLIST_NICKAPPEAR
  // $_nicklist_appearance(nc chan)
  @l $theirflags = $nicklist_flags[$getwindowid(.) $lower($2) $1]
  
  // cache appearances for quicker drawing
  if [$nicklist_appearcache[$theirflags]] == []
    @ $nicklist_appearcache[$theirflags] = $_nicklist_appearance($theirflags)
  endif
  
  @ $fresult = $nicklist_appearcache[$theirflags]
EndAlias

Alias _NICKLIST_ENABLE
  // _nicklist_enable <enabled>
  
  @l $sid = $getwindowid(.)
  @l $exclude = $nicklist_exclude[$networkid()]
  
  foreach ($i; $channellist())
    if $listindexof($listquote($i) $exclude) == -1
      @l $enabled = 0
    else
      @l $enabled = $1
    endif
    
    @l $nicklist = $nicklist_objectbychan[$sid $lower($i)]
    if $enabled
      @p $nicklist.Style = lbOwnerDrawFixed
    else
      @p $nicklist.Style = lbStandard
    endif
  endforeach
EndAlias

Alias _NICKLIST_ISEXCLUDED
  // $_nicklist_isexcluded(<channel>)
  @l $exclude = $nicklist_exclude[$networkid()]
  @ $fresult = $($listindexof($listquote($1) $exclude) != -1)
EndAlias

// script settings
AddScriptControl config check "Use enhanced nick list" nicklist_enabled = 1

// set defaults
if [$nicklist_precedence] == [$$nicklist_precedence]
  @s $nicklist_precedence = ohv
endif

if [$nicklist_flaginfo] == [$$nicklist_flaginfo]
  ^NLAddFlag o @
  ^NLColor o clRed
  ^NLStyle o [fsBold]
  
  ^NLAddFlag h %
  ^NLColor h 7
  
  ^NLAddFlag v +
  ^NLColor v clNavy
else
  // update old settings
  @l $info = $nicklist_flaginfo[o]
  if ([$info] != []) && ([$info[namesflag] == [])
    @l $info[namesflag] = @
    @s $nicklist_flaginfo[o] = $info
  endif
  @l $info = $nicklist_flaginfo[h]
  if ([$info] != []) && ([$info[namesflag] == [])
    @l $info[namesflag] = %
    @s $nicklist_flaginfo[h] = $info
  endif
  @l $info = $nicklist_flaginfo[v]
  if ([$info] != []) && ([$info[namesflag] == [])
    @l $info[namesflag] = +
    @s $nicklist_flaginfo[v] = $info
  endif
endif
