# Copyright (c) 2006 Oliver Heins <olli@sopos.org>
#      http://sopos.org/olli/
# using work from Mauricio Fernandez <mfp@acm.org> 
#      http://eigenclass.org/hiki.rb?wmii+ruby
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# You may also redistribute this program under the same terms as Ruby 
# (see LICENSE).
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ===========================================================================
#
#{{{ Core bindings and applets defined as the "olli@sopos.org" plugin
# 
# This file must be placed in $HOME/.wmii-3/plugins.
# ===========================================================================

Plugin.define "olli@sopos.org"  do
  author '"Oliver Heins" <olli@sopos.org>'

  #{{{ Volume control
  bar_applet("volume", 990) do |wmii, bar|
    mixers = wmii.plugin_config["standard:volume"]["mixer"] || ["Master"]
    mixers = [mixers] if !(Array === mixers)
    update_volume = lambda do |increment|
      if mixers.empty?
        bar.data = "VOL OFF"
        return
      end
      sign = increment < 0 ? "-" : "+"
      status = ''
      mixers.reverse.each do |mixer| # show status of first mixer in list
        status = `amixer set "#{mixer},0" #{increment.abs}#{sign}`
      end
      volume = status [/\[(\d+%)\]/]
      volume = "OFF" if status[/\[off\]/]
      bar.data = "VOL #{volume}"
    end
    Thread.new{ loop { update_volume[0]; sleep 10 } }

    term = wmii.plugin_config["standard"]["x-terminal-emulator"] || "xterm"
    bar.on_click(MOUSE_SCROLL_UP){ update_volume[+1] }
    bar.on_click(MOUSE_SCROLL_DOWN){ update_volume[-1] }
    wmii.on_key("XF86AudioRaiseVolume") { update_volume[+1] }
    wmii.on_key("XF86AudioLowerVolume") { update_volume[-1] }
    bar.on_click(MOUSE_BUTTON_LEFT) do
      handler = wmii.on_createclient do |cid|
        wmii.write("/view/sel/sel/ctl", "sendto 0")
        wmii.write("/view/sel/sel/geom", "0 100 east south-100")
        wmii.unregister handler
      end
      system "wmiisetsid #{term} -e alsamixer &"
    end
    bar.on_click(MOUSE_BUTTON_RIGHT) do
      action = case `amixer get "#{mixers.first},0"`
      when /\[off\]/: 'unmute'
      when /\[on\]/ : 'mute'
      end
      mixers.each do |mixer|
        `amixer set "#{mixer},0" #{action}`
      end
      update_volume[0]
    end
  end

  # {{{ Weather
  bar_applet("weather", 0) do |wmii, bar|
    require 'net/http'
    require 'time'
    ausgabe = ""
    Thread.new do
      agent = 'ruby-wmii #{WMIIRC_VERSION} (#{WMIIRC_RELEASE_DATE})'
      metar = wmii.plugin_config["ollis-plugins:weather"]["metar"] || ["eddv"]
      metar = metar.to_s
      loop do
        http = Net::HTTP.new('weather.noaa.gov', 80)
        page = http.start do
          req = Net::HTTP::Get.new('http://weather.noaa.gov/pub/data/observations/metar/decoded/'+metar.upcase+'.TXT', 'User-Agent' => agent)
          http.request(req).body
        end
        page = page.to_a
        page[0] = "Location: " + page[0].chomp
        page[1] = "Date: " + page[1].chomp
        feld = Hash.new
        feld["Wind"], feld["Relative Humidity"], feld["Sky conditions"] = '','','';
        page.each do |line|
          name, wert = line.split(/\s*:\s*/, 2)
          feld[name] = wert
        end
        temperature = feld["Temperature"].scan(/\((.+)\)/).to_s
        temperature.sub!(/ /,  '° ')
        ort = feld["Location"].scan(/(^[^)]+\))/).to_s
        date = feld["Date"].scan(/\/ ([0-9]{4})\.([0-9]{2})\.([0-9]{2}) ([0-9]{2})([0-9]{2}) UTC/)
        year, month, day, hour, minute = date[0][0..4]
        gmt_time = Time.gm(year, month, day, hour, minute, 0)
        localtime =  gmt_time.localtime
        bar.data = temperature.chomp
        ausgabe = <<EOF
Current conditions at #{ort}
Last updated #{localtime}
Wind: #{feld["Wind"].chomp}
Temperature: #{temperature}
Relative Humidity: #{feld["Relative Humidity"].chomp}
Sky conditions: #{feld["Sky conditions"].chomp}
EOF
        sleep 15*60
      end
    end
    xmessagebox = "xmessage -center -buttons quit:0 -default quit -file -"
    fl = lambda{ wmii.write "/view/ctl", "select 0" }
    toggle_fl = lambda{ sleep 2; wmii.write "/view/ctl", "select toggle" }
    bar.on_click(MOUSE_BUTTON_LEFT){ fl[]; system "echo '#{ausgabe}' | wmiisetsid #{xmessagebox} &"; toggle_fl[] }
  end
  
  # {{{ Amarok:np
  bar_applet("now_playing", 0, "-- Now Playing --") do |wmii, bar|
    Thread.new do
      np_maxlength = 35
      nixplaying = "Nothing"
      np_toleranz = 3
      np_toleranz_akt = 0
      loop do
        t = `ps | grep amarok|grep -v grep`
        np_text = if t.length > 1 then `cat ~/.nowplaying`
                  else nixplaying end
        np_text = nixplaying if np_text.length < 2
        if np_text.length <= np_maxlength + np_toleranz
          np_toleranz_akt = np_toleranz
          np_dots = ""
        else
          np_toleranz_akt = -3
          np_dots = "..."
        end
        bar.data = np_text[0,np_maxlength+np_toleranz_akt]+np_dots
        sleep 5
      end
    end
    xmessagebox = "xmessage -center -buttons quit:0 -default quit -file -"
    fl = lambda{ wmii.write "/view/ctl", "select 0" }
    toggle_fl = lambda{ sleep 2; wmii.write "/view/ctl", "select toggle" }
    bar.on_click do |name, button|
      current = wmii.curr_view_index
      case button.to_i
      when MOUSE_BUTTON_LEFT:  wmii.set_curr_view "amarok" unless wmii.curr_view == "amarok"
      when MOUSE_BUTTON_RIGHT: fl[]; system "cat ~/.nowplaying | wmiisetsid #{xmessagebox} &"; toggle_fl[] 
      end
    end
  end

  #{{{ Clipboard
  def_settings "clipboard/no_of_buff,refresh_period,selection,sel_buffer,selected}" do |wmii|
    wmii.plugin_config["ollis-plugins:clipboard"]["no_of_buff"] ||= 10
    wmii.plugin_config["ollis-plugins:clipboard"]["refresh_period"] ||= 1
    wmii.plugin_config["ollis-plugins:clipboard"]["selection"] = ''
    wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"] = Array.new
    wmii.plugin_config["ollis-plugins:clipboard"]["mouseclick_prog"] ||= "true"
  end
  bar_applet("clipboard", 50) do |wmii, bar|
    Thread.new do
      loop do
        selection ||= `wmiipsel`.strip # wmiipsel is much faster than xclip
        if selection != wmii.plugin_config["ollis-plugins:clipboard"]["selection"]
          LOGGER.debug "new selection: #{selection}"
          wmii.plugin_config["ollis-plugins:clipboard"]["selection"] = selection
          wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"].push(selection)
          wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"].uniq!
          if wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"].length > wmii.plugin_config["ollis-plugins:clipboard"]["no_of_buff"]
            wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"].shift
          end
        end
        sleep(wmii.plugin_config["ollis-plugins:clipboard"]["refresh_period"] || 1)
      end
    end
  end
  binding("clipboard_print", "MODKEY-Shift-h") do |wmii,|
    LOGGER.debug "clipboard_print called!!!"
    system wmii.plugin_config["ollis-plugins:clipboard"]["mouseclick_prog"]
  end
  binding("clipboard_select", "MODKEY-h") do |wmii,|
    LOGGER.debug "clipboard_select called!!!"
    Thread.new do
      list = Array.new
      wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"].each do |curr|
        list.push(curr.gsub("\n", " "))
      end
      result = wmii.wmiimenu(list.reverse) do |choice|
        if(choice.length > 0)
          obj_id = list.rindex(choice)
          selection = wmii.plugin_config["ollis-plugins:clipboard"]["sel_buffer"][obj_id]
          system "echo '#{selection}' | xclip -i"
        end
      end
    end
  end

end


