# -*- coding: utf-8 -*-

module Plugin::ExtractGtk
end

=begin rdoc
  抽出タブの一覧
=end

class Plugin::ExtractGtk::ExtractTabList < Gtk::TreeView
  ICON_SIZE = 16

  COL_ICON  = 0
  COL_NAME  = 1
  COL_SLUG  = 2
  COL_SOUND = 3
  COL_POPUP = 4

  def initialize(plugin)
    super(Gtk::ListStore.new(
      GdkPixbuf::Pixbuf, # icon
      String,            # name
      Symbol,            # slug
      GdkPixbuf::Pixbuf, # sound
      GdkPixbuf::Pixbuf  # popup
    ))

    append_column Gtk::TreeViewColumn.new(
      '',
      Gtk::CellRendererPixbuf.new,
      pixbuf: COL_ICON
    )
    append_column(Gtk::TreeViewColumn.new(
      plugin._('名前'),
      Gtk::CellRendererText.new,
      text: COL_NAME
    ).tap { |col| col.expand = true })
    append_column Gtk::TreeViewColumn.new(
      '',
      Gtk::CellRendererPixbuf.new,
      pixbuf: COL_SOUND
    )
    append_column Gtk::TreeViewColumn.new(
      '',
      Gtk::CellRendererPixbuf.new,
      pixbuf: COL_POPUP
    )

    extract_tabs.each(&method(:add_record))
    register_signal_handlers
  end

  # 現在選択されている抽出タブのslugを返す
  # ==== Return
  # 選択されている項目のslug。何も選択されていない場合はnil
  def selected_slug
    selected_iter = selection.selected
    selected_iter[COL_SLUG].to_sym if selected_iter
  end

  # レコードを追加する
  # ==== Args
  # [record] 追加するレコード(Plugin::Extract::Setting)
  # ==== Return
  # self
  def add_record(record)
    iter = model.append
    setup_iter iter, record
    self
  end

  # レコードをもとにリストビューを更新する
  # ==== Args
  # [record] 更新されたレコード(Plugin::Extract::Setting)
  def update_record(record)
    update_iter = model.to_enum(:each)
                    .map { |_, _, iter| iter }
                    .find { |iter| record[:slug].to_sym == iter[COL_SLUG].to_sym }
    setup_iter update_iter, record if update_iter
  end

  # 抽出タブをリストから削除する
  # ==== Args
  # [record_slug] 削除する抽出タブのslug
  # ==== Return
  # self
  def remove_record(record_slug)
    record_slug = record_slug.to_sym
    remove_iter = model.to_enum(:each).map { |_, _, iter| iter }.find { |iter| record_slug == iter[COL_SLUG].to_sym }
    model.remove(remove_iter) if remove_iter
    self
  end

  private

  def register_signal_handlers
    # 項目をダブルクリックして設定を開く
    ssc(:button_press_event) do |_, ev|
      next if ev.event_type != Gdk::EventType::BUTTON2_PRESS
      slug = selected_slug
      if slug
        Plugin.call(:extract_open_edit_dialog, slug)
        true
      end
    end
  end

  # ==== utility

  # レコードの配列を返す
  # ==== Return
  # レコードの配列
  def extract_tabs
    Plugin.filtering(:extract_tabs_get, []).first
  end

  # イテレータにレコードの内容をコピーする
  # ==== Args
  # [iter] TreeIter
  # [record] 参照するレコード (Plugin::Extract::Setting)
  def setup_iter(iter, record)
    size = { width: Gdk.scale(ICON_SIZE), height: Gdk.scale(ICON_SIZE) }
    set_icon = ->(col, photo) do
      iter[col] = photo.load_pixbuf(**size) do |pb|
        iter[col] = pb unless destroyed?
      end
    end

    iter[COL_NAME] = record[:name]
    iter[COL_SLUG] = record[:slug]
    if record[:icon]
      photo = Enumerator.new { |y|
        Plugin.filtering :photo_filter, record[:icon], y
      }.first
      set_icon.(COL_ICON, photo)
    end
    if record[:sound].to_s.empty?
      set_icon.(COL_SOUND, Skin[:notify_sound_off])
    else
      set_icon.(COL_SOUND, Skin[:notify_sound_on])
    end
    if record[:popup]
      set_icon.(COL_POPUP, Skin[:notify_popup_on])
    else
      set_icon.(COL_POPUP, Skin[:notify_popup_off])
    end
  end
end
