/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     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
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//	Oct 26, 2022

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

#define SLASH '/'

#define G_MAX DRAW_HEIGHT / 2.0 - 10.0	// graph center line location (zero is top)
#define G_MAX2 DRAW_HEIGHT - 60  	// baseline lower limit
#define G_LIM DRAW_HEIGHT		// bar length limit

//------------------------------------------
//	Process line (i) of the bar graph
//------------------------------------------

void    bar_graph(int lower, double chan[], int i, cairo_t *cr,
                  int connect_graph, int display_bars, int color, int noLine, int panel) {

	if (chan[i] > G_LIM) chan[i] = G_LIM;
	if (chan[i+1] > G_LIM) chan[i+1] = G_LIM;

//------------------------
//	vertical bars
//------------------------

	if (display_bars) draw_bars_only(cr, lower, i, chan, color, noLine, panel);

	if (bar_spots)
		if (super_bars) spots2(cr, i, chan[i], G_MAX2, 0, panel);
		else spots2(cr, i, chan[i], G_MAX, lower, panel);


//---------------------------------------
//	connecting horizontal graph lines
//---------------------------------------

	if (connect_graph) connecting_lines(cr, lower, i, chan);

	}

//-----------------------------
//	draw vertical bars
//-----------------------------

void    draw_bars_only(cairo_t *cr, int lower, int i, double chan[], int color, int noLine, int panel) {

	double length;
	double point;
	double bar_max;

	point = chan[i];

	if (panel == SMALL_PANEL) bar_max = 110.0;
	else bar_max = 240.0;

//------------------------------
//		centered graph
//------------------------------

	if (!super_bars) {

		if (lower == LOWER) {
			if (point > bar_max) point = bar_max;
			length = G_MAX + point - 2.0;
			cairo_move_to (cr, i * bar_space + G_OFF, length);

			cairo_line_to (cr,
			               i * bar_space + G_OFF,
			               G_MAX - 2.0 ); // baseline line
			}

		else { //upper
			if (point > bar_max) point = bar_max;
			length = G_MAX - point + 2.0;
			cairo_move_to (cr, i * bar_space + G_OFF, length);

			cairo_line_to (cr,
			               i * bar_space + G_OFF,
			               G_MAX + 2.0 ); // baseline line
			}

		cairo_stroke (cr);

		}

//-----------------------------
//		baseline graph
//-----------------------------

	else {

		color_bars(cr, i, 0, color); // restore
		cairo_move_to (cr, i * bar_space + G_OFF,
		               G_MAX2 - (double) chan[i]  ); // horizontal, vertical

		cairo_line_to (cr,
		               i * bar_space + G_OFF,
		               G_MAX2 ); // baseline line

		cairo_stroke (cr);
		}
	}


//-------------------------------------------------
//	draw connecting horizontal graph lines
//-------------------------------------------------

void	connecting_lines(cairo_t *cr, int lower, int i, double chan[]) {

// ???????

#define CONNECT_OFFSET 1.0 // connect bar distance from bar

	if (ray_count + i > 99) return;  // not at the end of the graph

	if (super_bars) {	// bars starting at the bottom
		cairo_move_to (cr, (double) ((i * bar_space) + G_OFF1),
		               G_MAX2 - (double) chan[i] - CONNECT_OFFSET ); // first bar

		cairo_line_to (cr, (double) (((i + ray_count) * bar_space) + G_OFF),
		               G_MAX2 - (double) chan[i + ray_count] - CONNECT_OFFSET ); // second bar

		cairo_stroke (cr); // do it
		return;
		}

	if (lower) { // below the centerline

		cairo_set_source_rgb(cr, 1.0, 0., 0.);      // red

		cairo_move_to (cr, (double) ((i * bar_space) + G_OFF1),
		               G_MAX + (double) chan[i] +  CONNECT_OFFSET ); // first bar

		cairo_line_to (cr, (double) (( (i + ray_count) * bar_space) + G_OFF),
		               G_MAX + (double) chan[i + ray_count] + CONNECT_OFFSET); // second bar
		}

	else { // above the center line

		cairo_set_source_rgb(cr, 1.0, 1.0, 0.3);         // yellow

		cairo_move_to (cr, (double) ((i * bar_space) + G_OFF1),
		               G_MAX - chan[i] - CONNECT_OFFSET ); // first

		cairo_line_to (cr, (double) (((i + ray_count) * bar_space) + G_OFF),
		               G_MAX - chan[i + ray_count] - CONNECT_OFFSET ); // second

		}

	cairo_stroke (cr); // do it

	}

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

void dots(cairo_t *cr, double hr, double vr) {
	cairo_move_to (cr, hr, vr ); // top
	cairo_arc (cr, hr, vr, 4.0, -M_PI, M_PI );
	cairo_line_to (cr, hr, vr );
	cairo_fill(cr); // fill in arc
	cairo_stroke (cr);
	}


