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

#include "dingl.h"
#include "trail.h"
#include "log.h"

void trail_t::alloc (int n) {
  if (n > n_tpts) {
    n_tpts = n;
    if (tpts) delete[] tpts;
    tpts = new float [2 * n_tpts];
  }
}

trail_t::trail_t () {
  cur = 0;
  total = 0;
}

trail_t::trail_t (int t) {
  cur = 0;
  total = 0;
  set (t);
}

void trail_t::set (int t) {
  if (t > total) alloc (t);
  total = t;
  if (total == 0) reset ();
}

void trail_t::reset () {
  cur = 0;
  pts.x.clear ();
  pts.y.clear ();
}

void trail_t::add (float x, float y) {
	if (total && !(x == last.x && y == last.y)) {
		last.x = x; last.y = y;
		int dt = cur - total;
		if (dt > -1) {
			int npops = dt + 1;
			for (int i = 0; i < npops; ++i) {
        pts.x.pop_front ();
        pts.y.pop_front ();
      }
			cur -= npops;
		}
    pts.x.push_back (x);
    pts.y.push_back (y);
		++cur;
	}
}

void trail_t::change (int delta) {
  total += delta;
  if (delta > 0) 
    alloc (total);
  else {
	  if (total < 1) {
      total = 0;
      reset ();
    } 
  }
}

void trail_t::draw () {
  if (total) {
    int m = 0, n = 0;	
    float x, y;
    for (std::list< float >::iterator xiter = pts.x.begin (), xjter = pts.x.end (), yiter = pts.y.begin (); xiter != xjter; ++xiter, ++yiter) {
      x = *xiter;
      y = *yiter;
      tpts[m++] = x; tpts[m++]=y;
      ++n;
    }
    glVertexPointer (2, GL_FLOAT, 0, tpts);
    glDrawArrays (GL_LINE_STRIP, 0, n);
  }
}

#ifdef __SVG__
void trail_t::write () {
  dlog << "<polyline points=\"";
  float x, y;
  for (std::list< float >::iterator xiter = pts.x.begin (), xjter = pts.x.end (), yiter = pts.y.begin (); xiter != xjter; ++xiter, ++yiter) {
    x = *xiter;
    y = *yiter;
    dlog << x << "," << y << ' ';
	}
  dlog << "\" style=\"stroke-width:1\" fill=\"none\" stroke=\"black\"/>" << endl;
}
#endif
