require 'open-uri'

class FLVGetter
    def FLVGetter.get_flv(url)
      raise "Empty URL" if url.empty?
      page = open(url).read
      id = url.split("v=")[1].split("&")[0]
      v, t = page.match(/\&video_id=(.*?)&.*?\&t=(.*?)&/)[1..2]
      "http://www.youtube.com/get_video.php?video_id=#{v}&t=#{t}"
  end
end

Shoes.app :width=>424 , :height=>391 do
  background black
  stack do
    stack do
      background red
      flow do
        para "Youtube URL: "
        @url = edit_line "",:width=>300
      end
      flow do
        button("Watch") do 
          begin
            flv = FLVGetter.get_flv @url.text
            @videostack.clear do
              background black
              stack do
                @vid = video flv
                @vid.play
              end
              para "controls: ",
                link("play")  { @vid.play }, ", ",
                link("pause") { @vid.pause }, ", ",
                link("stop")  { @vid.stop }, ", ",
                link("hide")  { @vid.hide }, ", ",
                link("show")  { @vid.show }, ", ",
                link("+5 sec") { @vid.time += 5000 }
            end
            rescue => error
            alert(error.inspect)
          end
        end
        button("Save") do
          url = @url.text
          Shoes.app(:width=>130,:height=>40) do
            @label=para ""
            @progress = :Locating
            every(2) do
              @label.replace @progress.to_s+"..."
              case @progress
                when :Done
                  @progress=:Closing
                  close
                  alert("Download complete")
              end
            end
            fname=ask_save_file
            unless fname
              close
              return
            end
            @thread = Thread.new do
              begin
                flv = FLVGetter.get_flv url
                @progress = :Saving
                File.open(fname,'wb') do |file|
                  file.write open(flv).read
                  #open(flv) do |stream| #todo: use a method that allows live progress updates
                    #written = 0              #ie. @progress => percentage
                    #while (data = stream.read(4096))
                    #  file.write data
                    #  written += data
                    #end
                  #end
                end
                @progress=:Done
              rescue => error
                alert(error.inspect)
                close # is this safe? (cross thread)
              end
            end
          end
        end      
      end
      @videostack = stack { background black }
    end
  end
end
