#!/usr/bin/env ruby

require "qte"
require "qpe"
require "thread"
include Qte
include Qpe

$version = "0.1.1"
$shoutcast = "http://www.shoutcast.com/"

$workdir = "/home/zaurus/Applications/shoutcastplayer"
if !File.exist?("#{$workdir}")
   Dir.mkdir("#{$workdir}")
end
$tmpfile = "/home/zaurus/Applications/shoutcastplayer/shoutcast.tmp"
$tmpfile2 = "/home/zaurus/Applications/shoutcastplayer/shoutcast2.tmp"
$tmpfile3 = "/home/zaurus/Applications/shoutcastplayer/shoutcast3.tmp"
$sleepfile = "/home/zaurus/Applications/shoutcastplayer/sleepfile.sh"
# $atsleep = "/home/zaurus/Applications/shoutcastplayer/atsleepfile.sh"


#  Configure File
$conffile = "/home/zaurus/Settings/shoutcastplayer.conf"
$conf = Hash.new
#  Each initial value
$conf['cache'] = '350'     # mplayer Cash size
$conf['pdelay'] = '2'      # pls From file acquisition delay to
$conf['sleep'] = 'no'      # Sleep timer invalidity
$conf['sleeptime'] = '5'   # Time to sleep (amount)
$conf['atsleepfile'] = ''  # When sleeping the file name which is registered to the  atd (the extension which is excluded)
$conf['autoplay'] = 'no'   # After the starting it does not play back automatically


class ShoutcastPlayer < QMainWindow
   def initialize()
      super()
      setCaption(tr("SHOUTcast Player Ver#{$version}"))

      # Genre
      @lab1 = QLabel.new("Genre", self)
      @lab1.setGeometry(0,0,60,35)
      @lab1.setAlignment(AlignRight | AlignVCenter)
      @cb1 = QComboBox.new( self )
      @cb1.setGeometry(60,0,210,35)
      connect(@cb1,QSIGNAL("activated(int)"), self, 'changeCategory')
      @cb1.insertItem("TopTen")    # 0
      @cb1.insertItem("Alternative")
      @cb1.insertItem("Classical")
      @cb1.insertItem("Comedy")
      @cb1.insertItem("Country")
      @cb1.insertItem("Dance")
      @cb1.insertItem("Funk")
      @cb1.insertItem("Jazz")
      @cb1.insertItem("Metal")
      @cb1.insertItem("Mixed") 
      @cb1.insertItem("Pop")
      @cb1.insertItem("Rap")
      @cb1.insertItem("RnB")
      @cb1.insertItem("Rock")
      @cb1.insertItem("Talk")
      @cb1.insertItem("Techno")
      @cb1.insertItem("80s")
      @cb1.insertItem("70s")
      @cb1.insertItem("World")
#     @cb1.insertItem("?s=SearchWord")  # When searching the menu it registers,

      # Searching
      @lab2 = QLabel.new("Search", self)
      @lab2.setGeometry(0,35,60,35)
      @lab2.setAlignment(AlignRight | AlignVCenter)
      @eb = QLineEdit.new(self)
      @eb.setGeometry(60,35,210,35)

      # To ranking 200 rank
      @lab3 = QLabel.new("Rank", self)
      @lab3.setGeometry(270,0,100,35)
      @lab3.setAlignment(AlignRight | AlignVCenter)
      @cb3 = QComboBox.new( self )
      @cb3.setGeometry(370,0,150,35)
      from = 1
      to = 20
      10.times{            # When after 200 ranks it indicates, 10 large
         @cb3.insertItem("#{from} - #{to}")
         from += 20
         to += 20
      }

      # Bit rate
      @lab4 = QLabel.new("MaxBitrate", self)
      @lab4.setGeometry(270,35,100,35)
      @lab4.setAlignment(AlignRight | AlignVCenter)
      @cb4 = QComboBox.new( self )
      @cb4.setGeometry(370,35,150,35)
      @cb4.insertItem("All")       # 0
      @cb4.insertItem("128")       # 1
      @cb4.insertItem("96")        # 2
      @cb4.insertItem("80")        # 3
      @cb4.insertItem("64")        # 4
      @cb4.insertItem("56")        # 5
      @cb4.insertItem("32")        # 6

      @list = QListView.new(self)
      @list.setGeometry(0,70,640,300)
      @list.setSorting( 6, true)  # Sort object
      @list.addColumn("rate")     # Column addition 0
      @list.addColumn("listner")  # 1
      @list.addColumn("cate")     # 2
      @list.addColumn("Title")    # 3
      @list.addColumn("Playing")  # 4
      @list.addColumn("path")     # 5
      @list.addColumn("No.")      # 6
      @list.setAllColumnsShowFocus(true)
      @list.columns.times { |i|
         @list.setColumnWidth(i, 20)
      }
         @list.setColumnAlignment(0, AlignRight)
         @list.setColumnAlignment(1, AlignRight)
         @list.setColumnAlignment(6, AlignRight)
      connect(@list, QSIGNAL("clicked(QListViewItem *)"), self, "tapped")
      connect(@list, QSIGNAL("returnPressed(QListViewItem *)"), self, "tapped")

      @pbget = QPushButton.new(tr("Search"), self)
      @pbget.setGeometry(525,0,110,35)
      connect(@pbget,QSIGNAL("clicked()"), self, 'fetchInfo')
      @pbstop = QPushButton.new(tr("Stop"), self)
      @pbstop.setGeometry(525,35,110,35)
      connect(@pbstop,QSIGNAL("clicked()"), self, 'stop')

      @msgsts = QLineEdit.new(tr(""), self) 
      @msgsts.setReadOnly(true)
      @msgsts.setFocusPolicy( NoFocus )
      @msgsts.setGeometry(0,370,640,35)

      loadConf       # load shoutcastplayer.conf
      setSleep

      # sleep Detection of time and end processing thread
      if $conf['sleep'] == 'yes'
         system("/home/QtPalmtop/bin/qcop QPE/System 'setScreenSaverIntervals(int,int,int)' 0 0 0")
         Thread.new{
            Thread.pass
            loop{
               if $conf['sleep'] == 'yes' && !atfileExist?($conf['atsleepfile'])
                  system("killall mplayer")
                  system("qcop QPE/Network 'stop()'")
                  sleep 20
                  system("/home/QtPalmtop/bin/qcop QPE/System 'setScreenSaverIntervals(int,int,int)' -1 -1 -1")
                  system("qcop QPE/Application/shoutcastplayer.rb 'quit()'")
                  system("qcop QPE/Application/suspend 'raise()'")
               end
               sleep 60
               system("/home/QtPalmtop/bin/qcop QPE/System 'setScreenSaverIntervals(int,int,int)' 0 0 0")
            }
         }
      end

      autoplay
      @msgsts.setText("mplayer cache size = #{$conf['cache']}kB")

      catchEvent()
   end

   def fetchInfo
      if !online?
         @msgsts.setText(tr("!!! Offline !!!"))
         return
      end
      @list.clear
      @list.columns.times { |i|
         @list.setColumnWidth(i, 20)
      }

      path = ""
      genre, maxbitrate, rank = "", "", ""

      # If the genre / searching searching column is the sky,  with genre contraction included
      search = @eb.text.to_str
      if search != ""
         genre = "?s=#{search}"
      else
         genre = "directory/?sgenre=#{@cb1.currentText.to_str}"
      end

      # Ranking
      if @cb3.currentItem == 0
         rank = ""
      else
         i = @cb3.currentItem * 20
         rank = "\\&startat=#{i.to_s}"   # \ 2 necessary
      end

      # Bit rate
      if @cb4.currentText.to_str == "All"
         maxbitrate = ""
      else
         maxbitrate = "\\&maxbitrate=#{@cb4.currentText.to_str}"  # \ 2 necessary
      end

      path = genre + maxbitrate + rank
      makeList("#{$shoutcast}#{path}")
      @msgsts.setText(tr("The tap please do the ch which it plays back"))
   end

   def makeList(url)
       if !online?
          @msgsts.setText(tr("!!! Offline !!!"))
          return
       end
      @msgsts.setText(tr("During information acquiring"))
      ret = `wget -O #{$tmpfile} #{url}`
#     system("wget -O #{$tmpfile} #{url}")
      system("killall wget")
      @msgsts.setText(tr("Start"))

      # bitwarp Carriage return is inserted after the corresponding tag
      f1 = File.open($tmpfile)
      f2 = File.open($tmpfile2, "w")
      while line = f1.gets
         line.chomp!
         line.gsub!(/>/, ">\n")
         f2.puts line + "\n"
      end
      f1.close
      f2.close
      f = File.open($tmpfile2)

      # Is acquired from here analysis
      bline1 = ""
      while line = f.gets
         line.chomp!
         # playlist.pls Searching
         if line =~ %r|^.*a href="/(.+?playlist\.pls.+?)">.*$|
            number, listner, cate, title, playing, path, bitrate = "", "", "", "", "", "", ""
            # pls Pass to
            path = $1
            # Ranking 
            bline1 =~ %r|^(\d+)</b>$|
            number = sprintf("%3d",$1.to_i)
            # could not translated
            nil while f.gets.chomp! !~ %r|^.*(\[.+?\])|
            cate = $1
            # Title
            nil while f.gets.chomp! !~ %r|^(.+?)</a>$|
            title = $1
            # Listener several
            while line = f.gets 
               if line =~ %r|^\D*(\d+/\d+)</font>$|
                  break
               end
               # Now Playing: Being to be times when it does not exist
               # During listener several detection it checks
               if line =~ %r|^.*Now Playing:</font>|
                  f.gets.chomp! =~ %r|^\s*(.+?)</font.*$|
                  playing = $1
               end
            end
            listner = $1
            # Bit rate
            nil while f.gets.chomp! !~ %r|^\D*(\d+)</font>$|
            bitrate = $1
            # In list item addition
            QListViewItem.new(@list, bitrate, "[#{listner}]", cate, tr(title), playing, path, number)
         end
         # Ranking seems coming line is kept
         if line =~ %r|</b>|
            bline1 = line
         end
      end
      f.close
      @msgsts.setText(tr("Analysis end"))
      i = @list.firstChild()
      @list.setSelected(i, true)  # Most focusing is applied to the item above
   end

   # When the list the tap being done, processing
   def tapped(item)
      system("killall mplayer")
      @msgsts.setText(tr("During pls file acquiring"))
      path = item.text(5).to_str

      # When the wget is done with the system, before the  $tmpfile3 is drawn up, there are times when the mplayer is executed
      ret = `wget -O #{$tmpfile3} #{$shoutcast}/#{path}`
      # Because of sense with the conf it makes variable
      sleep $conf['pdelay'].to_i
      @msgsts.setText(item.text(3).to_str)
      @msgsts.home(false)
      system("mplayer -quiet -cache #{$conf['cache']} -playlist #{$tmpfile3} &")
   end

   # When modifying genre, processing
   def changeCategory(i)
      @eb.clear
   end

   # Playback stop
   def stop
      @msgsts.setText("stopped")
      system("killall wget")
      system("killall mplayer")
   end

   def autoplay
      return if $conf['autoplay'] == "no"
      @msgsts.setText("AutoPlay")
      return if !File.exist?($tmpfile3)

      3.times{
         if !online?
            system("qcop QPE/Network 'connectRequest()'")
            sleep 20
         else
            break
         end
      }
      if online?
         system("mplayer -quiet -cache #{$conf['cache']} -playlist #{$tmpfile3} &")
      end
   end

   # shoutcastplayer.conf load
   def loadConf
      if File.exist?("#{$conffile}")
         file = File.open("#{$conffile}")
         while line = file.gets
            line.chomp!
            key, value = line.split(/=/)
            $conf[key] = value
         end
      end
   end

   # shoutcastplayer.conf save
   def saveConf
      file = File.open($conffile, "w")
      $conf.each{ |key, val|
         file.puts "#{key}=#{val}"
      }
      file.close
   end


   # Processing when
   def closeEvent(e)
      # kill prosess
      system("killall wget")
      system("killall mplayer")
      # delete tmpfile
#     system("rm #{$tmpfile}")
#     system("rm #{$tmpfile2}")
      # save shoutcastplayer.conf
      saveConf
#     close()
      e.accept()  #Unless there is this, it does not close
   end

   # In net presence of connection verification
   def online?
     i = nil
     i = `route -n | grep '^0\.0\.0\.0'`
     if i == ""
        false
        return
     end
     true
   end

   # atd Presence of the file which is registered verification
   def atfileExist?(timestr)
      atfile = false
      re = Regexp.new(timestr)
      dir = Dir.open("/var/spool/at")
      while file = dir.read
         if file =~ re
            atfile = true
            break
         end
      end
      dir.close
      if atfile
         return true
      end
      false
   end

   # Sleep time in atd register
   def setSleep
      if $conf['sleep'] == 'yes'
         # The screen saver is made invalid
         now = Time.new
         sleep = $conf['sleeptime'].to_i
         sleep = 2 if sleep < 2
         stime = now +  sleep * 60
         strtime = stime.strftime("%Y.%m.%d-%H:%M:%S")
         $conf['atsleepfile'] = stime.to_i.to_s  # The file name which is registered to the atd (is  excluded the extension）
         system("su -c 'echo | at #{strtime}'")
      end
   end
end


$defaultCodec = QTextCodec.codecForName("utf8")
app = QPEApplication.new([$0]+ARGV)
app.setDefaultCodec($defaultCodec)
QApplication.setFont(QFont.new("lcfont",18))
app.showMainWidget(ShoutcastPlayer.new())
app.exec

