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

module Rouge
  module Formatters
    # A formatter for 256-color terminals
    class Terminal256 < Formatter
      tag 'terminal256'

      # @private
      attr_reader :theme


      # @option opts :theme
      #   (default is thankful_eyes) the theme to render with.
      def initialize(opts={})
        @theme = opts[:theme] || 'thankful_eyes'
        @theme = Theme.find(@theme) if @theme.is_a? String
      end

      def stream(tokens, &b)
        tokens.each do |tok, val|
          escape = escape_sequence(tok)
          yield escape.style_string
          yield val.gsub("\n", "\n#{escape.style_string}")
          yield escape.reset_string
        end
      end

      class EscapeSequence
        attr_reader :style
        def initialize(style)
          @style = style
        end

        def self.xterm_colors
          @xterm_colors ||= [].tap do |out|
            # colors 0..15: 16 basic colors
            out << [0x00, 0x00, 0x00] # 0
            out << [0xcd, 0x00, 0x00] # 1
            out << [0x00, 0xcd, 0x00] # 2
            out << [0xcd, 0xcd, 0x00] # 3
            out << [0x00, 0x00, 0xee] # 4
            out << [0xcd, 0x00, 0xcd] # 5
            out << [0x00, 0xcd, 0xcd] # 6
            out << [0xe5, 0xe5, 0xe5] # 7
            out << [0x7f, 0x7f, 0x7f] # 8
            out << [0xff, 0x00, 0x00] # 9
            out << [0x00, 0xff, 0x00] # 10
            out << [0xff, 0xff, 0x00] # 11
            out << [0x5c, 0x5c, 0xff] # 12
            out << [0xff, 0x00, 0xff] # 13
            out << [0x00, 0xff, 0xff] # 14
            out << [0xff, 0xff, 0xff] # 15

            # colors 16..232: the 6x6x6 color cube
            valuerange = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]

            217.times do |i|
              r = valuerange[(i / 36) % 6]
              g = valuerange[(i / 6) % 6]
              b = valuerange[i % 6]
              out << [r, g, b]
            end

            # colors 233..253: grayscale
            1.upto 22 do |i|
              v = 8 + i * 10
              out << [v, v, v]
            end
          end
        end

        def fg
          return @fg if instance_variable_defined? :@fg
          @fg = style.fg && self.class.color_index(style.fg)
        end

        def bg
          return @bg if instance_variable_defined? :@bg
          @bg = style.bg && self.class.color_index(style.bg)
        end

        def style_string
          @style_string ||= begin
            attrs = []

            attrs << ['38', '5', fg.to_s] if fg
            attrs << ['48', '5', bg.to_s] if bg
            attrs << '01' if style[:bold]
            attrs << '04' if style[:italic] # underline, but hey, whatevs
            escape(attrs)
          end
        end

        def reset_string
          @reset_string ||= begin
            attrs = []
            attrs << '39' if fg # fg reset
            attrs << '49' if bg # bg reset
            attrs << '00' if style[:bold] || style[:italic]

            escape(attrs)
          end
        end

      private
        def escape(attrs)
          return '' if attrs.empty?
          "\e[#{attrs.join(';')}m"
        end

        def self.color_index(color)
          @color_index_cache ||= {}
          @color_index_cache[color] ||= closest_color(*get_rgb(color))
        end

        def self.get_rgb(color)
          color = $1 if color =~ /#([0-9a-f]+)/i
          hexes = case color.size
          when 3
            color.chars.map { |c| "#{c}#{c}" }
          when 6
            color.scan(/../)
          else
            raise "invalid color: #{color}"
          end

          hexes.map { |h| h.to_i(16) }
        end

        # max distance between two colors, #000000 to #ffffff
        MAX_DISTANCE = 257 * 257 * 3

        def self.closest_color(r, g, b)
          @@colors_cache ||= {}
          key = (r << 16) + (g << 8) + b
          @@colors_cache.fetch(key) do
            distance = MAX_DISTANCE

            match = 0

            xterm_colors.each_with_index do |(cr, cg, cb), i|
              d = (r - cr)**2 + (g - cg)**2 + (b - cb)**2
              next if d >= distance

              match = i
              distance = d
            end

            match
          end
        end
      end

    # private
      def escape_sequence(token)
        @escape_sequences ||= {}
        @escape_sequences[token.qualname] ||=
          EscapeSequence.new(get_style(token))
      end

      def get_style(token)
        return text_style if token.ancestors.include? Token::Tokens::Text

        theme.get_own_style(token) || text_style
      end

      def text_style
        style = theme.get_style(Token['Text'])
        # don't highlight text backgrounds
        style.delete :bg
        style
      end
    end
  end
end
