/* frame.h -- code for drawing frame.  -*- C++ -*-
   Copyright (C) 2025-2026 Gerardo Ballabio

   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/>. */

#include <vector>
#include <gtkmm.h>
#include <epoxy/gl.h>

#ifndef __FRAME_
#define __FRAME_

class gl_frame
{
private:
  // this is needed to access current font via create_pango_layout
  Gtk::Widget &widget;

  int width, height, font_size;
  GLfloat pixel_scale;
  double scale, vscale;
  std::vector<char> tchar;
  std::vector<int> tx, ty, twidth, theight;
  std::vector<Glib::ustring> tlabel;
  std::vector<GLfloat> tvertices;

  GLuint i_axes, i_cube, v_cube, i_tick, v_tick, n_ticks, big_ticks,
    i_bar, v_bar, i_tick2, v_tick2, n_ticks2, big_ticks2;
  GLint s_tick_xy, s_tick_xz, s_tick_yz, s_tick_yx, s_tick_zx, s_tick_zy;
  GLfloat matrix[16];
  bool d_axes, d_cube, d_bar;

  // handles for OpenGL objects
  GLuint h_program, h_vertex_shader, h_fragment_shader,
    h_vertex_array_axes, h_vertex_buffer_axes, h_index_buffer_axes,
    h_vertex_array_cube, h_vertex_buffer_cube, h_index_buffer_cube,
    h_vertex_array_bar, h_vertex_buffer_bar, h_index_buffer_bar,
    h_program_tex, h_vertex_shader_tex, h_fragment_shader_tex,
    h_vertex_array_tex, h_buffer_tex, h_texture;
  // uniform variables
  GLuint u_matrix, u_matrix_tex, u_sampler_tex;

  void init_lines();
  void init_textures();
  void init_subtexture(char text);
  void init_axes();
  void init_cube();
  void init_bar();
  void set_axes();
  void set_ticks();
  void set_ticks_sides();
  void set_ticks_scale(std::vector<double> &ticks, int &start, int &stride,
		       double min, double max);
  void set_font_size();
  void draw_axes();
  void draw_axes_labels();
  void draw_cube();
  void draw_ticks_labels();
  void draw_bar();
  void draw_bar_labels();
  void draw_texture(int n, const GLfloat *in,
		    GLfloat scalex, GLfloat scaley, int offset,
		    bool cube = true);
public:
  gl_frame(Gtk::Widget &widget_);

  void init();
  void set_frame(int width_, int height_);
  void set_scale(double scale_);
  void set_vscale(double vscale_);
  void set_matrix(const GLfloat *matrix_);
  void set_draw_axes(bool draw_) { d_axes = draw_; }
  void set_draw_cube(bool draw_) { d_cube = draw_; }
  void set_draw_bar(bool draw_) { d_bar = draw_; }

  const int get_font_size() { return font_size; }
  const double get_scale() { return scale; }
  const bool get_draw_axes() { return d_axes; }
  const bool get_draw_cube() { return d_cube; }
  const bool get_draw_bar() { return d_bar; }

  void draw();
};

#endif /* __FRAME_ */
