/* Styling for ui_file
   Copyright (C) 2018-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDB_UI_STYLE_H
#define GDB_UI_STYLE_H

/* One of the color spaces that usually supported by terminals.  */
enum class color_space
{
  /* one default terminal color  */
  MONOCHROME,

  /* foreground colors \e[30m ... \e[37m,
     background colors \e[40m ... \e[47m  */
  ANSI_8COLOR,

  /* foreground colors \e[30m ... \e[37m, \e[90m ... \e[97m
     background colors \e[40m ... \e[47m, \e[100m ... \e107m  */
  AIXTERM_16COLOR,

  /* foreground colors \e[38;5;0m ... \e[38;5;255m
     background colors \e[48;5;0m ... \e[48;5;255m  */
  XTERM_256COLOR,

  /* foreground colors \e[38;2;0;0;0m ... \e[38;2;255;255;255m
     background colors \e[48;2;0;0;0m ... \e[48;2;255;255;255m  */
  RGB_24BIT
};

/* Color spaces supported by terminal.  */
extern const std::vector<color_space> & colorsupport ();

/* Textual representation of C.  */
extern const char * color_space_name (color_space c);

/* Cast C to RESULT and return true if it's value is valid; false otherwise.  */
extern bool color_space_safe_cast (color_space *result, long c);

/* Styles that can be applied to a ui_file.  */
struct ui_file_style
{
  /* One of the basic colors that can be handled by ANSI
     terminals.  */
  enum basic_color
  {
    NONE = -1,
    BLACK,
    RED,
    GREEN,
    YELLOW,
    BLUE,
    MAGENTA,
    CYAN,
    WHITE
  };

  /* Representation of a terminal color.  */
  class color
  {
  public:

    color (basic_color c)
      : m_color_space (c == NONE ? color_space::MONOCHROME
				 : color_space::ANSI_8COLOR),
	m_value (c)
    {
    }

    color (int c)
      : m_value (c)
    {
      if (c < -1 || c > 255)
	error (_("Palette color index %d is out of range."), c);
      if (c == -1)
	m_color_space = color_space::MONOCHROME;
      else if (c <= 7)
	m_color_space = color_space::ANSI_8COLOR;
      else if (c <= 15)
	m_color_space = color_space::AIXTERM_16COLOR;
      else
	m_color_space = color_space::XTERM_256COLOR;
    }

    color (color_space cs, int c)
      : m_color_space (cs),
	m_value (c)
    {
      if (c < -1 || c > 255)
	error (_("Palette color index %d is out of range."), c);

      std::pair<int, int> range;
      switch (cs)
	{
	case color_space::MONOCHROME:
	  range = {-1, -1};
	  break;
	case color_space::ANSI_8COLOR:
	  range = {0, 7};
	  break;
	case color_space::AIXTERM_16COLOR:
	  range = {0, 15};
	  break;
	case color_space::XTERM_256COLOR:
	  range = {0, 255};
	  break;
	default:
	  error (_("Color space %d is incompatible with indexed colors."),
		 static_cast<int> (cs));
	}

      if (c < range.first || c > range.second)
	error (_("Color %d is out of range [%d, %d] of color space %d."),
	       c, range.first, range.second, static_cast<int> (cs));
    }

    color (uint8_t r, uint8_t g, uint8_t b)
      : m_color_space (color_space::RGB_24BIT),
	m_red (r),
	m_green (g),
	m_blue (b)
    {
    }

    bool operator== (const color &other) const
    {
      if (m_color_space != other.m_color_space)
	return false;
      if (is_simple ())
	return m_value == other.m_value;
      return (m_red == other.m_red && m_green == other.m_green
	      && m_blue == other.m_blue);
    }

    bool operator!= (const color &other) const
    {
      return ! (*this == other);
    }

    /* Compute a simple hash code for this object.  */
    size_t hash () const
    {
      if (is_simple ())
	return m_value;
      return (m_red << 16) + (m_green << 8) + m_red;
    }

    color_space colorspace () const
    {
      return m_color_space;
    }

    /* Return true if this is the "NONE" color, false otherwise.  */
    bool is_none () const
    {
      return m_color_space == color_space::MONOCHROME && m_value == NONE;
    }

    /* Return true if this is one of the basic colors, false
       otherwise.  */
    bool is_basic () const
    {
      if (m_color_space == color_space::ANSI_8COLOR
	  || m_color_space == color_space::AIXTERM_16COLOR)
	return BLACK <= m_value && m_value <= WHITE;
      else
	return false;
    }

    /* Return true if this is one of the colors, stored as int, false
       otherwise.  */
    bool is_simple () const
    {
      return m_color_space != color_space::RGB_24BIT;
    }

    /* Return true if this is one of the indexed colors, false
       otherwise.  */
    bool is_indexed () const
    {
      return m_color_space != color_space::RGB_24BIT
	     && m_color_space != color_space::MONOCHROME;
    }

    /* Return true if this is one of the direct colors (RGB, CMY, CMYK), false
       otherwise.  */
    bool is_direct () const
    {
      return m_color_space == color_space::RGB_24BIT;
    }

    /* Return the value of a simple color.  */
    int get_value () const
    {
      gdb_assert (is_simple ());
      return m_value;
    }

    /* Fill in RGB with the red/green/blue values for this color.
       This may not be called for basic colors or for the "NONE"
       color.  */
    void get_rgb (uint8_t *rgb) const;

    /* Append the ANSI terminal escape sequence for this color to STR.
       IS_FG indicates whether this is a foreground or background
       color.  */
    void append_ansi (bool is_fg, std::string *str) const;

    /* Return the ANSI escape sequence for this color.
       IS_FG indicates whether this is a foreground or background color.  */
    std::string to_ansi (bool is_fg) const;

    /* Returns text representation of this object.
       It is "none", name of a basic color, number or a #RRGGBB hex triplet.  */
    std::string to_string () const;

    /* Approximates THIS color by closest one from SPACES.  */
    color approximate (const std::vector<color_space> &spaces) const;

  private:

    color_space m_color_space;
    union
    {
      int m_value;
      struct
      {
	uint8_t m_red, m_green, m_blue;
      };
    };
  };

  /* Intensity settings that are available.  */
  enum intensity
  {
    NORMAL = 0,
    BOLD,
    DIM
  };

  ui_file_style () = default;

  ui_file_style (color f, color b, intensity i = NORMAL)
    : m_foreground (f),
      m_background (b),
      m_intensity (i)
  {
  }

  bool operator== (const ui_file_style &other) const
  {
    return (m_foreground == other.m_foreground
	    && m_background == other.m_background
	    && m_intensity == other.m_intensity
	    && m_reverse == other.m_reverse
	    && m_italic == other.m_italic
	    && m_underline == other.m_underline);
  }

  bool operator!= (const ui_file_style &other) const
  {
    return !(*this == other);
  }

  /* Return the ANSI escape sequence for this style.  */
  std::string to_ansi () const;

  /* Return true if this style is the default style; false
     otherwise.  */
  bool is_default () const
  {
    return (m_foreground == NONE
	    && m_background == NONE
	    && m_intensity == NORMAL
	    && !m_reverse
	    && !m_italic
	    && !m_underline);
  }

  /* Return true if this style specified reverse display; false
     otherwise.  */
  bool is_reverse () const
  {
    return m_reverse;
  }

  /* Set/clear the reverse display flag.  */
  void set_reverse (bool reverse)
  {
    m_reverse = reverse;
  }

  /* Return the foreground color of this style.  */
  const color &get_foreground () const
  {
    return m_foreground;
  }

  /* Set the foreground color of this style.  */
  void set_fg (color c)
  {
    m_foreground = c;
  }

  /* Return the background color of this style.  */
  const color &get_background () const
  {
    return m_background;
  }

  /* Set the background color of this style.  */
  void set_bg (color c)
  {
    m_background = c;
  }

  /* Return the intensity of this style.  */
  intensity get_intensity () const
  {
    return m_intensity;
  }

  /* Set the intensity of this style.  */
  void set_intensity (intensity i)
  {
    m_intensity = i;
  }

  /* Return true if this style specified italic display; false
     otherwise.  */
  bool is_italic () const
  {
    return m_italic;
  }

  /* Set/clear the italic display flag.  */
  void set_italic (bool italic)
  {
    m_italic = italic;
  }

  /* Return true if this style specified underline display; false
     otherwise.  */
  bool is_underline () const
  {
    return m_underline;
  }

  /* Set/clear the underline display flag.  */
  void set_underline (bool underline)
  {
    m_underline = underline;
  }

  /* Parse an ANSI escape sequence in BUF, modifying this style.  BUF
     must begin with an ESC character.  Return true if an escape
     sequence was successfully parsed; false otherwise.  In either
     case, N_READ is updated to reflect the number of chars read from
     BUF.  */
  bool parse (const char *buf, size_t *n_read);

  /* We need this because we can't pass a reference via va_args.  */
  const ui_file_style *ptr () const
  {
    return this;
  }

  /* nullptr-terminated list of names corresponding to enum basic_color.  */
  static const std::vector<const char *> basic_color_enums;

private:

  color m_foreground = NONE;
  color m_background = NONE;
  intensity m_intensity = NORMAL;
  bool m_italic = false;
  bool m_underline = false;
  bool m_reverse = false;
};

/* Possible results for checking an ANSI escape sequence.  */
enum class ansi_escape_result
{
  /* The escape sequence is definitely not recognizable.  */
  NO_MATCH,

  /* The escape sequence might be recognizable with more input.  */
  INCOMPLETE,

  /* The escape sequence is definitely recognizable.  */
  MATCHED,
};

/* Examine an ANSI escape sequence in BUF.  BUF must begin with an ESC
   character.  Return a value indicating whether the sequence was
   recognizable.  If MATCHED is returned, then N_READ is updated to
   reflect the number of chars read from BUF.  */

extern ansi_escape_result examine_ansi_escape (const char *buf, int *n_read);

/* Skip an ANSI escape sequence in BUF.  BUF must begin with an ESC
   character.  Return true if an escape sequence was successfully
   skipped; false otherwise.  If an escape sequence was skipped,
   N_READ is updated to reflect the number of chars read from BUF.  */

static inline bool
skip_ansi_escape (const char *buf, int *n_read)
{
  return examine_ansi_escape (buf, n_read) == ansi_escape_result::MATCHED;
}

#endif /* GDB_UI_STYLE_H */
