
// SPDX-License-Identifier: CC-BY-NC-SA-4.0
//
// Copyright (C) 2026 Bit by Bit Signal Processing LLC (https://bxbsp.com)
//
// This work is placed under the "Creative Commons Attribution
// NonCommercial ShareAlike 4.0 International" license, known
// by the shortened acronym "CC-BY-NC-SA-4.0".
//
// This work 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.
//
// A CC-BY-NC-SA-4.0 license allows you to use this work for
// noncommercial purposes so long as attribution is made to the
// original author.  Modified versions of this work may be distributed,
// but only under the same license.  For further details, see the
// Creative Commons License "CC-BY-NC-SA-4.0".
//
// You should have received a copy of the CC-BY-NC-SA-4.0 license
// along with this work. If not, see
// <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
//

//

#ifndef BACKING_PANEL_HH
#define BACKING_PANEL_HH

#include "panel.hh"
#include "draw_text.hh"
#include "svg.hh"
#include "global_draw_rect.hh"
#include "global_draw_line.hh"

class backing_panel : public panel
{
public:
  
  uint16_t* buff;
  
public:
  
  backing_panel(int w, int h);
  backing_panel(int w, int h, int p);
  
  virtual ~backing_panel();

  virtual void   draw_point_no_boundscheck(point p, color c);
  virtual color  get_point_no_boundscheck(point p);
  virtual void   clear_rect(color c, point corner1, point corner2);

  virtual void   draw_text(const char* text, color c, int x, int y, int flags = 0);
  virtual void   draw_multicolored_text(const char* text, int start_color, dt_colors& c, int x, int y, int flags = 0);
  virtual int    calculate_text_width(const char* text);
  virtual int    calculate_text_height(const char* text);

  virtual void   draw_text(const wchar_t* text, color c, int x, int y, int flags = 0);
  virtual void   draw_multicolored_text(const wchar_t* text, int start_color, dt_colors& c, int x, int y, int flags = 0);
  virtual int    calculate_text_width(const wchar_t* text);
  virtual int    calculate_text_height(const wchar_t* text);

  virtual void   draw_text(const char16_t* text, color c, int x, int y, int flags = 0);
  virtual void   draw_multicolored_text(const char16_t* text, int start_color, dt_colors& c, int x, int y, int flags = 0);
  virtual int    calculate_text_width(const char16_t* text);
  virtual int    calculate_text_height(const char16_t* text);

  virtual void   draw_text(const char32_t* text, color c, int x, int y, int flags = 0);
  virtual void   draw_multicolored_text(const char32_t* text, int start_color, dt_colors& c, int x, int y, int flags = 0);
  virtual int    calculate_text_width(const char32_t* text);
  virtual int    calculate_text_height(const char32_t* text);

  virtual void   set_text_size(int height_pixels);

  virtual void   draw_svg_from_data(uint8_t* svg_data, int svg_data_length, int offset_x=0, int offset_y=0, int draw_width=0, int draw_height=0);
  virtual bool   draw_svg_from_file(const char* filename, int offset_x=0, int offset_y=0, int draw_width=0, int draw_height=0);
  virtual bool   svg_dimensions_from_file(const char* filename, int& width, int& height);

  virtual void   draw_line_known_background(pointf p0, pointf p1, color c, color bg);
  virtual void   draw_line(pointf p0, pointf p1, color c);
  virtual void   draw_line_vertical(point p0, point p1, color c);
  virtual void   draw_line_horizontal(point p0, point p1, color c);
};


inline backing_panel::~backing_panel()
{
  delete [] buff;
}

inline backing_panel::backing_panel(int w, int h) : panel(w, h)
{
  buff = new uint16_t[w*h];
}

inline backing_panel::backing_panel(int w, int h, int p) : panel(w, h, p)
{
  buff = new uint16_t[p*h];
}


inline void backing_panel::draw_point_no_boundscheck(point p, color c)
{
#ifdef INVERT_X
  int x_fixed = width-1 - p.x;
#else
  int x_fixed = p.x;
#endif

#ifdef INVERT_Y
  int y_fixed = height-1 - p.y;
#else
  int y_fixed = p.y;
#endif
  
  int location = y_fixed * pitch + x_fixed;

  buff[location] = c;
}

inline color backing_panel::get_point_no_boundscheck(point p)
{
#ifdef INVERT_X
  int x_fixed = width-1 - p.x;
#else
  int x_fixed = p.x;
#endif

#ifdef INVERT_Y
  int y_fixed = height-1 - p.y;
#else
  int y_fixed = p.y;
#endif
  
  int location = y_fixed * pitch + x_fixed;

  return color(buff[location]);
}

inline void backing_panel::clear_rect(color c, point corner1, point corner2)
{
  global_clear_rect(this, c, corner1, corner2);
}


inline void backing_panel::draw_text(const char* text, color c, int x, int y, int flags)
{
  global_draw_text(text, c, this, x, y, flags);
}


inline void backing_panel::draw_text(const wchar_t* text, color c, int x, int y, int flags)
{
  global_draw_text(text, c, this, x, y, flags);
}


inline void backing_panel::draw_text(const char16_t* text, color c, int x, int y, int flags)
{
  global_draw_text(text, c, this, x, y, flags);
}


inline void backing_panel::draw_text(const char32_t* text, color c, int x, int y, int flags)
{
  global_draw_text(text, c, this, x, y, flags);
}


inline void backing_panel::draw_multicolored_text(const char* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  global_draw_multicolored_text(text, c, start_color, this, x, y, flags);
}

inline void backing_panel::draw_multicolored_text(const wchar_t* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  global_draw_multicolored_text(text, c, start_color, this, x, y, flags);
}

inline void backing_panel::draw_multicolored_text(const char16_t* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  global_draw_multicolored_text(text, c, start_color, this, x, y, flags);
}

inline void backing_panel::draw_multicolored_text(const char32_t* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  global_draw_multicolored_text(text, c, start_color, this, x, y, flags);
}


inline int  backing_panel::calculate_text_width(const char* text)
{
  return global_calculate_text_width(text);
}

inline int  backing_panel::calculate_text_width(const wchar_t* text)
{
  return global_calculate_text_width(text);
}

inline int  backing_panel::calculate_text_width(const char16_t* text)
{
  return global_calculate_text_width(text);
}

inline int  backing_panel::calculate_text_width(const char32_t* text)
{
  return global_calculate_text_width(text);
}


inline int  backing_panel::calculate_text_height(const char* text)
{
  return global_calculate_text_height(text);
}

inline int  backing_panel::calculate_text_height(const wchar_t* text)
{
  return global_calculate_text_height(text);
}

inline int  backing_panel::calculate_text_height(const char16_t* text)
{
  return global_calculate_text_height(text);
}

inline int  backing_panel::calculate_text_height(const char32_t* text)
{
  return global_calculate_text_height(text);
}


inline void backing_panel::set_text_size(int height_pixels)
{
  global_set_text_size(height_pixels);
}


inline void backing_panel::draw_svg_from_data(uint8_t* svg_data, int svg_data_length, int offset_x, int offset_y, int draw_width, int draw_height)
{
  global_draw_svg_from_data(this, svg_data, svg_data_length, offset_x, offset_y, draw_width, draw_height);
}

inline bool backing_panel::draw_svg_from_file(const char* filename, int offset_x, int offset_y, int draw_width, int draw_height)
{
  return global_draw_svg_from_file(this, filename, offset_x, offset_y, draw_width, draw_height);
}

inline bool backing_panel::svg_dimensions_from_file(const char* filename, int& width, int& height)
{
  return global_svg_dimensions_from_file(filename, width, height);
}


inline void backing_panel::draw_line_known_background(pointf p0, pointf p1, color c, color bg)
{
  global_draw_line_known_background(this, p0, p1, c, bg);
}

inline void backing_panel::draw_line(pointf p0, pointf p1, color c)
{
  global_draw_line(this, p0, p1, c);
}

inline void backing_panel::draw_line_vertical(point p0, point p1, color c)
{
  global_draw_line_vertical(this, p0, p1, c);
}

inline void backing_panel::draw_line_horizontal(point p0, point p1, color c)
{
  global_draw_line_horizontal(this, p0, p1, c);
}




#endif

