
#include "StdAfx.h"
#include "clientconsole.h"
#include "SingleSimulationResultDTO.h"
#include "StepResultDTO.h"
#include "SimulationParametersDTO.h"
#include "SimulationControllerFacade.h"
#include "AbstractSimulationResultDTO.h"
#include "ResultDTOIteratorFactory.h"
#include "ServiceInfoDTO.h"
#include "ActionFactory.h"
#include "DTOIterator.h"
#include <string>
#include<iostream>
using namespace std;

ClientConsole* ClientConsole::_instance =0;

ClientConsole::ClientConsole(void)
{
	queue_size_value_service1 = 0;
	average_time_value_service1 = 0;
	average_queue_size_value_service1 = 0;
	queue_size_value_service2 = 0;
	average_time_value_service2 = 0;
	average_queue_size_value_service2 = 0;
	queue_size_value_service3 = 0;
	average_time_value_service3 = 0;
	average_queue_size_value_service3 = 0;
	queue_size_value_service4 = 0;
	average_time_value_service4 = 0;
	average_queue_size_value_service4 = 0;
	queue_size_value_service5 = 0;
	average_time_value_service5 = 0;
	average_queue_size_value_service5 = 0;
	number_arrivals_value = 0;
	average_time_service_suits_flaw_value = 0;
	average_time_service_suits_value = 0;
	number_suits_flaw_value = 0;
	number_suits_value = 0;
	queue_size_coat_value = 0;
	queue_size_pants_value = 0;
	average_time_coat_value = 0;
	average_time_pants_value = 0;
	average_queue_size_coat_value = 0;
	average_queue_size_pants_value = 0;
}

void ClientConsole::paintUpdateStep() {

	cout << "Queue Size Service1 : " << queue_size_value_service1 << "\n";
	cout << "Average Time Service1 : " << average_time_value_service1 << "\n";
	cout << "Average Queue Size Service1 : " << average_queue_size_value_service1 << "\n";
	cout << "Queue Size Service2 : " << queue_size_value_service2 << "\n";
	cout << "Average Time Service2 : " << average_time_value_service2 << "\n";
	cout << "Average Queue Size Service2 : " << average_queue_size_value_service2 << "\n";
	cout << "Queue Size Service3 : " << queue_size_value_service3 << "\n";
	cout << "Average Time Service3 : " << average_time_value_service3 << "\n";
	cout << "Average Queue Size Service3 : " << average_queue_size_value_service3 << "\n";
	cout << "Queue Size Service4 : " << queue_size_value_service4 << "\n";
	cout << "Average Time Service4 : " << average_time_value_service4 << "\n";
	cout << "Average Queue Size Service4 : " << average_queue_size_value_service4 << "\n";
	cout << "Queue Size Service5 : " << queue_size_value_service5 << "\n";
	cout << "Average Time Service5 : " << average_time_value_service5 << "\n";
	cout << "Average Queue Size Service5 : " << average_queue_size_value_service5 << "\n";
	cout << "Number Of Arrivals_value : " << number_arrivals_value << "\n";
	cout << "Average Time Service Suits Flaws : " << average_time_service_suits_flaw_value << "\n";
	cout << "Average Time Service Suits : " << average_time_service_suits_value << "\n";
	cout << "Number Suits Flaws : " << number_suits_flaw_value << "\n";
	cout << "Number Suits : " << number_suits_value << "\n";
	cout << "Queue Size Coat : " << queue_size_coat_value << "\n";
	cout << "Queue Size Pants : " << queue_size_pants_value << "\n";
	cout << "Average Time Coats : " << average_time_coat_value << "\n";
	cout << "Average Time Pants : " << average_time_pants_value << "\n";
	cout << "Average Queue Size Coats : " << average_queue_size_coat_value << "\n";
	cout << "Average Queue Size Pants : " << average_queue_size_pants_value << "\n";
}

ClientConsole* ClientConsole::instance()
{
	if(!_instance)
	{
		_instance=new ClientConsole();
	}
	return _instance;
};

void ClientConsole::start()
{
	SimulationParametersDTO* simulationParametersDTO = new SimulationParametersDTO;

	char qtd_buffer [100];
	cout << "Insira o tempo medio de chegadas: \n";
	cin.getline (qtd_buffer,100);

	char num_sim_buffer [100];
	cout << "Numero de Simulacoes: \n";
	cin.getline (num_sim_buffer,100);

	char temp_sim_buffer [100];
	cout << "Tempo de cada Simulacao: \n";
	cin.getline (temp_sim_buffer,100);

	char continuous_buffer [100];
	cout << "Simulação Continua (Sim - 1 ; Nao - 0) : \n";
	cin.getline (continuous_buffer,100);

	int qtd = atoi(qtd_buffer);
	int num_sim = atoi(num_sim_buffer);
	int temp_sim = atoi(temp_sim_buffer);
	int continuous = atoi(continuous_buffer);

	isContinuous = false;

	if (continuous == 1)
		isContinuous = true;

	//cout << "\nSimulationDefinitionData: " << isContinuous << " " << qtd << " " << temp_sim << " " << num_sim << "\n";
	AbstractAction* startAction = ActionFactory::createStartSimulatorAction(isContinuous,qtd,temp_sim,num_sim);
	SimulationControllerFacade* simulationControllerFacade = getSimulationControllerFacade();
	simulationControllerFacade->executeAction(startAction);
}

void ClientConsole::updateStep(){

	if (!isContinuous){
		cout << "\nFoi executado um passo. Dados: \n";
		AbstractSimulationResultDTO* result = getSimulationResultDTO();
		StepResultDTO* stepResultDTO = dynamic_cast<StepResultDTO*>(result);
		DTOIterator* dtoIterator = ResultDTOIteratorFactory::createServicesIterator(stepResultDTO);
		while(dtoIterator->hasNextResult()){
			AbstractSimulationResultDTO* element = dtoIterator->nextResult();
			if (element->getID().compare(string("service1")) == 0){
				cout << "\nServico 1:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service2")) == 0){
				cout << "\nServico 2:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service3")) == 0){
				cout << "\nServic0 3:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service4Coats")) == 0){
				cout << "\nServico 4 - Casacos:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service4Pants")) == 0){
				cout << "\nServico 4 - Calcas:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service4Suits")) == 0){
				cout << "\nServico 4 - Fatos:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service5")) == 0){
				cout << "\nServico 5:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
		}
		cout << "Continuar ou sair? ((Numero de Passos) - Continuar, 0 - Sair) \n";
		char step_buffer [100];
		cin.getline(step_buffer,100);
		int num_step = atoi(step_buffer);

		if (num_step == 0){
			exit(0);
		} else {
			AbstractAction* stepAction = ActionFactory::createStepSimulatorAction(num_step);
			SimulationControllerFacade* simulationControllerFacade = getSimulationControllerFacade();
			simulationControllerFacade->executeAction(stepAction);
		}
	}
}

void ClientConsole::updateMultipleSimulations(){
	AbstractSimulationResult* result = getSimulationResultDTO();
	MultipleSimulationResultDTO* multipleSimulationResultDTO = dynamic_cast<MultipleSimulationResultDTO*>(result);
	DTOIterator* iterator = ResultDTOIteratorFactory::createSingleSimulationIterator(multipleSimulationResultDTO);

}

void ClientConsole::updateSimulation(){
	AbstractSimulationResultDTO* result = getSimulationResultDTO();
	SingleSimulationResultDTO* simulationResultDTO = dynamic_cast<SingleSimulationResultDTO*>(result);
	DTOIterator* iterator = ResultDTOIteratorFactory::createGeneralIterator(simulationResultDTO);
	bool print = false;
	while(iterator->hasNextResult()){
		AbstractSimulationResultDTO* element = iterator->nextResult();
		if (element->getID().compare(string("0"))){
			print = false;
		}
		if (print){
			if (element->getID().compare(string("service1")) == 0){
				cout << "\nServico 1:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service2")) == 0){
				cout << "\nServico 2:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service3")) == 0){
				cout << "\nServic0 3:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service4Coats")) == 0){
				cout << "\nServico 4 - Casacos:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service4Pants")) == 0){
				cout << "\nServico 4 - Calcas:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service4Suits")) == 0){
				cout << "\nServico 4 - Fatos:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
			if (element->getID().compare(string("service5")) == 0){
				cout << "\nServico 5:\n";
				ServiceInfoDTO* service = dynamic_cast<ServiceInfoDTO*>(element);
				cout << "Tamanho Actual da fila: "  << service->getServiceActualQueueSize() << "\n";
				cout << "Tamanho Medio da fila: "  << service->getServiceAvgQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: "  << service->getServiceUseRate() << "\n";
				cout << "Tamanho Maximo da fila: "  << service->getMaximumQueueSize() << "\n";
				cout << "Taxa de Utilizacao do Servico: : "  << service->getServiceUseRate() << "\n";
			}
		}
	}
}
