/*
# Docsis cable modem diagnostics (cmdiag)
#
# Copyright (C) 2006-2007 Emil Penchev
#
# This program is free software, distributed under the terms of
# the GNU General Public License 2.0
#
*/


#include <curses.h>
#include <string.h>
#include <stdio.h>
#include "pbar.h"
#include "globals.h"

/* Constructor for the bar */
PowerBar::PowerBar(int x, int y, string tp, string s_meas, string e_meas, int s_mark, int e_mark, 
                   int len, int m_parts, int bartype) : Bar(x, y, tp, s_meas, e_meas, s_mark, e_mark, len)
{
	max_parts = m_parts;
 
	int bar_parts_colors_ds[] = { RED, WHITE, GREEN, WHITE, RED };
	int bar_parts_lenghts_ds[] = { DS_BAR_LOW_RED_LEN, DS_BAR_LOW_WHITE_LEN, DS_BAR_MIDDLE_GREEN_LEN, DS_BAR_HIGH_WHITE_LEN, DS_BAR_HIGH_RED_LEN  }; 
	int bar_parts_colors_us[] = { RED, WHITE, GREEN, WHITE, RED };
	int bar_parts_lenghts_us[] = { US_BAR_LOW_RED_LEN, US_BAR_LOW_WHITE_LEN, US_BAR_MIDDLE_GREEN_LEN, US_BAR_HIGH_WHITE_LEN, US_BAR_HIGH_RED_LEN  }; 
	int bar_parts_lenghts_snr[] = { SNR_BAR_RED_LEN, SNR_BAR_WHITE_LEN, SNR_BAR_GREEN_LEN };
	int bar_parts_colors_err_rate[] = { GREEN, WHITE, RED };
	int bar_parts_lenghts_err_rate[] = { ERR_RATE_BAR_GREEN_LEN, ERR_RATE_BAR_WHITE_LEN, ERR_RATE_BAR_RED_LEN };
	
	//Downstream
	if (bartype == 1) 
	{
		bar_parts_lenghts = bar_parts_lenghts_ds;
		bar_parts_colors = bar_parts_colors_ds;
	}
 
	//Upstream
	if (bartype == 2) 
	{
		bar_parts_lenghts = bar_parts_lenghts_us;
		bar_parts_colors = bar_parts_colors_us;
	} 
 
	//SNR
	if (bartype == 3) 
	{
		bar_parts_lenghts = bar_parts_lenghts_snr;
		bar_parts_colors = bar_parts_lenghts_snr;
	}
	
	//Error
	if (bartype == 4) 
	{
		bar_parts_lenghts = bar_parts_lenghts_err_rate;
		bar_parts_colors = bar_parts_colors_err_rate;
	}
 
	/* Init the bar struct lenght colot start and end position */
	parts = new color_parts[max_parts];

	for (int i = 0; i < max_parts; i++) 
	{
		parts[i].n_color = bar_parts_colors[i];
		if (bartype == 4)
			parts[i].col_pair = i + 6;
		else parts[i].col_pair = i + 1;
 
		if (i == 0) parts[i].start_pos = xpos;
		else parts[i].start_pos = parts[i-1].end_pos; 
 
		if (bar_parts_lenghts != NULL) {
			parts[i].end_pos = parts[i].start_pos + bar_parts_lenghts[i];
			parts[i].lenght = bar_parts_lenghts[i];
		}
	}
 
}

void PowerBar::SignalUpdate(int lev, string slev)
{
	int n_mpart = 0;
	int bar_len = 0;
	string  res_lev;
	int i = 0;
	string emptystr = "               ";
 
	if (*type == "Downstream") 
	{
		bar_len = bar_lenght / 2;
		bar_len += lev;
	}
	else
		bar_len = lev;
 
	while (1) 
	{
		if (bar_len > parts[i].lenght) 
		{
			bar_len -= parts[i].lenght;
			parts[i].draw_lenght = parts[i].lenght;
			i++;
		}
		else 
		{
			parts[i].draw_lenght = bar_len;
			n_mpart = i;
			break;
		}
	}
 
	if (slev != "") 
	{
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0); 
 
		// draw update
		for (i = 0; i <= n_mpart; i++) 
		{
			set_color(parts[i].n_color, parts[i].col_pair, 1); //On
			draw_part(ypos, parts[i].start_pos, parts[i].start_pos +  parts[i].draw_lenght);
			set_color(parts[i].n_color, parts[i].col_pair, 0); //Off
		}
 
		//sprintf(res_lev, "%d", lev);
		attroff(A_BOLD);
		res_lev = slev;
		res_lev = res_lev + "dBmV";
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str()); 
		mvwaddstr(stdscr, ypos, parts[max_parts-1].end_pos + 1, res_lev.c_str());
	}
	else 
	{
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0); 
		attroff(A_BOLD);
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
		res_lev = "Timeout";
		mvwaddstr(stdscr, ypos, parts[max_parts-1].end_pos + 3, res_lev.c_str());
	}
 
	refresh();
}

void PowerBar::ErrRateUpdate(int bits)
{
	//int nres = 0;
	int bits_s = 0;
	int i = 0;
	int n_mpart = 0;
	int bar_len = 0;
	string emptystr = "               ";
	
	if ((bits > level) && (level == 0)) 
	{
		level = bits; 
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0);
		attroff(A_BOLD);
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
	}
	else if (bits > level) 
	{
		if (level == 0)
			level = bits;
		bar_len = (bits-level) / 2;
        	if (bar_len > ERR_RATE_BAR_LENGHT) 
			bar_len = ERR_RATE_BAR_LENGHT;
		while (1) 
		{
			if (bar_len > parts[i].lenght) 
			{
				bar_len -= parts[i].lenght;
				parts[i].draw_lenght = parts[i].lenght;
				i++;
			}
			else 
			{
				parts[i].draw_lenght = bar_len;
				n_mpart = i;
				break;
			}
		}
		
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0);
		//nres = (bits-level) / 2;
		bits_s = (bits-level);
		level = bits;
		
		// draw update
		for (i = 0; i <= n_mpart; i++) 
		{
			set_color(parts[i].n_color, parts[i].col_pair, 1); //On
			draw_part(ypos, parts[i].start_pos, parts[i].start_pos +  parts[i].draw_lenght);
			set_color(parts[i].n_color, parts[i].col_pair, 0); //Off
		}
		attroff(A_BOLD);
		string sbits_s = (itos(bits_s)) + " bps";
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, sbits_s.c_str());
		
	}
	else 
	{
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0);
		attroff(A_BOLD);
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
	}

	refresh();
		
}



