/*
* curve_display.cc
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/

#include "curve_display.h"
#include "viewwin.h"
#include "multi_curve.h"
#include "console.h"

#include <vector>
using namespace std;

extern viewport view;

void curve_display::add_gutter () {
  static const float GUTTER = 0.01f;
  bbox.resize (GUTTER, GUTTER);
}

void curve_display::unit_bbox () {
  bbox (0, -1, 1, 1);
  add_gutter ();
}

curve_display::curve_display (int w, int h) {
  gl_pts = 0;
  n_glpts = 0;
  crv = 0;
  set_size (w, h);
  unit_bbox ();
}

void curve_display::setbbox (int sf) {
  if (sf) {
    bbox (-0.5f, -1, 1.5f, 1);
  } else {
    bbox (0, -1, 1, 1);
  }
  add_gutter ();
}

void curve_display::calc_bbox () {
  crv->calc_bbox (bbox);
  add_gutter ();
}

void curve_display::draw () {
  widget::draw ();
  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
  glLoadIdentity ();
  glOrtho (bbox.left, bbox.right, bbox.bottom, bbox.top, -1, 1);
  glViewport (posx, posy, extents.width, extents.height);
  glMatrixMode (GL_MODELVIEW);
    draw_curve ();
  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();
  glViewport (0, 0, view.width, view.height);
}

void curve_display::draw_curve () {
	if (!crv) return;
  int n = 0, r = 0;
  vector<curve>& curv = crv->curv;
  for (int i = 0, j = curv.size(); i < j; ++i) n += curv[i].vpts.size ();
  if (n_glpts < n) {
    if (gl_pts) delete[] gl_pts;
    gl_pts = new float [2 * n];
    n_glpts = n;
  }
  for (int i = 0, j = curv.size(); i < j; ++i) {
    vector<crvpt>& vpts = curv[i].vpts;
    for (int p = 0, q = vpts.size (); p < q; ++p) {
      gl_pts[r++] = vpts[p].x;
      gl_pts[r++] = vpts[p].y;
    }
  }
  glVertexPointer (2, GL_FLOAT, 0, gl_pts);
  glDrawArrays (GL_LINE_STRIP, 0, n);
}

curve_display::~curve_display () {
  if (gl_pts) delete [] gl_pts;
}

