/*
* range.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 "range.h"
#include "font.h"
#include "utils.h"
#include "log.h"
#include "audio.h"
#include "scale_info.h"
#include "console.h"

#include <map>
#include <fstream>
using namespace std;

extern multi_curve ran_mod_width_crv, ran_mod_height_crv;

range::range () : fixed (CENTER), mod (&ran_mod_width_crv, &ran_mod_height_crv)  {}

void range::calc_note_freq (int i, scale_info& si) {
	float interval = si.intervals [intervals[i]];
	notes[i].set_freq (si.lo_tonic, interval);
	delta_step = notes[1].step - notes[0].step;
}

void range::calc (scale_info& si) {
	calc_note_freq (0, si);
	calc_note_freq (1, si);
}

void range::change_note (int i, int j, scale_info& si) {
	note& ni = notes [i];
	ni.change_scale_pos (j, si);
	intervals[i] = si.notes [ni.scale_pos];
	calc_note_freq (i, si);
	ni.set_name (intervals[i], si.western);
}

void range::change_octave (int i, int o, scale_info& si) {
	note& ni = notes[i];
	ni.octave += o;
	calc_note_freq (i, si);
}

void range::draw_labels (int label, int show_frequency) {

	int ln = line_height;
  int L = extents.left, B = extents.bottom - ln, B2 = B - ln;
  int R = extents.right, T = extents.top, T2 = T + ln;

  glColor3f (1, 1, 1);
  pts[0]=L; pts[1]=extents.bottom;
  pts[2]=R; pts[3]=extents.bottom;
	pts[4]=R; pts[5]=extents.top;
	pts[6]=L; pts[7]=extents.top;
	glVertexPointer (2, GL_INT, 0, pts);
	glDrawArrays (GL_LINE_LOOP, 0, 4);

	string& n0 = notes[0].name;
	draw_string (n0, L, B);
	draw_string (n0, L, T);
	if (show_frequency) {
		string& h0 = notes[0].hz_name;
		draw_string (h0, L, B2);
		draw_string (h0, L, T2);
	}

	if (label == BOTH) {
		string& n1 = notes[1].name; 
		draw_string (n1, R, B);
		draw_string (n1, R, T);
		if (show_frequency) {
			string& h1 = notes[1].hz_name;
			draw_string (h1, R, B2);
			draw_string (h1, R, T2);
		}
	}

}

void range::sample_rate_changed () {
  for (int i = 0; i < 2; ++i) notes[i].set_freq (notes[i].hz);
  delta_step = notes[1].step - notes[0].step;
}

void range::init_mod () {
	extern rnd<int> RAN_MOD_BPM;
	mod.active = 0;
	mod.fm.depth = 0;
	mod.fm.bv.set_bpm (RAN_MOD_BPM());
	mod.fm.initial = extents.width;
	mod.am.depth = 0;
	mod.am.bv.set_bpm (RAN_MOD_BPM());
	mod.am.initial = extents.height;
}

void range::change_height (int dh) {
	int top = extents.top + dh;
	if (top > extents.bottom) {
		extents (extents.left, extents.bottom, extents.right, top);
		mod.am.initial = extents.height;
		mod.am.bv.now = 0.0f;
		cons << "Height = " << extents.height << " Vol/pixel = " << 1.0f / extents.height << eol;
	}
}

void range::print_hz_per_pixel () {
	cons << YELLOW << "Width = " << extents.width << " pixels, Hz/pixel = " << hz_per_pix () << eol;
}
