#include "traffic_agent.cpp"
const string testMessage = "test_message";

class TrafficAgentCycleTime : public BaseTrafficAgent {
private:
	static double measurement_cycle_time; // s
	static double saturated_stream; // car/s
	static double Tc;
	int cycle_counter;
	Array <int> lane_sum;

	void sum_lanes() {
		for ( int i = 0; i < lane_sum.length(); i ++ ) {
			if ( inputs(2*i) > 0 ) {
				lane_sum(i) = lane_sum(i) + inputs(2*i);
			}
		}
	}

	void echo ( string message ) {
		cout << name << " hlasi: " << message << endl;		
	}

	void send2neighbour( Setting &set, int i, string messageName, double messageValue ) {		
		if ( i < neighbours.length() ) {
			Setting &msg =set.add(Setting::TypeGroup);
			UI::save( neighbours(i), msg, "to" );
			UI::save (name,msg,"from");
			UI::save( messageName, msg, "what" );
			UI::save( messageValue, msg, "value" );
		}
		else {
			//throw new Exception("soused "+((string)i)+" neexistuje");
			//cout << endl << endl << "soused " << i << mimo
			std::stringstream out;
			out << "soused " << i << " neexistuje";
			//throw out.str();
			cout << out.str();
		}
	}

	void printVector ( RV rv_vector, vec vector, string description ) {
		cout << endl << description << " " << name << endl;
		int k = 0;
		for ( int i = 0; i < rv_vector.length(); i ++ ) {
			cout << rv_vector.name(i) << " : ";
			for ( int j = 0; j < rv_vector.size(i); j ++ ) {				
				cout << vector(k) << " ";
				k ++;
			}
			cout << endl;
		}
		cout << endl;
	}

	

public:
	void from_setting( Setting &set ) {
		BaseTrafficAgent::from_setting(set);
		TrafficAgentCycleTime::measurement_cycle_time = 90; //s
		TrafficAgentCycleTime::saturated_stream = 0.5;
		TrafficAgentCycleTime::Tc = 80;
	}

	void broadcast(Setting &set){
		//BaseTrafficAgent::broadcast(set);
		try {
			for ( int i = 0; i < neighbours.length(); i ++ ) {
				send2neighbour( set, i, testMessage, 2.3 );				
			}
		} catch ( string s ) {
			cout << s << endl;
		}		
	}

	void receive(const Setting& msg){
		string what;
		string from;
		string to;
		double val;
		try {
			UI::get(what, msg, "what", UI::compulsory);
			UI::get(from, msg, "from", UI::compulsory);
			UI::get(to, msg, "to", UI::compulsory);
			UI::get(val, msg, "value");
			if ( what == testMessage ) {
				//cout << endl << name << ": OD: " << from << " CO: " << what << " KOLIK: " << val <<endl;
			}
			if ( what == "new_stable_state" ) {
				//echo("new_stable_state");
				BaseTrafficAgent::receive(msg);		
			}

			
		} catch ( UISettingException e ) {
			echo(e.what());
		}
	}

	void validate (){
		BaseTrafficAgent::validate();
		lane_sum.set_size( rv_inputs.length() );
		for ( int i = 0; i < lane_sum.length(); i ++ ) {
			lane_sum(i) = 0;
			cout << endl << endl << "lane_sum initialization " << name << " " << lane_sum(i) <<endl << endl ;
		}
		echo("validate");
	}

	void adapt (const vec &glob_dt) {
		sum_lanes();
		//printVector( rv_queues, queues, "queues" );
		printVector( rv_inputs, inputs, "inputs" );
		for ( int i = 0; i < lane_sum.length(); i ++ ) {
			cout << lane_sum(i) << endl;
		}
		cout << endl << endl;
		//printVector( green_names, green_times, "inputs" );
		//cout << endl << name << "green times: " << endl;
		for ( int i = 0; i < green_times.length(); i ++ ) {
			//cout << green_names(i) << " " << green_starts(i) << " " << green_times(i) << endl;
		}

		
/*
		for ( int i = 0; i < outputs.length(); i ++ ) {
			cout << name << " outputs " << outputs(i) << endl;
		}

		for ( int i = 0; i < rv_outputs.length(); i ++ ) {
			cout << name << " rv_outputs " << rv_outputs.name(i) << endl;
		}

	*/	

		BaseTrafficAgent::adapt(glob_dt);
		//echo("adapted");
	}

	void act (vec &glob_ut){
		
	}
	

};
UIREGISTER(TrafficAgentCycleTime);