
// 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 SUBPANEL_HH
#define SUBPANEL_HH


#include "panel.hh"

//
// Drawable region, with drawing routines
//

class subpanel : public panel
{
public:

  panel*  parent;
  point   offset;
  
  subpanel(panel* parent, point offset, int w, int h);
  virtual ~subpanel() {}

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

  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 void   clear_rect(color c, point corner1, point corner2);
  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);

  virtual void   draw_circle(pointf p0, float radius, color c);
  virtual void   draw_triangle(pointf p0, pointf p1, pointf p2, color c);

  void resize(int x, int y, int w, int h);
};


inline subpanel::subpanel(panel* parent, point offset, int w, int h) : panel(w, h)
{
  this->parent = parent;
  this->offset = offset;
}


inline void subpanel::draw_point_no_boundscheck(point p, color c)
{
  if(p.y<0 || p.y>=height || p.x<0 || p.x>=width)
    abort();
  parent->draw_point(p+offset, c);
}

inline color subpanel::get_point_no_boundscheck(point p)
{
  return parent->get_point(p+offset);
}

inline void subpanel::clear_rect(color c, point corner1, point corner2)
{
  parent->clear_rect(c, corner1+offset, corner2+offset);
}

inline void subpanel::draw_circle(pointf p0, float radius, color c)
{
  parent->draw_circle(p0 + pointf(offset), radius, c);
}

inline void subpanel::draw_triangle(pointf p0, pointf p1, pointf p2, color c)
{
  parent->draw_triangle(p0 + pointf(offset), p1 + pointf(offset), p2 + pointf(offset), c);
}


inline void subpanel::resize(int x, int y, int w, int h)
{
  offset.x = x;
  offset.y = y;
  width = w;
  height = h;
}


inline void subpanel::draw_text(const char* text, color c, int x, int y, int flags)
{
  parent->draw_text(text, c, x + offset.x, y + offset.y, flags);
}

inline void subpanel::draw_text(const wchar_t* text, color c, int x, int y, int flags)
{
  parent->draw_text(text, c, x + offset.x, y + offset.y, flags);
}

inline void subpanel::draw_text(const char16_t* text, color c, int x, int y, int flags)
{
  parent->draw_text(text, c, x + offset.x, y + offset.y, flags);
}

inline void subpanel::draw_text(const char32_t* text, color c, int x, int y, int flags)
{
  parent->draw_text(text, c, x + offset.x, y + offset.y, flags);
}


inline void subpanel::draw_multicolored_text(const char* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  parent->draw_multicolored_text(text, start_color, c, x + offset.x, y + offset.y, flags);
}

inline void subpanel::draw_multicolored_text(const wchar_t* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  parent->draw_multicolored_text(text, start_color, c, x + offset.x, y + offset.y, flags);
}

inline void subpanel::draw_multicolored_text(const char16_t* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  parent->draw_multicolored_text(text, start_color, c, x + offset.x, y + offset.y, flags);
}

inline void subpanel::draw_multicolored_text(const char32_t* text, int start_color, dt_colors& c, int x, int y, int flags)
{
  parent->draw_multicolored_text(text, start_color, c, x + offset.x, y + offset.y, flags);
}


inline int  subpanel::calculate_text_width(const char* text)
{
  return parent->calculate_text_width(text);
}

inline int  subpanel::calculate_text_width(const wchar_t* text)
{
  return parent->calculate_text_width(text);
}

inline int  subpanel::calculate_text_width(const char16_t* text)
{
  return parent->calculate_text_width(text);
}

inline int  subpanel::calculate_text_width(const char32_t* text)
{
  return parent->calculate_text_width(text);
}


inline int  subpanel::calculate_text_height(const char* text)
{
  return parent->calculate_text_height(text);
}

inline int  subpanel::calculate_text_height(const wchar_t* text)
{
  return parent->calculate_text_height(text);
}

inline int  subpanel::calculate_text_height(const char16_t* text)
{
  return parent->calculate_text_height(text);
}

inline int  subpanel::calculate_text_height(const char32_t* text)
{
  return parent->calculate_text_height(text);
}


inline void subpanel::set_text_size(int height_pixels)
{
  parent->set_text_size(height_pixels);
}


inline void subpanel::draw_svg_from_data(uint8_t* svg_data, int svg_data_length, int offset_x, int offset_y, int draw_width, int draw_height)
{
  parent->draw_svg_from_data(svg_data, svg_data_length, offset_x + offset.x, offset_y + offset.y, draw_width, draw_height);
}


inline void subpanel::draw_line(pointf p0, pointf p1, color c)
{
  parent->draw_line(p0 + pointf(offset), p1 + pointf(offset), c);
}


inline void subpanel::draw_line_horizontal(point p0i, point p1i, color c)
{
  parent->draw_line_horizontal(p0i + offset, p1i + offset, c);
}


inline void subpanel::draw_line_vertical(point p0i, point p1i, color c)
{
  parent->draw_line_vertical(p0i + offset, p1i + offset, c);
}


inline void subpanel::draw_line_known_background(pointf p0, pointf p1, color c, color bg)
{
  parent->draw_line_known_background(p0 + pointf(offset), p1 + pointf(offset), c, bg);
}



#endif
