// src/simulation_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 3 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, see http://www.gnu.org/licenses/.



#include "gettext.h"


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

#include <iostream>
#include <stdio.h>	//per sprintf


using namespace sgpem;
using namespace std;

using namespace Gtk;
using namespace Glib;


TabularSimulationStatisticsWidget::TabularSimulationStatisticsWidget()
{		
	//insert columns
	_columns.add(_col_inactivity);
	_columns.add(_col_progress);
	_columns.add(_col_turn);
	_columns.add(_col_response);
	_columns.add(_col_effic);
	_columns.add(_col_term_procs);
	_columns.add(_col_term_threads);
	_columns.add(_col_through_procs);
	_columns.add(_col_through_threads);

	_model = TreeStore::create(_columns);
	set_model(_model);
	
	append_column(_("Avg. inactivity time"), _col_inactivity);
	append_column(_("Avg. execution progress"), _col_progress);
	append_column(_("Avg. turn around"), _col_turn);
	append_column(_("Avg. response time"), _col_response);
	append_column(_("Avg. efficiency"), _col_effic);
	append_column(_("# terminated processes"), _col_term_procs);
	append_column(_("# terminated threads"), _col_term_threads);
	append_column(_("Avg. processes throughput"), _col_through_procs);
	append_column(_("Avg. threads throughput"), _col_through_threads);
	                                
                                 
	set_headers_visible(true);      
	                                
	// Register this HistoryObserver:
	Simulation::get_instance().get_history().attach(*this);		
}                                
                                 
TabularSimulationStatisticsWidget::~TabularSimulationStatisticsWidget()
{
	Simulation::get_instance().get_history().detach(*this);
}


void
TabularSimulationStatisticsWidget::update(const History& changed_history)
{
	_model->clear();
	int num_procs=0, num_threads=0;
	vector<Process*> procs = Simulation::get_instance().get_history().get_environment_at(0).get_processes();
	num_procs = procs.size();
	for (unsigned int i =0; i < procs.size(); i++)
		num_threads += procs[i]->get_threads().size();
	
	if (num_procs == 0)
		return;
			
	Statistics::get_instance().calculateStatisticsAt(changed_history.get_front());
	const SimulationStatistics* stats = Statistics::get_instance().get_simulation_statistics();

	TreeModel::Row riga_P = *(_model->append());

	char buff[100];
	
	sprintf(buff, "%.2f", stats->get_average_inactivity_time());
	riga_P[_col_inactivity] 	= Glib::ustring(buff);
	sprintf(buff, "%.1f", stats->get_average_execution_progress());
	riga_P[_col_progress] 		= Glib::ustring(buff) + Glib::ustring("%");
	sprintf(buff, "%.2f", stats->get_average_turn_around());
	riga_P[_col_turn] 			= Glib::ustring(buff);
	sprintf(buff, "%.2f", stats->get_average_response_time());
	riga_P[_col_response] 		= Glib::ustring(buff);
	sprintf(buff, "%.1f", stats->get_average_efficiency());	
	riga_P[_col_effic] 			= Glib::ustring(buff) + Glib::ustring("%");
	sprintf(buff, "%d / %d", stats->get_terminated_processes(), num_procs);	
	riga_P[_col_term_procs] 	= Glib::ustring(buff);
	sprintf(buff, "%d / %d", stats->get_terminated_threads(), num_threads);	
	riga_P[_col_term_threads] 	= Glib::ustring(buff);
	sprintf(buff, "%.3f", stats->get_average_processes_throughput());
	riga_P[_col_through_procs] 	= Glib::ustring(buff);
	sprintf(buff, "%.3f", stats->get_average_threads_throughput());
	riga_P[_col_through_threads]= Glib::ustring(buff);
	
	expand_all();
	/*
	const SimulationStatistics* sim = Statistics::get_instance().get_simulation_statistics();
	cout << "\n\n****** SIMULATION STATISTICS *******\n AVG_RESP= " 
			<< sim->get_average_response_time() << "  AVG_INACT= " << sim->get_average_inactivity_time() <<
			"  AVG_EXEC= " << sim->get_average_execution_progress() <<  
			"%  AVG_EFFIC= " << sim->get_average_efficiency() << 
			"%  AVG_TURN= " << sim->get_average_turn_around() << 
			"  TERM_PROCS= " << sim->get_terminated_processes() << 
			"  TERM_THRES= " << sim->get_terminated_threads() << 
			"  THRU_PROCS= " << sim->get_average_processes_throughput() << 
			"  THRU_THREA= " << sim->get_average_threads_throughput() << "\n\n";
	*/
}

