/***************************************************************************
 *                           TimeDrivenInternalSpike.h                     *
 *                           -------------------                           *
 * copyright            : (C) 2014 by Francisco Naveros                    *
 * email                : fnaveros@ugr.es                                  *
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TIMEDRIVENINTERNALSPIKE_H_
#define TIMEDRIVENINTERNALSPIKE_H_

/*!
 * \file TimeDrvienInternalSpike.h
 *
 * \author Francisco Naveros
 * \date May 2014
 *
 * This file declares a class which can implement a groupe of internal spike in only one event. This event is associate with all
 * time driven neuron model in CPU and GPU.
 */
 
#include <iostream>

#include "./InternalSpike.h"

using namespace std;

class Neuron;
class Simulation;
class VectorNeuronState;
class PropagatedSpikeGroupe;
class NeuronModelPropagationDelayStructure;


/*!
 * \class TimeDrivenInternalSpike
 *
 * \brief Neural network internal spike for a set of time driven neurons.
 *
 * This class abstract the concept of spike. An internal spike is an event generated by the own cell
 * without external excitation.
 *
 * \author Francisco Naveros
 * \date May 2014
 */
class TimeDrivenInternalSpike: public InternalSpike{
	private:

		/*!
		* \brief Vector neuron state associated to the time driven neuron mode.
		*/
		VectorNeuronState * State;

		/*!
		* \brief Propagation delay structure used to create the PropagatedSpikeGroupe events.
		*/
		NeuronModelPropagationDelayStructure * PropagationStructure;

		/*!
		* \brief Neuron vector.
		*/
		Neuron** Neurons;

		/*!
		* \brief One PropagatedSpikeGropue for each target OpenMP queue and propagation delay.
		*/
		PropagatedSpikeGroupe *** propagatedSpikeGroupe;

		/*!
		* \brief Source OpenMP queue.
		*/
		const int OpenMP_index;

		/*!
   		 * \brief It process the internal spike associated to the "index" neuron.
   		 * 
   		 * It process the internal spike associated to the "index" neuron.
   		 * 
   		 * \param CurrentSimulation The simulation object where the event is working.
		 * \param index inside the vector of neurons.
   		 */
		void ProcessInternalSpikeEvent(Simulation * CurrentSimulation, int index);


	public:
   		
   	
   		/*!
   		 * \brief Constructor with parameters.
   		 * 
   		 * It creates and initializes a new spike with the parameters.
   		 * 
   		 * \param NewTime Time of the new spike.
   		 * \param NewState Vector neuron state for the time driven neuron model.
		 * \param Vector of neuron associated to the time driven neuron model.
   		 */
   		TimeDrivenInternalSpike(double NewTime, VectorNeuronState * NewState, NeuronModelPropagationDelayStructure * NewPropagationStrucuture, Neuron ** NewNeurons, int NewOpenMP_index);
   		
   		/*!
   		 * \brief Class destructor.
   		 * 
   		 * It destroies an object of this class.
   		 */
   		virtual ~TimeDrivenInternalSpike();
   	

   		/*!
   		 * \brief It process an event in the simulation with the option of real time available.
   		 * 
   		 * It process an event in the simulation with the option of real time available.
   		 * 
   		 * \param CurrentSimulation The simulation object where the event is working.
		 * \param RealTimeRestriction watchdog variable executed in a parallel OpenMP thread that
		 * control the consumed time in each slot.
   		 */
   		virtual void ProcessEvent(Simulation * CurrentSimulation,  int RealTimeRestriction);

		/*!
   		 * \brief It process an event in the simulation without the option of real time available.
   		 * 
   		 * It process an event in the simulation without the option of real time available.
   		 * 
   		 * \param CurrentSimulation The simulation object where the event is working.
   		 */
		virtual void ProcessEvent(Simulation * CurrentSimulation);
   		 
    	/*!
   		 * \brief this method print the event type.
   		 * 
   		 * This method print the event type..
		 */  		
		virtual void PrintType();


		/*!
   		 * \brief The event queue uses this preference variable to sort the events with the same time stamp.
   		 * 
   		 * The event queue uses this preference variable to sort the events with the same time stamp.
		 */
		virtual enum EventPriority ProcessingPriority();
};

#endif /*TIMEDRIVENINTERNALSPIKE_H_*/
