/*
# 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 <unistd.h>
#include <stdlib.h>
#include "bar.h"
#include "globals.h"

/* sets on or off the desired color */
void Bar::set_color(int fg_color, int n_color, int on)
{
	if (on)
	{
		init_pair(n_color, fg_color, fg_color);
		attron(COLOR_PAIR(n_color)); 
	}
	else attroff(COLOR_PAIR(n_color));
}

/* Draws color part of the bar */
void Bar::draw_part(int y, int start_pos, int end_pos)
{
	int i = 0;
 
	for (i = start_pos; i < end_pos; i++)
		mvwaddch(stdscr, y, i, ACS_CKBOARD); 
 
	refresh();
}

string Bar::itos(int number)
{
	stringstream ss;
	string str;
	ss << number;
	ss >> str;
	
	return str;
}
 
/* Helper function, draws border around the bar */
void Bar::draw_border()
{
	int end_pos = xpos + bar_lenght;
	
	init_pair(10, COLOR_CYAN, COLOR_BLACK);
	attron(COLOR_PAIR(10));
 
	for (int i = xpos; i <= end_pos; i++)
		mvwaddch(stdscr, ypos+1, i, ACS_HLINE);
 
	for (int i = xpos; i <= end_pos; i++)
		mvwaddch(stdscr, ypos-1, i, ACS_HLINE);
 
	mvwaddch(stdscr, ypos-1, xpos-1, ACS_ULCORNER);
	mvwaddch(stdscr, ypos+1, xpos-1, ACS_LLCORNER);
 
	mvwaddch(stdscr, ypos-1, xpos+bar_lenght+1, ACS_URCORNER);
	mvwaddch(stdscr, ypos+1, xpos+bar_lenght+1, ACS_LRCORNER);
 
	mvwaddch(stdscr, ypos, xpos-1, ACS_VLINE);
	mvwaddch(stdscr, ypos, xpos+bar_lenght+1, ACS_VLINE); 
 
	attroff(COLOR_PAIR(10));
}

/* Constructor for the bar */
Bar::Bar(int x, int y, string tp, string s_meas, string e_meas, int s_mark, int e_mark, int len)
{
	xpos = x;
	ypos = y;
	
	type = new string(tp);
	st_mark_measure = new string(s_meas);
	end_mark_measure =  new string(e_meas);
	
	bar_lenght = len;
	st_mark = s_mark;
	end_mark = e_mark; 
	level = 0;
}

void Bar::Draw()
{
	
	mvwaddstr(stdscr, ypos-2, xpos, type->c_str());
 
	//Print Start mark
	string tmp_mark(itos(st_mark));
	tmp_mark = tmp_mark + *st_mark_measure;
	mvwaddstr(stdscr, ypos+2, xpos, tmp_mark.c_str());
	
	//Print End Mark
	tmp_mark = itos(end_mark);
	tmp_mark = tmp_mark + *end_mark_measure; 
	mvwaddstr(stdscr, ypos+2, xpos+bar_lenght - 5, tmp_mark.c_str());
 
	// Draw empty bar
	attron(A_BOLD);
	set_color(BLACK, 12, 1);
	draw_part(ypos, xpos, xpos + bar_lenght);
	set_color(BLACK, 12, 0); 
	attroff(A_BOLD);
	
	refresh();
}

void Bar::DataUpdate(int lev)
{
	int draw_lenght = 0;	//how much we must draw
	int min_cell_div = 0;	// this is in bits
	int bits_s = 0;			//performance in bit rate
	int nres = 0;
	string str_lev;			//stores data to be printted on the screen
	string measure_unit;	//bps kbs Mpbs
	string emptystr = "               ";
		
	if (lev > level) 
	{
		if (level == 0) 
			level = lev;
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0);
		min_cell_div = 12500;
		nres = ((lev-level) * 8) / min_cell_div;
		bits_s = (lev - level) * 8;
		bits_s /= 1000; 
		measure_unit = "kbps"; 
		if (nres < 1) 
			nres = 1;
		if (nres > DAT_BAR_LENGHT )
			nres = DAT_BAR_LENGHT;
		draw_lenght = xpos + nres;
		level = lev;
		// draw update
		set_color(GREEN, 3, 1); //On
		draw_part(ypos, xpos, draw_lenght);
		set_color(GREEN, 3, 0); //Off
		attroff(A_BOLD);
		str_lev = itos(bits_s);
		str_lev = str_lev + " ";
		str_lev = str_lev + measure_unit;
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, str_lev.c_str());
	}
	else if ((lev < level) || (lev == 0)) 
	{
		// 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());
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, "0 kbps");
	}

	refresh();

}

void Bar::RxUpdate(int lev)
{
	int draw_lenght = 0;	//how much we must draw
	string str_lev;		    //stores data to be printted on the screen
	string emptystr = "               ";
	string measure_unit = "dBmV";
	int rxpower = lev;
	
	if (lev != level) 
	{
		if (level == 0) 
			level = lev;
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0);
		if (lev > DAT_BAR_LENGHT ) 
			rxpower = DAT_BAR_LENGHT;
		draw_lenght = xpos + rxpower;
		level = lev;
		// draw update
		set_color(GREEN, 3, 1); //On
		draw_part(ypos, xpos, draw_lenght);
		set_color(GREEN, 3, 0); //Off
		attroff(A_BOLD);
		str_lev = itos(rxpower);
		str_lev = str_lev + " ";
		str_lev = str_lev + measure_unit;
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, str_lev.c_str());
	}
	/*else if ((lev < level) || (lev == 0)) {
		// 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();
}


// Unused method for the FEC counters

/*void Bar::CodeWordsUpdate(int ncwords)
{
	int draw_lenght = 0;	//how much we must draw
	string str_cwords;      //stores data to be printted on the screen
	string emptystr = "               ";
	string measure_unit = "Code Words";
	int code_words = ncwords;
	
	if (level != ncwords)
	{
		if (level == 0)
			level = ncwords;
		// erase bar contents
		attron(A_BOLD);
		set_color(BLACK, 12, 1);
		draw_part(ypos, xpos, xpos + bar_lenght);
		set_color(BLACK, 12, 0);
		if (ncwords > DAT_BAR_LENGHT ) 
			code_words = DAT_BAR_LENGHT;
		draw_lenght = xpos + code_words;
		level = ncwords;
		// draw update
		set_color(GREEN, 3, 1); //On
		draw_part(ypos, xpos, draw_lenght);
		set_color(GREEN, 3, 0); //Off
		attroff(A_BOLD);
		str_cwords = itos(code_words);
		str_cwords = str_cwords + " ";
		str_cwords = str_cwords + measure_unit;
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, emptystr.c_str());
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, str_cwords.c_str());
	}
	else if ((code_words < level) || (code_words == 0)) 
	{
		// 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());
		mvwaddstr(stdscr, ypos, xpos + bar_lenght + 1, "0 Code Words");
	}

	refresh();

}*/













