# frozen_string_literal: true

module Vedeu

  module Views

    # Represents a {Vedeu::Views::Char} as a HTML tag with value. By
    # default, a table cell is used.
    #
    class HTMLChar

      include Vedeu::Common

      # @param (see #initialize)
      # @return (see #render)
      def self.render(char, options = {})
        new(char, options).render
      end

      # Returns a new instance of Vedeu::Views::HTMLChar.
      #
      # @param char [Vedeu::Views::Char]
      # @param options [Hash<Symbol => String>]
      # @option options start_tag [String]
      # @option options end_tag [String]
      # @return [Vedeu::Views::HTMLChar]
      def initialize(char, options = {})
        @char    = char
        @options = options
      end

      # @return [String]
      def render
        "#{start_tag}#{tag_style}>#{tag_value}#{end_tag}"
      end

      protected

      # @!attribute [r] char
      # @return [Vedeu::Views::Char]
      attr_reader :char

      private

      # @return [String]
      def tag_style
        return '' unless border || present?(value)

        " style='#{tag_style_background}#{tag_style_foreground}'"
      end

      # @return [String]
      def tag_style_background
        return '' if char.background.empty?

        "border:1px #{char.background.to_html} solid;" \
          "background:#{char.background.to_html};"
      end

      # @return [String]
      def tag_style_foreground
        return '' if char.foreground.empty?

        "color:#{char.foreground.to_html};#{border_style}"
      end

      # @return [String]
      def tag_value
        return '&nbsp;' if border || !present?(value)

        value
      end

      # @return [String]
      def border_style
        case border
        when :top_horizontal    then css(:top)
        when :left_vertical     then css(:left)
        when :right_vertical    then css(:right)
        when :bottom_horizontal then css(:bottom)
        when :top_left     then "#{css(:top)}#{css(:left)}"
        when :top_right    then "#{css(:top)}#{css(:right)}"
        when :bottom_left  then "#{css(:bottom)}#{css(:left)}"
        when :bottom_right then "#{css(:bottom)}#{css(:right)}"
        else
          ''
        end
      end

      # @param direction [Symbol]
      # @return [String]
      def css(direction)
        "border-#{direction}:1px #{char.foreground.to_html} solid;"
      end

      # @return [Symbol|NilClass]
      def border
        char.border
      end

      # @return [String]
      def value
        char.value
      end

      # @return [String]
      def start_tag
        options[:start_tag]
      end

      # @return [String]
      def end_tag
        options[:end_tag]
      end

      # @return [Hash<Symbol => String>]
      def options
        defaults.merge!(@options)
      end

      # @return [Hash<Symbol => String>]
      def defaults
        {
          start_tag: '<td',
          end_tag:   '</td>',
        }
      end

    end # HTMLChar

  end # Views

end # Vedeu