class Gdk::SubPartsMastodonStatusInfo < Gdk::SubParts
  DEFAULT_ICON_SIZE = 20
  ICON_NAME = {
    'unlisted' => Skin[:unlisted],
    'private' => Skin[:protected],
    'direct' => Skin[:directmessage]
  }.freeze

  register

  def icon_pixbuf
    ICON_NAME[helper.message.visibility]&.pixbuf(width: icon_size.width, height: icon_size.height)
  end

  def show_icon?
    (UserConfig[:mastodon_show_subparts_bot] && bot?) ||
      (UserConfig[:mastodon_show_subparts_pin] && pinned?) ||
      (UserConfig[:mastodon_show_subparts_visibility] && odd_visibility?)
  end

  def bot?
    helper.message.user.respond_to?(:bot) && helper.message.user.bot
  end

  def pinned?
    helper.message.respond_to?(:pinned) && helper.message.pinned
  end

  def odd_visibility?
    helper.message.respond_to?(:visibility) && ICON_NAME.has_key?(helper.message.visibility)
  end

  def visibility_text(visibility)
    case visibility
    when 'unlisted'
      Plugin[:mastodon]._('未収載')
    when 'private'
      Plugin[:mastodon]._('非公開')
    when 'direct'
      Plugin[:mastodon]._('ダイレクト')
    else
      ''
    end
  end

  def initialize(*args)
    super

    @margin = 2
  end

  def render(context)
    if helper.visible? && show_icon?
      context.save do
        context.translate(0, margin)
        render_bot(context)
        render_pin(context)
        render_visibility(context)
      end
    end
  end

  def render_bot(context)
    return unless UserConfig[:mastodon_show_subparts_bot] && bot?
    context.translate(margin, 0)
    context.set_source_pixbuf(
      Skin[:underconstruction].pixbuf(width: icon_size.width, height: icon_size.height)
    )
    context.paint
    context.translate(icon_size.width + margin, 0)
    render_text(
      context,
      Plugin[:mastodon]._('bot'),
      font_description: helper.font_description(UserConfig[:mumble_basic_font]),
      color: UserConfig[:mumble_basic_color]
    )
  end

  def render_pin(context)
    return unless UserConfig[:mastodon_show_subparts_pin] && pinned?
    context.translate(margin, 0)
    context.set_source_pixbuf(
      Skin[:underconstruction].pixbuf(width: icon_size.width, height: icon_size.height)
    )
    context.paint
    context.translate(icon_size.width + margin, 0)
    render_text(
      context,
      Plugin[:mastodon]._('ピン留め'),
      font_description: helper.font_description(UserConfig[:mumble_basic_font]),
      color: UserConfig[:mumble_basic_color]
    )
  end

  def render_visibility(context)
    return unless UserConfig[:mastodon_show_subparts_visibility] && odd_visibility?
    context.translate(margin, 0)
    context.set_source_pixbuf(icon_pixbuf)
    context.paint
    context.translate(icon_size.width + margin, 0)
    render_text(
      context,
      visibility_text(helper.message.visibility),
      font_description: helper.font_description(UserConfig[:mumble_basic_font]),
      color: UserConfig[:mumble_basic_color]
    )
  end

  def render_text(context, text, font_description: nil, color: nil)
    layout = context.create_pango_layout
    layout.font_description = font_description
    layout.text = text
    bot_text_width = layout.extents[1].width / Pango::SCALE
    context.set_source_rgb(*(color || [0, 0, 0]).map { |c| c.to_f / 65536 })
    context.show_pango_layout(layout)
    context.translate(bot_text_width, 0)
  end

  def margin
    Gdk.scale(@margin)
  end

  def icon_size
    @icon_size ||= Gdk.scale(DEFAULT_ICON_SIZE).then { Gdk::Rectangle.new(0, 0, _1, _1) }
  end

  def height
    @height ||= show_icon? ? icon_size.height + 2 * margin : 0
  end
end
