// src/schedulables_statistics_widget.cc - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This 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.
//
// SGPEMv2 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 SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA


#include "gettext.h"


#include "schedulables_statistics_widget.hh"
#include <sgpemv2/simulation.hh>
#include <sgpemv2/history.hh>
#include <sgpemv2/statistics.hh>

#include <iostream>
#include <sstream>

using namespace sgpem;
using namespace std;

using namespace Gtk;
using namespace Glib;


TabularSchedulableStatisticsWidget::TabularSchedulableStatisticsWidget()
{
	
	_show_runs = _show_perc = _show_inactive = _show_turn = 
			_show_resp =  _show_effic = 
			_show_ris_usage = _show_ris_block = true;
	
	//insert columns
	_columns.add(_col_name);
	_columns.add(_col_runs);
	_columns.add(_col_perc);
	_columns.add(_col_inactive);
	_columns.add(_col_turn);
	_columns.add(_col_resp);
	_columns.add(_col_effic);
	_columns.add(_col_ris_usage);
	_columns.add(_col_ris_block);
	
	_model = TreeStore::create(_columns);
	set_model(_model);
	
	//show only columns chosen by the user
	update_columns();
	
	set_headers_visible(true);
	
	// Register this HistoryObserver:
	Simulation::get_instance().get_history().attach(*this);		
}

TabularSchedulableStatisticsWidget::~TabularSchedulableStatisticsWidget()
{
	Simulation::get_instance().get_history().detach(*this);
}


void
TabularSchedulableStatisticsWidget::update(const History& changed_history)
{
	_model->clear();
	
	Statistics::get_instance().calculateStatisticsAt(changed_history.get_front());
	vector<const ProcessStatistics*> p_stats = Statistics::get_instance().get_process_statistics();
		
	for(unsigned int i_p = 0; i_p < p_stats.size(); i_p++)
	{
		TreeModel::Row riga_P = *(_model->append());
		
		riga_P[_col_name] 		= p_stats[i_p]->get_core()->get_name();
		riga_P[_col_runs] 		= p_stats[i_p]->get_execution_time();
		stringstream s1;		s1 << p_stats[i_p]->get_execution_progress() << "%";
		riga_P[_col_perc] 		= Glib::ustring(s1.str());
		riga_P[_col_inactive]= p_stats[i_p]->get_total_inactivity();
		stringstream s2;
		if (p_stats[i_p]->get_response_time() != -1)
			s2 << p_stats[i_p]->get_response_time() << " (avg:" << p_stats[i_p]->get_average_response_time() << ")";
		else
			s2 << "---";
		riga_P[_col_resp]		= Glib::ustring(s2.str());
		riga_P[_col_turn]		= p_stats[i_p]->get_turn_around();
		stringstream s3;
		if (p_stats[i_p]->get_efficiency() != -1)
			s3 << p_stats[i_p]->get_efficiency() << "%";
		else
			s3 << "---";				
		riga_P[_col_effic]		= Glib::ustring(s3.str());
		riga_P[_col_ris_usage]	= p_stats[i_p]->get_resource_usage_time();
		riga_P[_col_ris_block]	= p_stats[i_p]->get_resource_waitings_time();
			
		vector<const ThreadStatistics*> t_stats = p_stats[i_p]->get_threads_statistics();
		
		for(unsigned int i_t = 0; i_t < t_stats.size(); i_t++)
		{
			TreeModel::Row riga_T 	= *(_model->append(riga_P.children()));
			riga_T[_col_name] 		= t_stats[i_t]->get_core()->get_name();
			riga_T[_col_runs] 		= t_stats[i_t]->get_execution_time();
			stringstream s1;		s1 << t_stats[i_t]->get_execution_progress() << "%";
			riga_T[_col_perc] 		= Glib::ustring(s1.str());
			riga_T[_col_inactive]= t_stats[i_t]->get_total_inactivity();
			stringstream s2;
			if (t_stats[i_t]->get_response_time() != -1)
				s2 << t_stats[i_t]->get_response_time();
			else
				s2 << "---";
			riga_T[_col_resp]		= Glib::ustring(s2.str());
			riga_T[_col_turn]		= t_stats[i_t]->get_turn_around();
			stringstream s3;
			if (t_stats[i_t]->get_efficiency() != -1)
				s3 <<t_stats[i_t]->get_efficiency() << "%";
			else
				s3 << "---";							
			riga_T[_col_effic]		= Glib::ustring(s3.str());
			riga_T[_col_ris_usage]	= t_stats[i_t]->get_resource_usage_time();
			riga_T[_col_ris_block]	= t_stats[i_t]->get_resource_waitings_time();		
		}		
	}
	expand_all();
}


void 								
TabularSchedulableStatisticsWidget::update_columns()
{
	remove_all_columns();
	
	append_column(_("Schedulable"), _col_name);
	
	if (_show_runs)
		append_column(_("Running"), _col_runs);
	
	if (_show_perc )
		append_column(_("Completed"), _col_perc);
	
	if (_show_inactive)
		append_column(_("Inactivity"), _col_inactive);

	if (_show_turn)
		append_column(_("Turn Around"), _col_turn);

	if (_show_resp)
		append_column(_("Response"), _col_resp);
		
	//if (_show_turn)
//		append_column(_("Turn Around"), _col_inactive);

	if (_show_effic)
		append_column(_("Efficiency"), _col_effic);

	if (_show_ris_usage)
		append_column(_("Res. usage"), _col_ris_usage);
	
	if (_show_ris_block)
		append_column(_("Res. block"), _col_ris_block);

	
}

void		
TabularSchedulableStatisticsWidget::set_show_runs(bool b)
{
	_show_runs = b;
}
		
bool
TabularSchedulableStatisticsWidget::get_show_runs() const
{
	return _show_runs;
}
		
void		
TabularSchedulableStatisticsWidget::set_show_perc(bool b)
{
	_show_perc = b;
}
		
bool
TabularSchedulableStatisticsWidget::get_show_perc() const
{
	return _show_perc;
}
	
void		
TabularSchedulableStatisticsWidget::set_show_inactive(bool b)
{
	_show_inactive = b;
}
		
bool
TabularSchedulableStatisticsWidget::get_show_inactive() const
{
	return _show_inactive;
}	
	

void		
TabularSchedulableStatisticsWidget::set_show_turn_around(bool b)
{
	_show_turn = b;
}
		
bool		
TabularSchedulableStatisticsWidget::get_show_turn_around() const
{
	return _show_turn;
}

void		
TabularSchedulableStatisticsWidget::set_show_response(bool b)
{
	_show_resp = b;
}

bool		
TabularSchedulableStatisticsWidget::get_show_response() const
{
	return _show_resp;
}

void		
TabularSchedulableStatisticsWidget::set_show_efficiency(bool b)
{
	_show_effic = b;
}

bool		
TabularSchedulableStatisticsWidget::get_show_efficiency() const
{
	return _show_effic;
}
		
void		
TabularSchedulableStatisticsWidget::set_show_resource_usage(bool b)
{
	_show_ris_usage= b;
}
		
bool		
TabularSchedulableStatisticsWidget::get_show_resource_usage() const
{
	return _show_ris_usage;
}

void		
TabularSchedulableStatisticsWidget::set_show_resource_block(bool b)
{
	_show_ris_block= b;
}
		
bool		
TabularSchedulableStatisticsWidget::get_show_resource_block() const
{
	return _show_ris_block;
}

/*
void
TabularSchedulableStatisticsWidget::draw_widget(cairo_t* ctx)
{
	cout << "\nTabularSchedulableStatisticsWidget::draw_widget";


  // draw text: T = n as title
	
	const History& hist = Simulation::get_instance().get_history();	
	cairo_text_extents_t extents;
	stringstream ss;
	ss << "!CIAO MONDO!" ;
	cairo_text_extents(ctx, ss.str().c_str(), &extents);
	cairo_move_to(ctx, _draw_w/2 - extents.width/2.0, extents.height*2.0);
	cairo_show_text(ctx, ss.str().c_str());
	
	
	//cairo_save(ctx);
	//cairo_set_source(ctx, _running_process_gradient);
      // cairo_matrix_init_scale(&matrix, 1.0, y);
      // cairo_matrix_translate(&matrix, 0, -y);
	//cairo_matrix_init_translate(&matrix, 0, -y);
	//cairo_pattern_set_matrix (_running_process_gradient, &matrix);
	cairo_set_source_rgba(ctx, 1,0,0,1);
	cairo_rectangle(ctx, 0.5, 0.5, 10, 10);
	cairo_fill(ctx);
	
	//cairo_restore(ctx);
	//break;

}


void
TabularSchedulableStatisticsWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height)
{	
	cout << "\nHolt widget calc_drawing_size";
}

void
TabularSchedulableStatisticsWidget::calc_widget_size(size_t& width, size_t& height)
{	
	cout << "\nHolt widget calc_widget_size";
	//width = height = 20; // default minimum size
}

*/
