All pastes #994201 Raw Edit

Stuff

public text v1 · immutable
#994201 ·published 2008-04-23 05:55 UTC
rendered paste body
/*
* -------------- ------ --- - - --- -------- --- - --
*  Project Focus
*  Worldwide Weather Service
*
*  by Tim Gunter / IcyLiquid
*  icyliquid@gmail.com
*  version 4.2
* -------------- ------ --- - - --- -------- --- - --
*/

alias -l fcwv { return 4.2 }

; -------------- ------ --- - - --- -------- --- - --
; Menus
; -------------- ------ --- - - --- -------- --- - --

menu menubar,status,query {
  Focus Weather
  .Personal Lookup:focus.weather.configdialog --lookup
  .-
  .Configure:focus.weather.configdialog
  .Help:focus.weather.configdialog --help
  .-
  .Unload Me:focus.weather.unload --confirm
}

menu channel {
  Focus Weather
  .Personal Lookup:focus.weather.configdialog --lookup
  .-
  .Configure:focus.weather.configdialog $iif($focus.weather.setting($network,$chan,inactive) isnum,--channels $network $chan)
  . $+ $iif($focus.weather.setting($network,$chan,inactive) !isnum,Add $chan) $+ : focus.weather.newchannel $network $chan
  .Help:focus.weather.configdialog --help
  .-
  .Unload Me:focus.weather.unload --confirm
}

; -------------- ------ --- - - --- -------- --- - --
; mIRC Events
; -------------- ------ --- - - --- -------- --- - --

on *:load:{
  if ($focus.weather.checksystem) {
    focus.weather.configdialog --help
  }
}

on *:start:{ 
  if ($focus.weather.checksystem) {
    focus.weather.queue start
    focus.weather.gettriggers
  }
  else {
    focus.weather.unload --corrupt
  }
}

on *:unload:{
  if ($dialog($dxfm)) { dialog -x $dxfm }
  udcx
  .timerfocus.weather.* off
  .sockclose focus.weather.*
  fcw.msg Focus Worldwide Weather Service has been unloaded.
}

on *:text:*:#:{ 
  focus.weather.triggered pub $network $chan $nick $1 $$2- 
}

on *:input:#:{ 
  if (!$ctrlenter) { focus.weather.triggered self $network $chan $me $1 $$2- } 
}

on *:ctcpreply:time*:{
  if ($timer($+(focus.weather.ctcpforecasts.,$network,¬,$nick))) {
    var %thistime = $ctime($1-), %old = $gettok($timer($+(focus.weather.ctcpforecasts.,$network,¬,$nick)).com,3-,32)
    .timer $+ $+(focus.weather.ctcpforecasts.,$network,¬,$nick) off
    var %params = $focus.weather.convertfuzzytime($iif(%thistime isnum,$ifmatch,$ctime),$gettok(%old,5,172))
    focus.weather.doforecast ctcp $puttok(%old,%params,5,172)
    haltdef
  }
}

alias -l focus.weather.triggered {

  var %type = $1
  var %network = $2
  var %chan = $3
  var %nick = $4
  tokenize 32 $strip($5-)

  if ($istok($focus.weather.register($+(%network,¬triggers¬,%chan)),$1,32)) {
    if ($focus.weather.register(status)) {
      if (!$focus.weather.setting(%network,%chan,inactive)) {
        if (!$focus.weather.queue(%network,%chan,%nick).reqcheck) {
          if ($0 >= 2) {
            if ($focus.weather.queue(freesock)) {
              $focus.weather(%network,%chan,%nick,$2-).request
            }
            elseif ($focus.weather.setting(%network,%chan,limitwarnings)) {
              $focus.weather.queue(%network,.notice %nick There are currently no request slots available. Please try again shortly.).addqueue
            }
          }
        }
        elseif ($focus.weather.setting(%network,%chan,limitwarnings)) {
          $focus.weather.queue(%network,.notice %nick Please wait $duration($focus.weather.queue(%network,%chan,%nick).reqcheck) before requesting the weather again.).addqueue
        }
      }
      else {
        if (%type == self) { .timer 1 1 fcw.msg Focus Worldwide Weather Service is $fcw.high(globally disabled) $+ . Either $fcw.high(enable it) $+ , or use the $fcw.high(Lookup function) in your popups: $fcw.high(Focus Weather > Personal Lookup) }
      }
    }
    else {
      if (%type == self) { .timer 1 1 fcw.msg Weather is $fcw.high(disabled) in $fcw.high(%chan) $+ . Either $fcw.high(enable it) $+ , or use the $fcw.high(Lookup function) in your popups: $fcw.high(Focus Weather > Personal Lookup) }
    }
  }
}

; -------------- ------ --- - - --- -------- --- - --
; Display Aliases
; -------------- ------ --- - - --- -------- --- - --

alias -l fcw.msg { echo -a 07* $1- }
alias -l fcw.high { return $+(07,$1-,) }
alias -l fcw.med { return $+(15,$1-,) }
alias -l fcw.dark { return $+(14,$1-,) }

; -------------- ------ --- - - --- -------- --- - --
; Data Storage Aliases
; -------------- ------ --- - - --- -------- --- - --

alias -l focus.weather.setini {
  if ($0 >= 3 && $3 != $null) {
    writeini $iif($prop,$focus.weather.inifile($prop),$focus.weather.config) $1 $2 $3
  }
  else {
    remini $iif($prop,$focus.weather.inifile($prop),$focus.weather.config) $1 $2
  }
}

alias -l focus.weather.getini {
  if ($0 == 2) {
    return $readini($iif($prop,$focus.weather.inifile($prop),$focus.weather.config),$1,$2)
  }
}

alias -l focus.weather.inifile {
  if ($1 == config) { return $focus.weather.config }
}

alias -l focus.weather.dir { 
  if ($isid) { 
    return $+($scriptdir,$iif($1,$1-))
  }
}

alias -l lfn {
  if ($isid) {
    return $+(",$remove($1-,"),")
  }
}

alias -l focus.weather.config {
  return $lfn($focus.weather.dir(weather.ini))
}

alias -l focus.weather.deleteall {
  if ($dialog($dxfm)) { dialog -x $dxfm }
  udcx
  .timerfocus.weather.* off
  .sockclose focus.weather.*
  focus.weather.rmdir $scriptdirdcx
  focus.weather.rmdir $scriptdirimg
  focus.weather.rmdir $scriptdir
  fcw.msg Focus Worldwide Weather Service has been deleted.
}

alias -l focus.weather.rmdir {
  var %dir = $lfn($1-)
  if ($isdir(%dir)) {
    .echo -q $findfile(%dir,*,0,3,remove $lfn($1-))
    rmdir %dir
  }
}

alias -l focus.weather.checksystem {
  if ($isid) {
    if ($isfile($focus.weather.config)) {
      if ($focus.weather.setting(Default,Settings,inactive)) {
        $focus.weather.setting(Default,Settings,inactive,1)
      }
    }
    else { return $false }
    return $true
  }
}

alias -l focus.weather.setting {
  if ($isid) {
    var %topic = $iif($0 > 2,$+($1,/,$2),weather)
    var %setting = $iif($0 > 2,$3,$1)
    if (. isin $calc($0 / 2)) {
      ; Get
      return $focus.weather.getini(%topic,%setting)
    }
    else {
      ; Set
      var %value = $iif($0 > 2,$4,$2)
      $focus.weather.setini(%topic,%setting,%value)
    }
  }
}

alias -l focus.weather.unload {
  var %tounload = $yes, %todelete = $no, %toforce = $false
  if ($istok($1-,--corrupt,32)) { .echo -q $input(Your copy of Focus Worldwide Weather Service seems to be corrupt. You will need to download a new copy from www.mircscripts.org. The script will now unload and delete itself. $crlf $crlf Thankyou for using FWWS!,oid,Unloading...) | %toforce = $true }
  if ($istok($1-,--confirm,32) && !%toforce) { var %tounload = $input(Are you sure you want to unload this script?,yvqd,Confirm Unload) }
  if (%tounload == $yes && !%toforce) { var %todelete = $input(Would you also like to completely remove this script from your computer?,yvqd,Confirm Delete) }

  if (%todelete == $yes || %toforce) { focus.weather.deleteall }
  if (%tounload == $yes || %toforce) { .unload -rs $lfn($script) }
}

alias -l focus.weather.gettriggers {
  $focus.weather.register(status,$focus.weather.setting(status))
  var %networks = $focus.weather.locations(0).network, %network = 1
  while (%network <= %networks) {
    var %netname = $focus.weather.locations(%network).network
    var %channels = $focus.weather.locations(%network,0).chan, %channel = 1
    while (%channel <= %channels) {
      var %channame = $focus.weather.locations(%network,%channel).chan
      var %regname = $+(%netname,¬triggers¬,%channame)
      $focus.weather.register(%regname,$focus.weather.setting(%netname,%channame,triggers))
      inc %channel
    }
    inc %network
  }
}

alias -l _focus.weather.locations { return $focus.weather.locations($1 [ $+ [ $iif($0 > 1,$+($chr(44),$2)) ] $+ ] ). [ $+ [ $prop ] ] }
alias -l focus.weather.locations {
  if ($isid) {
    if ($prop == chan) {
      if ($0 < 2) { return }
      var %network = $iif($1 isnum && $1,$_focus.weather.locations($1).network,$1), %channel = $2
      var %search = $+([,%network,/,*,])
      var %hit = 0, %line = 1, %target = $iif(%channel == 0,$lines($focus.weather.config),%channel)
      while (%hit <= %target) {
        var %item = $read($focus.weather.config,nw,%search,%line)
        if (%item != $null) {
          var %line = $calc($readn + 1)
          inc %hit
          if (%hit == %channel) { return $mid($gettok(%item,2-,47),1,-1) }
        }
        else {
          if (%hit <= %target) {
            if (%channel == 0) { return %hit }
          }
          return
        }
      }
    }
    if ($prop == network) {
      if ($0 < 1) { return }

      var %search = $+([,*,/,*,]), %recorded
      var %hit = 0, %line = 1, %target = $iif($1 == 0,$lines($focus.weather.config),$1)
      while (%hit <= %target) {
        var %item = $read($focus.weather.config,nw,%search,%line)
        if (%item != $null) {
          var %network = $mid($gettok(%item,1,47),2)
          var %line = $calc($readn + 1)
          if (!$istok(%recorded,%network,32)) {
            var %recorded = $addtok(%recorded,%network,32)
            inc %hit
            if (%hit == $1) { return %network }
          }
        }
        else {
          if (%hit <= %target) {
            if ($1 == 0) { return %hit }
          }
          return
        }
      }
    }
  }
}

alias -l focus.weather.getscid {
  if ($isid) {
    var %scons = $scon(0)
    while (%scons) {
      if ($1 == $scon(%scons).network) { return $scon(%scons) }
      dec %scons
    }
  }
}

alias -l focus.weather.register {
  if ($isid) {
    if ($prop == del) {
      $focus.weather.queue($1).setreg
    }
    else {
      if ($0 > 1) { $focus.weather.queue($1,$2).setreg }
      else { return $focus.weather.queue($1).getreg }
    }
  }
}

alias -l focus.weather.queuepointer {
  if ($isid) {
    if ($1 == stacksize) {
      return $calc($focus.weather.register(queuestacklast) - $focus.weather.register(queuestackpointer))
    }
    if ($1 == new) {
      var %cptr = $iif($focus.weather.register(queuestacklast) isnum,$calc($ifmatch + 1),1)
      $focus.weather.register(queuestacklast,%cptr)
      if (%cptr == 1) { $focus.weather.register(queuestackpointer,%cptr) }
      return %cptr
    }
    if ($1 == current) {
      return $focus.weather.register(queuestackpointer)
    }
    if ($1 == advance) {
      var %cptr = $focus.weather.register(queuestackpointer)
      if ($calc(%cptr + 1) > $focus.weather.register(queuestacklast)) { $focus.weather.register(queuestacklast,0) | %nptr = 0 }
      else { %nptr = $ifmatch }
      $focus.weather.register(queuestackpointer,%nptr)
      return %cptr
    }
  }
}

alias -l focus.weather.queuehash { return focus.weather.queuehash }
alias -l focus.weather.reqhash { return focus.weather.reqhash }
alias -l focus.weather.reghash { return focus.weather.reghash }
alias -l _focus.weather.queue { if (!$isid) { focus.weather.queue $1- } }
alias -l focus.weather.queue {
  if ($prop == queueclear) { if ($hget($focus.weather.reqhash)) { hfree $focus.weather.reqhash } }  
  if ($prop == reqclear) { if ($hget($focus.weather.reqhash)) { hfree $focus.weather.reqhash } }
  if ($prop == regclear) { if ($hget($focus.weather.reghash)) { hfree $focus.weather.reghash } }  

  if (!$hget($focus.weather.queuehash)) { hmake $focus.weather.queuehash 100 }
  if (!$hget($focus.weather.reqhash)) { hmake $focus.weather.reqhash 100 | focus.weather.gettriggers }
  if (!$hget($focus.weather.reghash)) { hmake $focus.weather.reghash 100 }

  if ($1 == doqueue) {
    if ($focus.weather.queuepointer(current)) {
      var %ptr = $focus.weather.queuepointer(advance)
      var %task = $hget($focus.weather.queuehash,%ptr)
      hdel $focus.weather.queuehash %ptr
      if ($dialog($dxfm)) { $dcx.list($dxfm,116,1).delnode }
      scid $focus.weather.getscid($gettok(%task,1,32)) $gettok(%task,2-,32)
    }
  }

  if ($1 == start) {
    var %time = $focus.weather.setting(queuefreq)
    var %time = $iif(%time isnum && %time > 0,%time,1)
    .timerfocus.weather.queue $iif(. isin %time,-m) 0 %time focus.weather.queue doqueue
  }

  if (!$timer(focus.weather.queue)) { _focus.weather.queue start }

  if (!$isid) { return }

  if ($1 == socks) {
    return $sock(focus.weather.retrieve.*,0)
  }
  if ($1 == freesock) {
    if ($focus.weather.setting(socketmaxthreads) == 0 || $sock(focus.weather.retrieve.*,0) < $focus.weather.setting(socketmaxthreads)) {
      return $true
    }
    return $false
  }
  if ($1 == getsock) {
    if ($focus.weather.setting(socketmaxthreads) == 0 || $sock(focus.weather.retrieve.*,0) < $focus.weather.setting(socketmaxthreads)) {
      return $+(focus.weather.retrieve.,$ticks)
    }
    return $null
  }

  if (*clear !iswm $prop && $0 >= 3) {
    var %network = $1
    var %chan = $2
    var %nick = $3
  }

  if ($prop == setreg) {
    if ($0 > 1) {
      hadd $focus.weather.reghash $1 $2-
    }
    else {
      if ($0) { hdel $focus.weather.reghash $1 }
    }
  }
  if ($prop == getreg) {
    return $hget($focus.weather.reghash,$1)
  }

  if ($prop == request) {
    hadd -z $focus.weather.reqhash $+(%network,-,%chan,-,%nick) $focus.weather.setting(%network,%chan,requestwait)
  }
  if ($prop == requestshort) {
    hadd -z $focus.weather.reqhash $+(%network,-,%chan,-,%nick) 10
  }
  if ($prop == reqcheck) {
    return $iif($hget($focus.weather.reqhash,$+(%network,-,%chan,-,%nick)),$ifmatch,$false)
  }
  if ($prop == reqdel) {
    hdel $focus.weather.reqhash $+(%network,-,%chan,-,%nick)
  }

  if ($prop == addqueue) {
    var %ptr = $focus.weather.queuepointer(new)
    hadd $focus.weather.queuehash %ptr $1 $2-
    if ($dialog($dxfm)) { $dcx.list($ifmatch,116,0,0,+ 0 0 0 0 0 0 %ptr,+ 0 $1,+ 0 $2-).addnode }
  }

}

; -------------- ------ --- - - --- -------- --- - --
; Weather Processing Aliases
; -------------- ------ --- - - --- -------- --- - --

alias -l focus.weather {
  if ($isid) {
    if ($prop == request) {
      tokenize 32 $1-
      if ($4 == forecast) {
        if ($focus.weather.setting($1,$2,forecasts)) {
          $focus.weather.queue($1,$2,$3).request

          var %days = Monday Tuesday Wednesday Thursday Friday Saturday Sunday
          var %lasttwo = $gettok($5-,-2-,32), %lastone = $gettok($5-,-1,32), %midlast = $gettok($5-,-2-0,32)

          var %query = $5-
          if (%lasttwo == tommorrow night) { var %type = fuzzy, %params = $ifmatch }
          elseif (%lastone == tommorrow) { var %type = fuzzy, %params = $ifmatch }
          elseif (%lastone == tonight) { var %type = fuzzy, %params = $ifmatch }
          elseif ($istok(%days,%midlast,32)) { var %type = direct, %params = %lasttwo }
          elseif ($istok(%days,%lastone,32)) { var %type = direct, %params = %lastone }
          else { var %type = fuzzy, %params = tommorrow, %query = %query tommorrow }

          var %chop = $calc($numtok(%query,32) - $numtok(%params,32))
          var %query = $gettok(%query,$+(1-,%chop),32)
          var %query = $focus.weather.querystring(%query)

          if (%type == fuzzy) {
            if ($focus.weather.setting($1,$2,ctcpforecasts)) {
              $focus.weather.queue($1,focus.weather.getctcptime $1 $3 $+($1,¬,$2,¬,$3,¬,%query,¬,%params)).addqueue
            }
            else { var %type = guess }
          }
          if (%type == guess) {
            var %oparams = %params
            var %params = $focus.weather.convertfuzzytime($ctime,%params)
            var %type = direct
          }
          if (%type == direct) {
            focus.weather.doforecast manual $+($1,¬,$2,¬,$3,¬,%query,¬,$focus.weather.querystring(%params))
          }
        }
      }
      else {
        $focus.weather.queue($1,$2,$3).request
        var %query = $focus.weather.querystring($4-)
        focus.weather.doweather $1 $2 $3 %query
      }
    }
  }
  else {
    if ($1 == display) {
      var %capab, %place, %options, %thisweather
      var %network = $2
      var %chan = $3
      var %nick = $4
      var %im = $iif($focus.weather.setting(%network,%chan,imperial),i) $+ $iif($focus.weather.setting(%network,%chan,metric),m)
      if (!$len(%im)) { var %im = im }
      var %b = $iif($focus.weather.setting(%network,%chan,usebold),)

      var %alert = $focus.weather.register($+(%network,¬,%chan,¬,%nick,¬alert))
      $focus.weather.register($+(%network,¬,%chan,¬,%nick,¬alert)).del
      tokenize 171 $focus.weather.register($+(%network,¬,%chan,¬,%nick))
      $focus.weather.register($+(%network,¬,%chan,¬,%nick)).del
      var %item = 1
      var %permittedItems = 0
      while (%item <= $0) {
        var %data = $ [ $+ [ %item ] ]
        var %name = $gettok(%data,1,32)
        if (%name == place) { %place = $gettok(%data,2-,32) }
        if ($istok($focus.weather.setting(%network,%chan,capab),$left(%name,4),32) || $istok($focus.weather.setting(forcecapab),$left(%name,4),32)) {
          inc %permittedItems 1
          unset %optres
          var %longname = $focus.weather.getini(weathercapab,$left(%name,4)), %optres
          var %opts = $gettok(%data,2-,32), %opt = 1
          var %capab = $mid(%name,6,-1)
          var %optres = $+(%b,%longname,%b,$chr(32),$chr(40))

          while (%opt <= $numtok(%opts,172)) {
            var %thiscapab = $mid(%capab,%opt,1)
            if (%thiscapab == d) { var %optres = $+(%optres,$gettok(%opts,%opt,172)) }

            if (%thiscapab == i) { var %sp = $iif(d isin %capab,$chr(32)) } | else { var %sp = $null }
            if (%thiscapab == i && i isin %im) { var %optres = $+(%optres,%sp,$gettok(%opts,%opt,172),$iif(m isin %im && m isin %capab,/)) }

            if (%thiscapab == m && i !isin %im) { var %sp = $iif(d isin %capab,$chr(32)) } | else { var %sp = $null }
            if (%thiscapab == m && m isin %im) { var %optres = $+(%optres,%sp,$gettok(%opts,%opt,172)) }

            if (%thiscapab == o) { var %optres = $addtok(%optres,$gettok(%opts,%opt,172),32) }
            inc %opt
          }
          var %optres = $+(%optres,$chr(41))

          var %options = $addtok(%options,%optres,32)
        }
        inc %item
      }

      if (%permittedItems) {
        var %display = $focus.weather.setting(%network,%chan,displaymessage)
        var %msg = $replace($replace(%display,!place!,%place),!options!,%options)
        if ($len(%msg)) { $focus.weather.message(%network,%chan,%nick,%msg) }
        if ($len(%alert) && $focus.weather.setting(%network,%chan,showalerts)) {
          var %alertmsg = $replace($replace(%display,!place!,%place),!options!,%alert)
          if ($len(%alertmsg)) { $focus.weather.message(%network,%chan,%nick,%alertmsg) }
        }
      }
    }
  }
}

alias -l focus.weather.message {
  var %iscm = $focus.weather.setting($1,$2,cm)
  var %ispm = $focus.weather.setting($1,$2,pm)
  var %iscn = $focus.weather.setting($1,$2,cn)
  var %ispn = $focus.weather.setting($1,$2,pn)

  if (%iscm) { $focus.weather.queue($1,msg $2 $4).addqueue }
  if (%ispm) { $focus.weather.queue($1,msg $3 $4).addqueue }
  if (%iscn) { $focus.weather.queue($1,notice $2 $4).addqueue }
  if (%ispn) { $focus.weather.queue($1,notice $3 $4).addqueue }
}

alias -l focus.weather.getctcptime {
  .timerfocus.weather.ctcpforecasts. [ $+ [ $+($1,¬,$2) ] ] 1 10 focus.weather.doforecast timed $3-
  scid $focus.weather.getscid($1) .ctcp $2 TIME
}

alias -l focus.weather.doweather {
  var %request = $replace($focus.weather.setting(getweather),!zone!,$4-)
  $focus.weather.initrequest($1,$2,$3,%request)
}

alias -l focus.weather.doforecast {
  var %tokstring = $2-
  if ($1 == timed) { var %tokstring = $puttok(%tokstring,$focus.weather.convertfuzzytime($ctime,$gettok(%tokstring,5,172)),5,172) }
  var %request = $replace($replace($focus.weather.setting(getforecast),!zone!,$gettok(%tokstring,4,172)),!time!,$gettok(%tokstring,5,172))
  $focus.weather.initrequest($gettok(%tokstring,1,172),$gettok(%tokstring,2,172),$gettok(%tokstring,3,172),%request)
}

alias -l focus.weather.convertfuzzytime {
  var %tommorrow = $asctime($calc($1 + 86400),dddd)
  var %tonight = $asctime($1,dddd)
  var %day = $2-
  var %day = $replace(%day,tommorrow,%tommorrow)
  var %day = $replace(%day,tonight,%tonight night&alternate=tonight)
  return $focus.weather.querystring(%day)
}

alias -l focus.weather.querystring {
  return $lower($replace($replace($1-,$chr(44),$chr(32)),$chr(32),+))
}

alias -l focus.weather.initrequest {
  var %sockname = $focus.weather.queue(getsock)
  sockopen %sockname $focus.weather.setting(server) $focus.weather.setting(port)
  sockmark %sockname $1-
}

; -------------- ------ --- - - --- -------- --- - --
; Socket Section
; -------------- ------ --- - - --- -------- --- - --

alias -l focus.weather.getcapab {
  if (!$sock(focus.weather.getcapab)) {
    .timerfocus.weather.getcapab 1 5 focus.weather.showcapab --failure
    sockopen focus.weather.getcapab $focus.weather.setting(server) $focus.weather.setting(port)
    sockmark $focus.weather.setting(server)
  }
}

alias -l focus.weather.showcapab {
  if ($sock(focus.weather.getcapab)) { sockclose focus.weather.getcapab }
  if ($timer(focus.weather.getcapab)) { .timerfocus.weather.getcapab off }
  if ($istok($1-,--failure,32)) { fcw.msg Weather service error. Failed to connect to master server for option list! }

  if ($dialog($dxfm)) {
    var %channel = $dcx.general($dxfm,151).mark
    if (%channel) {
      var %chan = $gettok(%channel,1,32)
      var %net = $focus.weather.locations($gettok(%channel,2,32)).network
      var %mytoks = $focus.weather.setting(%net,%chan,capab)
      var %l = $true
    }
    else {
      var %l = $false
    }
    $dcx.general($dxfm,161).clear
    var %capab = $focus.weather.setting(capab)
    var %toks = $numtok(%capab,44), %tok = 1, %saved
    while (%tok <= %toks) {
      var %item = $gettok(%capab,%tok,44)
      var %code = $gettok(%item,1,91)
      var %name = $gettok(%item,2,93)
      if (%l && $istok(%mytoks,%code,32)) { var %saved = $addtok(%saved,%code,32) | var %i = 2 }
      else { %i = 1 }
      $dcx.list($dxfm,161,0,0,+ 0 %i 0 0 0 0 %name,+ 0 %code).addnode
      inc %tok
    }
    if (%l) { $focus.weather.setting(%net,%chan,capab,%saved) }
    if (%capab) { $dcx.general($dxfm,161).enable }
  }
}

on *:sockopen:focus.weather.*:{
  if ($sockerr > 0) { fcw.msg Weather service error. $sock($sockname).wsmsg }

  if (*getcapab iswm $sockname) {
    if ($sockerr > 0) { return }
    sockwrite -n $sockname GET $+($focus.weather.setting(getcapab),&version=,$fcwv) HTTP/1.1
  }
  elseif (*retrieve* iswm $sockname) {
    if ($sockerr > 0) { 
      var %network = $gettok($sock($sockname).mark,1,32), %chan = $gettok($sock($sockname).mark,2,32), %nick = $gettok($sock($sockname).mark,3,32)
      $focus.weather.message(%network,%chan,%nick,Weather server is currently unavailable. Please try again later.)
      return 
    }
    sockwrite -n $sockname GET $+($gettok($sock($sockname).mark,4-,32),&version=,$fcwv) HTTP/1.1
  }
  sockwrite -n $sockname Host: $focus.weather.setting(server)
  sockwrite -n $sockname User-Agent: User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7
  sockwrite -n $sockname
  .timer $+ $sockname off
}

on *:sockread:focus.weather.*:{
  if ($sockerr > 0) { fcw.msg Weather service error. $sock($sockname).wsmsg }

  sockread %focus.weather.data. [ $+ [ $sockname ] ]
  tokenize 32 %focus.weather.data. [ $+ [ $sockname ] ]
  unset %focus.weather.data. [ $+ [ $sockname ] ]

  if ($sockname == focus.weather.getcapab) {

    if ($sockerr > 0) { return }

    if ($1 == start) { return }
    elseif ($1 == end) { focus.weather.showcapab }
    elseif ($1 == capab) { 
      $focus.weather.setting(capab,$2-)
      tokenize 44 $2-
      var %section = 1
      $focus.weather.setini(weathercapab)
      while (%section <= $0) {
        var %item = $ [ $+ [ %section ] ]
        $focus.weather.setini(weathercapab,$gettok(%item,1,91),$gettok(%item,2-,32))
        inc %section
      }
    }
  }
  if (*retrieve* iswm $sockname) {

    var %network = $gettok($sock($sockname).mark,1,32), %chan = $gettok($sock($sockname).mark,2,32), %nick = $gettok($sock($sockname).mark,3,32)

    if ($sockerr > 0) {
      $focus.weather.message(%network,%chan,%nick,Weather service is currently experiencing technical difficulties. Please try again later!)
      fcw.msg Weather service error. $sock($sockname).wsmsg
      return 
    }

    if ($1 == start) { return }
    if ($1 == status) { 
      if ($2 == 0) {
        $focus.weather.queue($1,$2,$3).requestshort
        if ($3 == unavailable) {
          $focus.weather.message(%network,%chan,%nick,Weather for ' $+ $4- $+ ' could not be found. Please try again. Do not use abbreviations. Request format: !weather [forecast] <city country|us zip|canada zip> [monday|tuesday...|tommorrow] [night])
        }
        if ($3 == multiple) {
          $focus.weather.message(%network,%chan,%nick,Multiple results for ' $+ $4- $+ '. Please try again with a more specific search.)
        }
        if ($3-4 == no zone) {
          $focus.weather.message(%network,%chan,%nick,You need to specify a search term. Request format: !weather [forecast] <city country|us zip|canada zip> [monday|tuesday...|tommorrow] [night])
        }
        sockclose $sockname
      }
    }
    if ($1 == capab) {
      $focus.weather.register($+(%network,¬,%chan,¬,%nick),$1-)
    }
    if ($1 == place) {
      var %current = $focus.weather.register($+(%network,¬,%chan,¬,%nick))
      var %new = $addtok(%current,$1-,171)
      $focus.weather.register($+(%network,¬,%chan,¬,%nick),%new)
    }
    if ($1 == alert) {
      $focus.weather.register($+(%network,¬,%chan,¬,%nick,¬alert),$2-)
    }
    if ($focus.weather.getini(weathercapab,$left($1,4))) {
      var %current = $focus.weather.register($+(%network,¬,%chan,¬,%nick))
      var %new = $addtok(%current,$1-,171)
      $focus.weather.register($+(%network,¬,%chan,¬,%nick),%new)
    }
    if ($1 == end) {
      focus.weather display $gettok($sock($sockname).mark,1-3,32)
      sockclose $sockname
    }
  }
  if ($1 == force) {
    var %forcecapab
    tokenize 44 $2-
    var %section = 1
    while (%section <= $0) {
      var %item = $ [ $+ [ %section ] ]
      $focus.weather.setini(weathercapab,$gettok(%item,1,91),$gettok(%item,2-,32))
      var %forcecapab = $addtok(%forcecapab,$gettok(%item,1,91),32)
      inc %section
    }
    $focus.weather.setting(forcecapab,%forcecapab)
    return
  }
}

; -------------- ------ --- - - --- -------- --- - --
; Dialog
; -------------- ------ --- - - --- -------- --- - --

dialog focus.weather {
  title "Focus Worldwide Weather Service [/fwconfig]"
  size -1 -1 616 316
  option pixel
}

alias -l dbg { return $false } ; xdid output toggle

; -------------- ------ --- - - --- -------- --- - --
; Dialog Events
; -------------- ------ --- - - --- -------- --- - --

on *:dialog:focus.weather:*:*:{
  if ($devent == init) {
    var %n = $dname
    if (!$isdcx) { fcw.msg Could not find $fcw.high(dcx.dll) $+ . | dialog -x %n | return }

    .echo -q $dcx.dialog($dname,focus.weather.dcxcallback).mark
    $dcx.dialog(%n,+bdfty).styles

    $dcx.box(%n,1,11 11 77 295).add
    $dcx.general(%n,1,+t,$rgb(107,116,123)).color
    $dcx.panel(%n,1 3,4 4 69 287).add
    $dcx.toolbar(%n,3 2,0 0 71 290,nodivider flat left).add
    $dcx.toolbar(%n,2).clear
    $dcx.toolbar(%n,2,32).iconsize
    $dcx.toolbar(%n,2,+ndh 0 $weathericons).addicon
    $dcx.toolbar(%n,2,+ndh 1 $weathericons).addicon
    $dcx.toolbar(%n,2,+ndh 2 $weathericons).addicon
    $dcx.toolbar(%n,2,+ndh 3 $weathericons).addicon
    $dcx.toolbar(%n,2,+ndh 4 $weathericons).addicon
    $dcx.toolbar(%n,2,1,+lgkw 69 1 0,Options).addnode
    $dcx.toolbar(%n,2,2,+lgkw 69 2 0,Channels).addnode
    $dcx.toolbar(%n,2,3,+lgkw 69 3 0,Lookup).addnode
    $dcx.toolbar(%n,2,4,+lgkw 69 4 0,Help).addnode
    $dcx.toolbar(%n,2,5,+lgkw 69 5 0,Done).addnode

    ; Title

    $dcx.panel(%n,5,100 11 505 30).add
    $dcx.general(%n,5,+b,$rgb(240,238,226)).color
    $dcx.general(%n,5,static).border

    $dcx.tree(%n,5 6,0 0 505 30,noscroll disabled).add
    $dcx.tree(%n,6,+b,$rgb(240,238,226)).color
    $dcx.general(%n,6).border
    $dcx.general(%n,6,+b,default,-20,Trebuchet MS).font
    $dcx.tree(%n,6,-1,+bc 0 0 0 0 0 $rgb(92,92,92),f).addnode

    $dcx.text(%n,5 7,174 4 250 22).add
    $dcx.general(%n,7,+ab,default,-16,Trebuchet MS).font
    $dcx.general(%n,7,+bk,$rgb(240,238,226)).color
    $dcx.general(%n,7,+t,$rgb(92,92,92)).color

    ; Settings

    $dcx.panel(%n,10,100 41 505 265).add
    $dcx.general(%n,10,Global Settings).mark

    $dcx.box(%n,10 101,0 4 121 55,$dcxtab,System).add
    $dcx.general(%n,101,+t,$rgb(107,116,123)).color
    $dcx.comboex(%n,101 102,10 20 101 100,dropdown).add
    $dcx.comboex(%n,102,6 $weathericons).addicon
    $dcx.comboex(%n,102,7 $weathericons).addicon
    $dcx.comboex(%n,102,0,0,1 1 0,Inactive).addnode
    $dcx.comboex(%n,102,0,0,2 2 0,Active).addnode
    $dcx.comboex(%n,102,$iif($focus.weather.setting(status),2,1)).select

    $dcx.box(%n,10 103,120 4 212 55,$dcxtab,Output Queue).add
    $dcx.general(%n,103,+t,$rgb(107,116,123)).color
    $dcx.text(%n,103 104,10 24 70 20,$dcxtab,Frequency:).add
    $dcx.edit(%n,103 105,84 22 50 20,number).add
    $dcx.edit(%n,105,$focus.weather.setting(queuefreq)).value

    $dcx.button(%n,103 106,144 21 57 22,$dcxtab,Purge).add
    $dcx.general(%n,106,+ab,default,-10,Tahoma).font

    $dcx.box(%n,10 108,331 4 174 55,$dcxtab,Socket Threads).add
    $dcx.general(%n,108,+t,$rgb(107,116,123)).color
    $dcx.text(%n,108 109,10 24 36 20,$dcxtab,Max:).add
    $dcx.edit(%n,108 110,49 22 50 20,number).add
    $dcx.edit(%n,110,$focus.weather.setting(socketmaxthreads)).value

    $dcx.button(%n,108 111,109 21 52 22,$dcxtab,Kill).add
    $dcx.general(%n,111,+ab,default,-10,Tahoma).font

    $dcx.button(%n,$+(106,$chr(44),111),+dhns,$rgb(160,0,0)).color

    $dcx.box(%n,10 115,0 59 505 206,$dcxtab,Current Queue).add
    $dcx.general(%n,115,+t,$rgb(107,116,123)).color
    $dcx.list(%n,115 116,10 20 485 176,report singlesel flatsb borderselect fullrow showsel grid).add
    $dcx.list(%n,116,+ 0 30 ID:,+ 0 140 Points To:,+ 0 310 Task:).headers
    $dcx.general(%n,116,+b,$rgb(255,255,255)).color
    $dcx.general(%n,$+(105,$chr(44),110),+a,default,-10,Tahoma).font
    var %queuesize = $focus.weather.queuepointer(stacksize), %pointer = $focus.weather.queuepointer(current)
    while (%pointer > 0 && %pointer <= %queuesize) {
      var %task = $hget($focus.weather.queuehash,%pointer)
      $dcx.list(%n,116,0,0,+ 0 0 0 0 0 0 %pointer,+ 0 $gettok(%task,1,32),+ 0 $gettok(%task,2-,32)).addnode
      inc %pointer
    }
    $dcx.general(%n,10).hide

    ; Channels

    $dcx.panel(%n,15,100 41 505 265).add
    $dcx.general(%n,15,Channel Settings).mark

    $dcx.tree(%n,15 151,0 12 150 191,haslines showsel linesatroot hasbuttons).add
    $dcx.general(%n,151,+,default,-10,Tahoma).font
    $dcx.tree(%n,151,+ns 8 $weathericons).addicon
    $dcx.tree(%n,151,+ns 1 $weathericons).addicon

    $dcx.tree(%n,15 152,0 215 150 50,noscroll disabled).add
    $dcx.tree(%n,152,+b,$rgb(255,255,255)).color
    $dcx.general(%n,152,static).border

    $dcx.panel(%n,15 153,1 216 148 48).add
    $dcx.general(%n,153,+b,$rgb(255,255,255)).color
    $dcx.toolbar(%n,153 1532,0 0 148 24,nodivider flat list).add
    $dcx.toolbar(%n,1532,16).iconsize
    $dcx.toolbar(%n,1532,+ndh 5 $weathericons).addicon
    $dcx.toolbar(%n,1532,+ndh 6 $weathericons).addicon
    $dcx.toolbar(%n,1532,1,+lw 148 1 0,New Channel).addnode
    $dcx.toolbar(%n,1532,2,+lwd 148 2 0,Delete Channel).addnode

    $dcx.box(%n,15 154,162 4 227 50,$dcxtab,Triggers).add
    $dcx.general(%n,154,+t,$rgb(107,116,123)).color
    $dcx.edit(%n,154 155,10 22 206 18,tabstop).add

    $dcx.box(%n,15 156,388 4 117 50,$dcxtab,Request Delay).add
    $dcx.general(%n,156,+t,$rgb(107,116,123)).color
    $dcx.edit(%n,156 157,10 22 41 18,number tabstop).add
    $dcx.text(%n,156 158,60 23 50 20,$dcxtab,seconds).add

    $dcx.box(%n,15 159,162 54 343 50,$dcxtab,Display Message).add
    $dcx.general(%n,159,+t,$rgb(107,116,123)).color
    $dcx.edit(%n,159 160,10 22 323 18,tabstop).add
    $dcx.general(%n,$+(155,$chr(44),157,$chr(44),160),+a,default,-10,Tahoma).font

    $dcx.list(%n,15 161,162 116 140 149,report singlesel borderselect fullrow checkbox tabstop disabled).add
    $dcx.list(%n,161,+ 0 118 Weather Options,+ 0 0 Code).headers
    $dcx.general(%n,161,+b,$rgb(255,255,255)).color
    $dcx.list(%n,161,0,0,+ 0 0 0 0 0 0 Updating...,+ 0 0).addnode
    focus.weather.getcapab

    $dcx.tree(%n,15 162,314 116 191 149,haslines hasbuttons checkbox linesatroot tabstop).add
    $dcx.general(%n,162,+t,$rgb(144,153,158)).color
    $dcx.general(%n,162,+,default,-10,Tahoma).font
    $dcx.tree($dxfm,162,-1,+e 0 0 0 0 0 0,Settings).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Deactivate channel).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Issue limit warnings).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Allow forecasts).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Use CTCP TIME).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Use bold in message).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Show weather alerts).addnode
    $dcx.tree($dxfm,162,-1,+e 0 0 0 0 0 0,Message Protocol).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Channel Message).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Private Message).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Channel Notice).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Private Notice).addnode
    $dcx.tree($dxfm,162,-1,+e 0 0 0 0 0 0,Standards Systems).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Imperial (USA)).addnode
    $dcx.tree($dxfm,162,-1 -1,+ 0 0 0 1 0 0,Metric (World)).addnode
    $dcx.general(%n,15).hide

    ; Lookup

    $dcx.panel(%n,20,100 41 505 265).add
    $dcx.general(%n,20,Personal Lookup).mark

    $dcx.box(%n,20 201,0 4 505 55,$dcxtab,Your Query).add
    $dcx.general(%n,201,+t,$rgb(107,116,123)).color
    $dcx.edit(%n,201 202,10 24 390 18).add
    $dcx.general(%n,202,+a,default,-10,Tahoma).font
    $dcx.button(%n,201 203,410 22 82 22,$dcxtab,Lookup).add
    $dcx.general(%n,203,+ab,default,-10,Tahoma).font
    $dcx.button(%n,203,+dhns,$rgb(92,92,92)).color

    $dcx.box(%n,20 204,0 59 505 206,$dcxtab,Results).add
    $dcx.general(%n,204,+t,$rgb(107,116,123)).color
    $dcx.webcontrol(%n,204 205,10 24 485 172).add
    $dcx.webcontrol(%n,205,$+(http://,$focus.weather.setting(server),:,$focus.weather.setting(port),$remove($focus.weather.setting(getlookup),!zone!))).src
    $dcx.general(%n,20).hide

    ; Help

    $dcx.panel(%n,25,100 41 505 265).add
    $dcx.general(%n,25,Help).mark

    $dcx.tree(%n,25 251,0 12 150 253,haslines hasbuttons showsel linesatroot notooltips tabstop).add
    $dcx.general(%n,251,+,default,-10,Tahoma).font
    $dcx.tree($dxfm,251,-1,+be 0 0 0 0 0 0,Options).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,System).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Output Queue).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Socket Threads).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Current Queue).addnode
    $dcx.tree($dxfm,251,-1,+be 0 0 0 0 0 0,Channels).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Triggers).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Request Delay).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Display Message).addnode
    $dcx.tree($dxfm,251,-1 -1,+ 0 0 0 0 0 0,Weather Options).addnode
    $dcx.tree($dxfm,251,-1 -1,+be 0 0 0 0 0 0,Settings).addnode
    $dcx.tree($dxfm,251,-1 -1 -1,+ 0 0 0 0 0 0,Deactivate Channel).addnode
    $dcx.tree($dxfm,251,-1 -1 -1,+ 0 0 0 0 0 0,Issue Limit Warnings).addnode
    $dcx.tree($dxfm,251,-1 -1 -1,+ 0 0 0 0 0 0,Allow Forecasts).addnode
    $dcx.tree($dxfm,251,-1 -1 -1,+ 0 0 0 0 0 0,Use CTCP TIME).addnode
    $dcx.tree($dxfm,251,-1 -1 -1,+ 0 0 0 0 0 0,Use bold in message).addnode
    $dcx.tree($dxfm,251,-1 -1 -1,+ 0 0 0 0 0 0,Show weather alerts).addnode
    $dcx.tree($dxfm,251,-1 -1,+b 0 0 0 0 0 0,Message Protocol).addnode
    $dcx.tree($dxfm,251,-1 -1,+b 0 0 0 0 0 0,Standards System).addnode
    $dcx.tree($dxfm,251,-1,+be 0 0 0 0 0 0,About This Script).addnode

    $dcx.webcontrol(%n,25 252,162 12 343 253).add
    $dcx.webcontrol(%n,252,$+(http://,$focus.weather.setting(server),:,$focus.weather.setting(port),$focus.weather.setting(gethelp))).src
    $dcx.general(%n,25).hide

    focus.weather.gotosection %:gotosection
    if (%:gotochannel) { focus.weather.gotochannel %:gotochannel | unset %:gotochannel }
    unset %:gotosection
    $dcx.dialog(%n,+a).animate
  }
}

; -------------- ------ --- - - --- -------- --- - --
; Dialog Control Aliases
; -------------- ------ --- - - --- -------- --- - --

alias fwconfig { focus.weather.configdialog $1- }
alias -l focus.weather.configdialog { 
  if ($1 == --channels) { 
    %:gotosection = 2 
    if ($0 == 3) { %:gotochannel = $2- }
  }
  elseif ($1 == --lookup) { %:gotosection = 3 }
  elseif ($1 == --help) { %:gotosection = 4 }
  else { %:gotosection = 1 }

  if (!$dialog($dxfm)) {
    safedialog focus.weather
  }
  else {
    focus.weather.gotosection %:gotosection
    if (%:gotochannel) { focus.weather.gotochannel %:gotochannel }
    unset %:goto*
  }
}
alias -l safedialog { dialog $iif($dialog($1),-v,-m $1) $iif($0 == 2,$2,$1) }
alias -l isdcx { if ($isfile($lfn($scriptdirdcx\dcx.dll))) { return $true } | else { return $false } }
alias -l dcx {
  if ($isid) { return $dll($lfn($scriptdirdcx\dcx.dll),$1,$2-) }
  else { dll $lfn($scriptdirdcx\dcx.dll) $1- }
}
alias -l weathericons { return $scriptdirimg\icons.icl }
alias udcx { dll -u dcx.dll }
alias -l dcxtab { return $chr(9) }
alias -l dcxids {
  if ($isid) {
    var %j = $0, %i = 1, %res
    while (%i <= %j) {
      var %res = $addtok(%res,$ [ $+ [ %i ] ],44)
      inc %i
    }
    return %res
  }
}

alias -l xdid {
  if ($isid) { return $dcx(_xdid,$1 $2 $prop $3-) }
  else { dcx xdid $2 $3 $1 $4- | if ($dbg) { echo -a xdid $replace($1-,$dcxtab,$+($chr(32),$,+,$chr(32),$,chr(9),$chr(32),$,+,$chr(32))) } }
}
alias -l xdialog {
  if ($isid) { if ($dbg) { echo -a $ $+ xdialog( $+ $1 $+ , $+ $2- $+ ). $+ $prop } | return $dcx(_xdialog,$1 $prop $2-) }
  else { dcx xdialog $2 $1 $3- | if ($dbg) { echo -a xdialog $replace($1-,$dcxtab,$+($chr(32),$,+,$chr(32),$,chr(9),$chr(32),$,+,$chr(32))) } }
}

alias -l xdlg { if ($dialog($1)) { $2- } | else { safedialog $1 | $2- } }
alias -l _dxfm {
  if ($isid) { return $dxfm(-recurse,$chgtok($1-,32,172)) }
  else { dxfm $1- }
}
alias -l dxfm {
  if ($isid) {
    if ($1 == -recurse) { 
      tokenize 172 $2
    }
    if ($0 == 0) { return focus.weather }
    else {
      var %prop = $iif($prop,$ifmatch,text)
      if ($0 == 2) { return $xdid($_fm,$1,$2). [ $+ [ %prop ] ] }
      else { return $xdid($_dxfm,$1). [ $+ [ %prop ] ] }
    }
  }
  else {
    dlg $_dxfm xdid $1 $_dxfm $2-
  }
}

alias focus.weather.dcxcallback {

  var %dname = $1
  var %devent = $2
  var %did = $3
  if (%devent == sclick) {
    if (%did == 2) {
      if ($4 != 5) { focus.weather.gotosection $4 }
      else {
        var %oldchannel = $dcx.general($dxfm,151).mark
        if (%oldchannel) {
          ; Save
          focus.weather.savechannel $focus.weather.locations($gettok(%oldchannel,2,32)).network $gettok(%oldchannel,1,32)
        }
        $focus.weather.setting(status,$xdid(%dname,102).sel)
        $focus.weather.setting(queuefreq,$dcx.edit(%dname,105).value)
        $focus.weather.setting(socketmaxthreads,$dcx.edit(%dname,110).value)

        focus.weather.queue start
        focus.weather.gettriggers
        dialog -x %dname 
      }
    }
    if (%did == 106) {
      if ($input(Are you sure you want to Purge the queue? This will remove all waiting actions from the queue. People who requested weather will not receive it. This may cause undesired effects. $crlf $crlf Are you sure?,yvgwd,Confirm Queue Purge) == $yes) {
        $focus.weather.queue().regclear
        $focus.weather.queue().queueclear
        $focus.weather.queue().reqclear
        $dcx.general(%dname,116).clear
      }
    }
    if (%did == 111) {
      if ($input(Are you sure you want to Kill all weather sockets? This will prematurely abort all weather connections and may also cause a queue desync. $crlf $crlf Are you sure?,yvgwd,Confirm Socket Kill) == $yes) {
        .sockclose focus.weather.retrieve.*
      }
    }
    if (%did == 151) {
      var %path = $4-
      if ($numtok(%path,32) > 1) {
        var %channel = $xdid($dxfm,151,%path).text %path
        var %oldchannel = $dcx.general($dxfm,151).mark
        if (%oldchannel && %oldchannel != %channel) {
          ; Save
          focus.weather.savechannel $focus.weather.locations($gettok(%oldchannel,2,32)).network $gettok(%oldchannel,1,32)
        }
        if (%channel && %channel != %oldchannel) {
          ; Load
          focus.weather.clearchannel
          focus.weather.loadchannel $focus.weather.locations($gettok(%channel,2,32)).network $gettok(%channel,1,32) %channel
        }
      }
      else {
        var %oldchannel = $dcx.general($dxfm,151).mark
        if (%oldchannel) {
          ; Save
          focus.weather.savechannel $focus.weather.locations($gettok(%oldchannel,2,32)).network $gettok(%oldchannel,1,32)
        }
        focus.weather.clearchannel
      }
    }
    if (%did == 203) {
      $dcx.webcontrol(%dname,205,$+(http://,$focus.weather.setting(server),:,$focus.weather.setting(port),$replace($focus.weather.setting(getlookup),!zone!,$xdid(%dname,202).text))).src
    }
    if (%did == 251) {
      $dcx.webcontrol(%dname,252,$+(http://,$focus.weather.setting(server),:,$focus.weather.setting(port),$focus.weather.setting(gethelp),$4-)).src
    }
    if (%did == 1532) {
      if ($4 == 1) {
        ; New
        focus.weather.newchannel
      }
      if ($4 == 2) {
        ; Delete
        var %channel = $dcx.general($dxfm,151).mark
        if (%channel) {
          focus.weather.delchannel $focus.weather.locations($gettok(%channel,2,32)).network $gettok(%channel,1,32)
        }
      }
    }
  }
}

alias -l focus.weather.savechannel {
  $focus.weather.setting($1,$2,triggers,$dcx.edit($dxfm,155).value)
  $focus.weather.setting($1,$2,requestwait,$dcx.edit($dxfm,157).value)
  $focus.weather.setting($1,$2,displaymessage,$dcx.edit($dxfm,160).value)
  $focus.weather.register($+($1,¬triggers¬,$2),$dcx.edit($dxfm,155).value)

  ; Weather Options
  var %mytoks = $focus.weather.setting($1,$2,capab)
  var %options = $xdid($dxfm,161).num, %option = 1, %saved
  while (%option <= %options) {
    var %code = $xdid($dxfm,161,%option,1).text
    if ($dcx.list($dxfm,161,%option).state) {
      var %saved = $addtok(%saved,%code,32)
    }
    inc %option
  }
  $focus.weather.setting($1,$2,capab,%saved)

  ; Settings Tree
  $focus.weather.setting($1,$2,inactive,$dcx.tree($dxfm,162,1 1).state)
  $focus.weather.setting($1,$2,limitwarnings,$dcx.tree($dxfm,162,1 2).state)
  $focus.weather.setting($1,$2,forecasts,$dcx.tree($dxfm,162,1 3).state)
  $focus.weather.setting($1,$2,ctcpforecasts,$dcx.tree($dxfm,162,1 4).state)
  $focus.weather.setting($1,$2,usebold,$dcx.tree($dxfm,162,1 5).state)
  $focus.weather.setting($1,$2,showalerts,$dcx.tree($dxfm,162,1 6).state)
  $focus.weather.setting($1,$2,cm,$dcx.tree($dxfm,162,2 1).state)
  $focus.weather.setting($1,$2,pm,$dcx.tree($dxfm,162,2 2).state)
  $focus.weather.setting($1,$2,cn,$dcx.tree($dxfm,162,2 3).state)
  $focus.weather.setting($1,$2,pn,$dcx.tree($dxfm,162,2 4).state)
  $focus.weather.setting($1,$2,imperial,$dcx.tree($dxfm,162,3 1).state)
  $focus.weather.setting($1,$2,metric,$dcx.tree($dxfm,162,3 2).state)
}

alias -l focus.weather.loadchannel {
  if ($0 > 2) { $dcx.general($dxfm,151,$3-).mark }
  $dcx.text($dxfm,7,- $2).set
  $dcx.general($dxfm,$dcxids(155,157,160,161,162)).enable

  $dcx.edit($dxfm,155,$focus.weather.setting($1,$2,triggers)).value
  $dcx.edit($dxfm,157,$focus.weather.setting($1,$2,requestwait)).value
  $dcx.edit($dxfm,160,$focus.weather.setting($1,$2,displaymessage)).value

  ; Weather Options
  var %mytoks = $focus.weather.setting($1,$2,capab)
  var %options = $xdid($dxfm,161).num, %option = 1, %saved
  if ($xdid($dxfm,161,%option,0).text != Updating...) {
    while (%option <= %options) {
      var %code = $xdid($dxfm,161,%option,1).text
      if ($istok(%mytoks,%code,32)) {
        var %saved = $addtok(%saved,%code,32)
        $dcx.list($dxfm,161,1,%option).state
      }
      else {
        $dcx.list($dxfm,161,0,%option).state
      }
      inc %option
    }
    $focus.weather.setting($1,$2,capab,%saved)
  }

  ; Settings Tree
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,inactive),1 1).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,limitwarnings),1 2).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,forecasts),1 3).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,ctcpforecasts),1 4).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,usebold),1 5).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,showalerts),1 6).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,cm),2 1).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,pm),2 2).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,cn),2 3).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,pn),2 4).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,imperial),3 1).state
  $dcx.tree($dxfm,162,$focus.weather.setting($1,$2,metric),3 2).state
  $dcx.toolbar($dxfm,1532,2,+).state
}

alias -l focus.weather.clearchannel {
  $dcx.text($dxfm,7).set

  $dcx.general($dxfm,$dcxids(155,157,160,161,162)).disable
  $dcx.general($dxfm,155).clear
  $dcx.general($dxfm,157).clear
  $dcx.general($dxfm,160).clear

  var %options = $xdid($dxfm,161).num, %option = 1
  while (%option <= %options) {
    $dcx.list($dxfm,161,1,%option).state
    inc %option
  }

  var %root = $calc($xdid($dxfm,162,root).num - 1)
  while (%root) {
    var %children = $calc($xdid($dxfm,162,%root).num - 1)
    while (%children) {
      $dcx.tree($dxfm,162,0,%root %children).state
      dec %children
    }
    dec %root
  }
  $dcx.toolbar($dxfm,1532,2,+d).state
  $dcx.general($dxfm,151,0).mark
}

alias -l focus.weather.newchannel {
  if ($0 < 2) {
    var %data = $input(Please enter the channel's address in the following format: $crlf $crlf $chr(9) <network> <#channelname>,eo,Add channel)
    if (%data) { tokenize 32 %data }
    else { return }
  }

  if ($0 < 2) { return }

  if ($focus.weather.setting($1,$2,inactive) isnum) { .echo -q $input($2 on $1 is already in your channel list.,oid,Channel Exists) | return }

  var %items = $ini($focus.weather.inifile(config),Default/Settings,0), %item = 1
  while (%item <= %items) {
    var %setting = $ini($focus.weather.inifile(config),Default/Settings,%item)
    var %value = $focus.weather.setting(Default,Settings,%setting)
    $focus.weather.setting($1,$2,%setting,%value)
    inc %item
  }

  if ($dialog($dxfm)) {
    var %oldchannel = $dcx.general($dxfm,151).mark
    if (%oldchannel) {
      ; Save
      focus.weather.savechannel $focus.weather.locations($gettok(%oldchannel,2,32)).network $gettok(%oldchannel,1,32)
    }
    focus.weather.loadsection 2
    focus.weather.gotochannel $1 $2
  }
  else {
    focus.weather.configdialog --channels $1-
  }
}

alias -l focus.weather.delchannel {
  if ($1-2 == Default Settings) { return }
  if (!$input(Are you sure you want to delete the channel $2 from the $1 network? This cannot be undone.,ygqd,Confirm Delete)) { return }
  $focus.weather.register($+($1,¬triggers¬,$2)).del
  $focus.weather.setini($+($1,/,$2))
  focus.weather.loadsection 2
}

alias -l focus.weather.gotochannel {
  var %networks = $focus.weather.locations(0).network, %network = 1
  while (%network <= %networks) {
    var %netname = $focus.weather.locations(%network).network
    if ($1 == %netname) {
      var %channels = $focus.weather.locations(%network,0).chan, %channel = 1
      while (%channel <= %channels) {
        if ($2 == $focus.weather.locations(%network,%channel).chan) {
          var %oldchannel = $dcx.general($dxfm,151).mark
          $dcx.general($dxfm,151,$2 %network %channel).mark
          if (%oldchannel) {
            ; Save
            focus.weather.savechannel $focus.weather.locations($gettok(%oldchannel,2,32)).network $gettok(%oldchannel,1,32)
          }
          $dcx.tree($dxfm,151,%network %channel).select
          focus.weather.loadchannel $1-
          return
        }
        inc %channel
      }
      return
    }
    inc %network
  }
}

alias -l focus.weather.loadsection {
  if ($1 == 2) {
    $dcx.general($dxfm,7).show
    $dcx.general($dxfm,151).clear
    var %networks = $focus.weather.locations(0).network, %network = 1
    while (%network <= %networks) {
      var %netname = $focus.weather.locations(%network).network
      $dcx.tree($dxfm,151,-1,+eb 1 1 0 0 0 0,%netname).addnode
      var %channels = $focus.weather.locations(%network,0).chan, %channel = 1
      while (%channel <= %channels) {
        $dcx.tree($dxfm,151,-1 -1,+ 2 2 0 0 0 0,$focus.weather.locations(%network,%channel).chan).addnode
        inc %channel
      }
      inc %network
    }
    $dcx.tree($dxfm,151,1).select
    focus.weather.clearchannel
  }
  else {
    $dcx.general($dxfm,7).hide
  }
}

alias -l focus.weather.setsection {
  $dcx.tree($dxfm,6,1,$1-).rename
}

alias -l focus.weather.gotosection {
  var %panel = $calc(5 + ($1 * 5))
  var %oldpanel = $dcx.general($dxfm,2).mark
  if (%oldpanel && %oldpanel != %panel) {
    $dcx.general($dxfm,%oldpanel).hide
  }
  if (%panel && %panel != %oldpanel) {
    $dcx.general($dxfm,2,%panel).mark
    $dcx.general($dxfm,%panel).show
  }
  var %toolitems = $xdid($dxfm,2).num
  while (%toolitems) {
    $dcx.toolbar($dxfm,2,%toolitems,+w).state
    dec %toolitems
  }
  $dcx.toolbar($dxfm,2,$1,+wp).state
  focus.weather.loadsection $1
  if (%panel) { focus.weather.setsection $dcx.general($dxfm,%panel).mark }
}

; -------------- ------ --- - - --- -------- --- - --
; DCX Control Abstraction
; -------------- ------ --- - - --- -------- --- - --

alias dcx.getopts {
  var %tok = $2
  if ($left($1,1) == $chr(9)) {
    if (%tok == 1) { return $null }
    if (%tok > 1) { dec %tok }
    return $gettok($1,%tok,9)
  }
  else {
    return $gettok($1,%tok,9)
  }
}

alias dcx.dialog {
  if ($prop == mark) {
    return $dcx(Mark,$1 $2)
  }
  if ($prop == styles) {
    xdialog -b $1 $2-
  }
  if ($prop == animate) {
    xdialog -a $1 $2-
  }
  if ($prop == update) {
    if ($0 == 2) { var %cmd = $+(.tim,er -m 1 $2 xdialog -l) }
    else { var %cmd = xdialog -l }
    %cmd $1 update
  }
  if ($prop == color) {
    xdialog -g $1 $2 $3-
  }
  if ($prop == cells) {
    xdialog -l $1 $2 $dcxtab $3-
  }
}

alias dcx.panel {
  if ($prop == add) {
    $dcx.general(panel,$1,$2,$3,$4-).add
  }
}

alias dcx.image {
  if ($prop == add) {
    $dcx.general(image,$1,$2,$3,$4-).add
  }
  if ($prop == set) {
    xdid -i $1 $2 $3-
  }
}

alias dcx.button {
  if ($prop == add) {
    var %settings = $dcx.getopts($4-,1)
    var %value = $dcx.getopts($4-,2)
    var %id = $iif($numtok($2,32) > 1,$gettok($2,2,32),$2)
    if ($numtok($4-,9) == 1 && $chr(9) isin $4) { var %value = $5- }
    if (*Save iswm $1-) { echo -a 04 $+ settings: %settings }
    $dcx.general(button,$1,$2,$3,%settings).add
    if (%value) { $dcx.general($1,%id,%value).text | $dcx.general($1,%id,+,default,10,Tahoma).font }
  }
  if ($prop == iconsize) {
    xdid -l $1 $2 $3-
  }
  if ($prop == icon) {
    xdid -w $1 $2 $3-
  }
  if ($prop == color || $prop == image) {
    xdid -k $1 $2 $3-
  }
}

alias dcx.rebar {
  if ($prop == add) {
    $dcx.general(rebar,$1,$2,$3,$4-).add
  }
  if ($prop == addband) {
    xdid -a $1 $2 $+($3-4,$dcxtab,$5,$dcxtab,$6)
  }
}

alias dcx.list {
  if ($prop == add) {
    $dcx.general(listview,$1,$2,$3,$4-).add
  }
  if ($prop == headers) {
    var %headers = $0
    var %header = 3
    var %line 
    while (%header <= %headers) {
      var %thisheader = $ [ $+ [ $calc(%header) ] ]
      var %line = $addtok(%line,%thisheader,9)
      inc %header
    }
    xdid -t $1 $2 %line
  }
  if ($prop == addnode) {
    var %nodes = $0
    var %node = 5
    var %line 
    while (%node <= %nodes) {
      var %thisnode = $ [ $+ [ $calc(%node) ] ]
      var %line = $addtok(%line,%thisnode,9)
      inc %node
    }
    xdid -a $1-4 %line
  }
  if ($prop == delnode) {
    xdid -d $1 $2 $3
  }
  if ($prop == color) {
    xdid -i $1 $2 $3-
  }
  if ($prop == background) {
    xdid -g $1 $2 $3-
  }
  if ($prop == addicon) {
    xdid -w $1 $2 $3-
  }
  if ($prop == seticon) {
    xdid -l $1 $2 $3 $4 $5
  }
  if ($prop == select) {
    xdid -c $1 $2 $3-
  }
  if ($prop == sort) {
    xdid -z $1 $2 $3-
  }
  if ($prop == state) {
    if ($0 == 4) {
      xdid -k $1 $2 $iif($3 == 1,2,1) $4
    }
    else {
      return $iif($xdid($1,$2,$3).state == 2,1,0)
    }
  }
}

alias dcx.comboex {
  if ($prop == add) {
    $dcx.general(comboex,$1,$2,$3,$4-).add
  }
  if ($prop == addnode) {
    xdid -a $1 $2 $3-
  }
  if ($prop == select) {
    xdid -c $1 $2 $3
  }
  if ($prop == addicon) {
    xdid -w $1 $2 $3-
  }
  if ($prop == seltext) {
    return $xdid($1,$2).seltext
  }
  if ($prop == sel) {
    return $xdid($1,$2).sel
  }
}

alias dcx.tree {
  if ($prop == add) {
    $dcx.general(treeview,$1,$2,$3,$4-).add
  }
  if ($prop == addnode) {
    xdid -a $1 $2 $+($3,$dcxtab,$4 $5,$dcxtab,$6)
  }
  if ($prop == color) {
    xdid -i $1 $2 $3-
  }
  if ($prop == select) {
    xdid -c $1 $2 $3-
  }
  if ($prop == toggle) {
    xdid -t $1 $2 $3-
  }
  if ($prop == expand) {
    xdid -t $1 $2 +e $3-
  }
  if ($prop == aexpand) {
    xdid -t $1 $2 +a $3-
  }
  if ($prop == pexpand) {
    xdid -t $1 $2 +p $3-
  }
  if ($prop == rename) {
    xdid -v $1 $2 $+($3,$dcxtab,$4)
  }
  if ($prop == addicon) {
    xdid -w $1 $2 $3-
  }
  if ($prop == seticon) {
    xdid -l $1 $2 $+($3,$dcxtab,$4)
  }
  if ($prop == seltext) {
    return $xdid($1,$2).seltext
  }
  if ($prop == selpath) {
    return $xdid($1,$2).selpath
  }
  if ($prop == state) {
    if ($0 == 4) {
      xdid -k $1 $2 $iif($3 == 1,2,1) $4
    }
    else {
      return $iif($xdid($1,$2,$3).state == 2,1,0)
    }
  }
}

alias dcx.text {
  if ($prop == add) {
    var %settings = $dcx.getopts($4-,1)
    var %value = $dcx.getopts($4-,2)
    var %id = $iif($numtok($2,32) > 1,$gettok($2,2,32),$2)
    if ($numtok($4-,9) == 1 && $chr(9) isin $4) { var %value = $5- }
    $dcx.general(text,$1,$2,$3,%settings).add
    if (%value) { $dcx.general($1,%id,%value).text | $dcx.general($1,%id,+,default,10,Tahoma).font }
  }
  if ($prop == set) {
    xdid -t $1 $2 $iif($0 > 2,$3-)
  }
  if ($prop == get) {
    return $xdid($1,$2).text
  }
}

alias dcx.check {
  if ($prop == add) {
    var %settings = $dcx.getopts($4-,1)
    var %value = $dcx.getopts($4-,2)
    var %id = $iif($numtok($2,32) > 1,$gettok($2,2,32),$2)
    if ($numtok($4-,9) == 1 && $chr(9) isin $4) { var %value = $5- }
    $dcx.general(check,$1,$2,$3,%settings).add
    if (%value) { $dcx.general($1,%id,%value).text | $dcx.general($1,%id,+,default,10,Tahoma).font }
  }
  if ($prop == set) {
    xdid -t $1 $2 $3-
  }
  if ($prop == get) {
    return $xdid($1,$2).text
  }
}

alias dcx.webcontrol {
  if ($prop == add) {
    $dcx.general(webctrl,$1,$2,$3,$4-).add
  }
  if ($prop == src) {
    xdid -n $1 $2 $3-
  }
}

alias dcx.edit {
  if ($prop == add) {
    $dcx.general(edit,$1,$2,$3,$4-).add
  }
  if ($prop == value) {
    if ($0 == 3) {
      xdid -r $1 $2
      if ($3 !== $null) { xdid -a $1 $2 $3- }
    }
    else { return $xdid($1,$2).text }
  }
}

alias dcx.progressbar {
  if ($prop == add) {
    $dcx.general(pbar,$1,$2,$3,$4-).add
  }
  if ($prop == value) {
    xdid -v $1 $2 $3
  }
  if ($prop == stepsize) {
    xdid -u $1 $2 $3
  }
  if ($prop == range) {
    xdid -r $1 $2 $3 $4
  }
  if ($prop == addstep) { 
    xdid -t $1 $2
  }
  if ($prop == style) {
    xdid -j $1 $2 $iif($left($3,1),$ifmatch,p)
  }
  if ($prop == text) {
    xdid -i $1 $2 $3-
  }
  if ($prop == color) {
    xdid -c $1 $2 $3
  }
  if ($prop == background) {
    xdid -k $1 $2 $3
  }
}

alias dcx.line {
  if ($prop == add) {
    $dcx.general(line,$1,$2,$3,$4-).add
  }
}

alias dcx.toolbar {
  if ($prop == add) {
    $dcx.general(toolbar,$1,$2,$3,$4-).add
  }
  if ($prop == addnode) {

    if ($numtok($5-,9) < 2) {
      if ($right($5-,1) == $chr(9) || $chr(9) !isin $5-) { var %text = $gettok($5-,1,9) }
      if ($left($5-,1) == $chr(9)) { var %tooltip = $gettok($5-,2,9) }
    }
    else {
      var %text = $gettok($5-,1,9)
      var %tooltip = $gettok($5-,2,9)
    }
    xdid -a $1 $2 $3 $4 %text $dcxtab %tooltip
  }
  if ($prop == clearicons) {
    xdid -l $1 $2
  }
  if ($prop == addicon) {
    xdid -w $1 $2 $3-
  }
  if ($prop == iconsize) {
    xdid -l $1 $2 $3
  }
  if ($prop == clear) {
    xdid -r $1 $2
  }
  if ($prop == state) {
    xdid -t $1 $2 $3 $4
  }
  if ($prop == autostretch) {
    xdid -m $1 $2 $iif($3 == on,1,0)
  }
}

alias dcx.box {
  if ($prop == add) {
    var %settings = $dcx.getopts($4-,1)
    var %value = $dcx.getopts($4-,2)
    var %id = $iif($numtok($2,32) > 1,$gettok($2,2,32),$2)
    if ($numtok($4-,9) == 1 && $chr(9) isin $4) { var %value = $5- }
    $dcx.general(box,$1,$2,$3,%settings).add
    if (%value) { $dcx.general($1,%id,%value).text | $dcx.general($1,%id,+,default,10,Tahoma).font }
  }
}

alias dcx.general {
  if ($prop == add) {
    if ($numtok($3,32) > 1) {
      xdid -c $2 $3 $1 $4-
    }
    else {
      xdialog -c $2 $3 $1 $4-
    }
  }
  if ($prop == font) {
    xdid -f $1 $2 $3-
  }
  if ($prop == show) {
    xdid -s $1 $2
  }
  if ($prop == hide) {
    xdid -h $1 $2
  }
  if ($prop == enable) {
    xdid -e $1 $2
  }
  if ($prop == disable) {
    xdid -b $1 $2
  }
  if ($prop == border) {
    var %bs = $3
    var %bs = $replace(%bs,regular,b)
    var %bs = $replace(%bs,client,c)
    var %bs = $replace(%bs,frame,d)
    var %bs = $replace(%bs,modalframe,f)
    var %bs = $replace(%bs,static,s)
    var %bs = $replace(%bs,window,w)
    var %bs = $replace(%bs,$chr(32),)
    var %bs = $+(+,%bs)

    xdid -x $1 $2 %bs
  }
  if ($prop == mark) {
    if ($0 == 3) {
      xdid -M $1 $2 $3
    }
    else {
      return $xdid($1,$2).mark
    }
  }
  if ($prop == text) {
    xdid -t $1 $2 $3-
  }
  if ($prop == clear) {
    xdid -r $1 $2
  }
  if ($prop == color) {
    xdid -C $1 $2 $3-
  }
  if ($prop == cells) {
    xdid -l $1 $2 $3 $dcxtab $4-
  }
}