/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     Internet Radio Automation & Encoding Toolkit
#+
#+     Copyright (C) 2018, 2019, 2020, 2021 by Kevin C. O'Kane
#+
#+     Kevin C. O'Kane
#+     kc.okane@gmail.com
#+     https://www.cs.uni.edu/~okane
#+     https://threadsafebooks.com/
#+
#+ 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 2 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, write to the Free Software
#+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//	Nov 4, 2022

#include "includes.h"
#include "common-externs.h"

#define SLASH '/'

//-----------------------------
//
//	draw meters and bars
//
//-----------------------------

gboolean digital_draw2_draw (GtkDrawingArea *widget, cairo_t *cr) {

	double hor, ver, t1, len;

	extern double cairo_bg_red;
	extern double cairo_bg_green;
	extern double cairo_bg_blue;

	double Avg = 0.0, AvgB = 0.0, AvgM = 0.0;

	static double MaxLB[RMX], MaxRB[RMX], MaxMC[RMX];

	int noLine = 0;

//-------------------------
//	Meter background
//-------------------------

//	cairo_set_source_rgb(cr, 0.07, 0.07, 0.15); // blue-ish background
//	cairo_set_source_rgb(cr, cairo_bg_red, cairo_bg_green, cairo_bg_blue);
//	cairo_rectangle (cr, 0.0, 2.0, 406.0, 260.0);
//       	cairo_fill(cr); // fill in arc
//       	cairo_stroke(cr);

//	if (1 || which_meters != BAR_METER) {
	cairo_set_source_rgb(cr, .0, .0, .0); // center line color
	cairo_fill(cr);
	cairo_paint (cr);
//		}

#define MHOR 55.0

//----------------------------------------------
//	average the past X to dampen movement
//----------------------------------------------

#define ACOUNT 2

	Lx = 0.0;
	for (int i=0; i < ACOUNT; i++) Lx = Lx + lchan[i];
	Rx = 0.0;
	for (int i=0; i < ACOUNT; i++) Rx = Rx + rchan[i];

	Lx = Lx / ACOUNT;
	Rx = Rx / ACOUNT;

#define DECAY_FACTOR 250.0

//--------------------------------
//	LEFT Channel meter
//--------------------------------

	if (which_meters != BAR_METER) {

		if (Lx > ClipLevel) L_Clipping = 1;
		else L_Clipping = 0;

		if (Lx > 0.0)
			t1 = (Lx / 100.0) * M_PI;
		else
			t1 = 0.0;

		if (t1 < 0.1)
			MaxLM = 0.0;
		else if (t1 > MaxLM)
			MaxLM = t1;
		else if (MaxLM > 0.0)
			MaxLM = MaxLM - MaxLM / DECAY_FACTOR;

		MaxL[MLr] = t1 * t1;

		Avg = 0.0;

		for (int i = 0; i < RMX; i++) {
			Avg += MaxL[i];
			}
		}


	if (which_meters == BAR_METER) {

		AvgB = 0.0;

		MaxLB[MLr] = Lx * Lx;

		for (int i = 0; i < RMX; i++) {
			AvgB += MaxLB[i];
			}
		}

	MLr ++;

	if (MLr == RMX ) MLr = 0;

	if (which_meters != BAR_METER) {

		hor = MHOR;
		ver = 50.0;
		len = 30.0;
		dneedles(cr, hor, ver, len, t1, MaxLM, 1, sqrtf(Avg / RMX));
		cairo_move_to (cr, hor - 10.0, ver + 15.0 ); // top
		if (L_Clipping) cairo_show_text(cr, "Peak");
		else cairo_show_text(cr, "Left");
		cairo_stroke (cr);
		}
	else {
		level_bars(cr, Lx, sqrtf(AvgB / RMX), LEFT);
		}


//--------------------------------
//	RIGHT Channel meter
//--------------------------------

	if (which_meters != BAR_METER) {

		hor = MHOR + 180;

		if (Rx > ClipLevel) R_Clipping = 1;
		else R_Clipping = 0;

		if (Rx > 0.0) t1 = (Rx / 100.0) * M_PI;
		else t1 = 0.0;

		if (t1 < 0.1) MaxRM = 0.;
		else if (t1 > MaxRM) {
			MaxRM = t1;
			}
		else {
			if (MaxRM > 0.0) MaxRM = MaxRM - MaxRM / DECAY_FACTOR;
			}

		MaxR[MRr] = t1 * t1;

		Avg = 0.0;
		for (int i = 0; i < RMX; i++) {
			Avg += MaxR[i];
			}
		}


	if (which_meters == BAR_METER) {
		MaxRB[MRr] = Rx * Rx;
		AvgB = 0.0;
		for (int i = 0; i < RMX; i++) {
			AvgB += MaxRB[i];
			}
		}

	MRr++;
	if (MRr == RMX ) MRr = 0;

	if (which_meters != BAR_METER) {
		dneedles(cr, hor, ver, len, t1, MaxLM, 2, sqrtf(Avg / RMX));
		cairo_move_to (cr, hor - 15., ver + 15.0 ); // top
		if (R_Clipping) cairo_show_text(cr, "Peak");
		else cairo_show_text(cr, "Right");
		cairo_stroke (cr);
		}
	else {
		level_bars(cr, Rx, sqrtf(AvgB / RMX), RIGHT);
		}

//----------------------------------------------------------
//	microphone meter
//
//	no microphone in Windows version
//----------------------------------------------------------

	MRx = MLx = 0.0;	// start a new sample - this one has been used.

	if (which_meters !=BAR_METER) {

		hor = 340.0;

		if (ML > CLIP_LEVEL) ML = 99.0;	// limit

		t1 = (ML / 100.0) * M_PI;	// fraction of PI

		if (t1 < 0.1) MaxMM = 0.;

		else if (t1 > MaxMM) {
			MaxMM = t1;
			}
		else {
			if (MaxMM > 0.0) MaxMM = MaxMM - MaxMM / DECAY_FACTOR;
			}

		MaxM[MMr] = t1 * t1;

		Avg = 0.0;

		for (int i = 0; i < RMX; i++) {
			Avg += MaxM[i];
			}
		}

	if (which_meters == BAR_METER) {

		MaxMC[MMr] = ML * ML;

		AvgM = 0.0;
		for (int i = 0; i < RMX; i++) {
			AvgM += MaxMC[i];
			}
		}

	MMr++;
	if (MMr == RMX ) MMr = 0;

	if (which_meters != BAR_METER) {
		dneedles(cr, hor, ver, len, t1, MaxMM, 3, sqrtf(Avg / RMX));
		cairo_move_to (cr, hor - 30., ver + 15.0 ); // top
		cairo_show_text(cr, "Microphone");
		cairo_stroke (cr);
		}
	else {
		level_bars(cr, ML, sqrtf(AvgM / RMX), MIC);
		}

//--------------------------
// 	balance meter
//--------------------------

	if (which_meters != BAR_METER) {

		hor = MHOR + 90;
		len = 30.0;

		Balance = 50.0 + 2.0 * (Rx - Lx);	// difference & double the effect

		if (Balance > 99.0 ) Balance = 99.0;
		if (Balance < 0.0) Balance = 0.0;
		t1 = (Balance / 100.0) * M_PI;

		dneedles(cr, hor, ver, len, t1, 0.0, 4, 0.0);

		cairo_move_to (cr, hor - 18., ver + 15.0 ); // top
		cairo_show_text(cr, "Balance");
		cairo_stroke (cr);
		}

	return FALSE;

//------------------------------------------
//	Following code not currently active
//------------------------------------------
//
//	cairo_set_line_width(cr, LINE_WIDTH);
//
//-------------------------
//	media clipping
//-------------------------
//
//	if (L_Clipping) { // display text
//        	cairo_set_source_rgb(cr, 1.0, 1.0, 0.3); // yellow
//		cairo_move_to (cr, HOR_ORIGIN - 30, VER_ORIGIN + 3 ); // top
//		cairo_show_text(cr, "Peak");
//		cairo_stroke (cr);
//		}
//
//	if (R_Clipping) { // display text
//        	cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); // red
//		cairo_move_to (cr, HOR_ORIGIN - 30, VER_ORIGIN + LINE_WIDTH + LINE_SEP + 5 ); // top
//		cairo_show_text(cr, "Peak");
//		cairo_stroke (cr);
//		}
//
//	return FALSE;

	}
