require 'gst'
require 'gtk2'

module Rabbit
  class VideoWindow
    attr_accessor :window, :direction, :entry
    def initialize(element)
      @element = element
      @video = VideoWidget.new(@element.filename)
    end

    def setup(window)
      if not @completed
        @window = window
        init_window
        init_keys
        @completed = true
      end
    end

    def show(window)
      setup(window) if not window.nil?
      Utils.move_to(window, @video_window) do |bx, by, bw, bh, tw, th, sw, sh|
        [bx+@element.x, by+@element.y]
      end
      @video_window.resize(@element.width, @element.height)
      @video_window.show_all
      @video.play
    end

    def hide
      @video.pause
      @video_window.hide
    end

    private
    def init_window
      @video_window = Gtk::Window.new(Gtk::Window::POPUP)
      @video_window.modal = true
      @video_window.set_transient_for(window)

      vbox = Gtk::VBox.new
      vbox.pack_start(@video)
      @video_window.add(vbox)
      @video_window.signal_connect('frame-event') do |widget, event|
        if event.event_type == Gdk::Event::Type::BUTTON_PRESS
          @video.toggle
        end
      end
      @video_window.signal_connect('destroy') do
        @video.stop
      end
    end

    def init_keys
      @video_window.signal_connect("key_press_event") do |widget, key|
        case key.keyval
        when Gdk::Keyval::GDK_KEY_space
          @video.toggle
        when Gdk::Keyval::GDK_KEY_plus
          @video.seek(10)
        when Gdk::Keyval::GDK_KEY_minus
          @video.seek(-10)
        when *[
            Keys::MOVE_TO_NEXT_KEYS, Keys::MOVE_TO_PREVIOUS_KEYS,
            Keys::MOVE_TO_LAST_KEYS, Keys::MOVE_TO_LAST_KEYS,
          ].flatten
          hide
          Gtk::AccelGroup.activate(window, key.keyval, key.state)
        else
          Gtk::AccelGroup.activate(window, key.keyval, key.state)
        end
      end
    end

    class VideoWidget < Gtk::DrawingArea
      def initialize(file)
        super()

        @playbin = Gst::ElementFactory.make('playbin2')

        @video = Gst::ElementFactory.make('xvimagesink')
        @video.force_aspect_ratio = true

        @playbin.video_sink = @video
        @playbin.audio_sink = Gst::ElementFactory.make('autoaudiosink')
        @playbin.signal_connect('notify') do
          @playbin.video_sink.xwindow_id = self.window.xid if self.window
          @playbin.video_sink.expose
        end
        @playbin.uri = "file://#{File.absolute_path(file)}"
        @playbin.ready
      end

      def play
        @playbin.play
        @playing = true
      end

      def pause
        @playbin.pause
        @playing = false
      end

      def stop
        @playbin.stop
        @playing = false
      end

      def seek(time)
        @playbin.seek(1.0, Gst::Format::TIME,
          Gst::Seek::FLAG_FLUSH | Gst::Seek::FLAG_KEY_UNIT,
          Gst::Seek::TYPE_CUR, time * Gst::SECOND,
          Gst::Seek::TYPE_NONE, -1);
      end

      def toggle
        @playing ? pause : play
      end
    end
  end
end
