old_amp = stim.amp // to store the last value of stim.amp
proc stimChange() {
	if (!$1) { 
		printf("\nStimulation type changed to Current Pulse\n") 
		stim.amp = old_amp
	} else {
		old_amp = stim.amp	
		stim.amp = 0
		printf("\nStimulation type changed to Synaptic Input\n")
	}
}


proc loadqueue(){
	if(!bSynput) return
	UniformRand = new Random(seed)
	NormRand = new Random(seed)
	
	for i = 0, 250{
		Events(Dnf)
		Events(Upf)
		if(i>83) i+=1	
	}
}

proc Events() {local start, Event // See explanation for this proc torwards the end of this file
	start = UniformRand.uniform(0, 1000/$1)
	Event = start + NormRand.normal(0, 1e6/(16*$1*$1))
	for j=1, 3+int(StateNo*SI*$1/1000) { //3 is for generating some extra spikes as a safety margin 
		if(Event>=0) {
			if((abs((int(int(Event/SI)/2)==(int(Event/SI)/2))-($1==Upf)))){
				ns.o[i].event(Event)
				if(i>83){ns.o[i+1].event(Event)}
			}
		}
		Event = start + 1000 * j/$1 + NormRand.repick()
	}
}





/* EXPLANATION FOR THE Events proc follows:

//~ which can be rewritten as the following proc. This proc while same as the original proc will be easier to explain.
//~ The spike train that is input to each receptor has 7 parts - 3 up-state parts & 4 down-state parts. In the down-state
//~ parts, the frequency of the spike train should be 3Hz and in the up-state parts it should be 7.5 Hz. When Events(Dnf) is
//~ called for a given receptor, a spike train with spikes corresponding only to the 4 down-states is delivered to Netcon  (no spikes for the up-state is delivered).  __|_____|_____________|___|_______________|___|____________|____|__
//~ Similarly when Events(Upf) is called for the same receptor, another spike train with spikes
//~ corresponding to the up-state is delivered to the Netcon.                                                                                                                                             ____________|_|__|_|_____________|_|_|__|_____________|_|_|_|________
//~ Thus the actual spike train for a given receptor delivered to its Netcon will be the combination of the Events(Dnf) and Events(Upf) spike trains.                   __|_____|____|_|__|_|___|___|___ __|_|_|__|___|___|______|_|_|_|________

//~ The steps to achieve this is explained inline within the program code below


proc Events() {local start, Event
	Statef = $1 //Specifies whether the proc should generate and deliver to Netcon an up-state spike train or down-state spike train. 
	start = UniformRand.uniform(0, 1000/Statef) //To decide the first occurence of the spike in the spike train, define a variable 'start'. Draw the value of start from a uniform random distribution within the range 0 and inter-spike interval of Dn or Up state spike train
	Event = start + NormRand.normal(0, 1e6/(16*Statef*Statef)) //Generate the first spike of the spike train by adding a value to 'start' drawn from a normal dist (See Wolf et al for details)
	for j=1, 3+int(StateNo*SI*Statef/1000) { //Generate the reqd no. of spikes for the up or dn spike train. Add 3 extra spikes for a safety margin 
		if(Event>=0) { //If the generated spike (Event) is non-negative
			
			if(Statef==Upf) { //Determine if up or dn state spike train is to be generated.
				bUpf = 1
			} else {
				bUpf = 0
			}
						
			if((eAct==0)||(eAct==9)) { //For 'Run' & 'Range Run'
				
				StateID = int(Event/SI)/2 // A full spike train having up & dn states has 7 parts with each part having the duration of SI (e.g. 284 ms). If the generated Event falls within the 1st part, StateID will be assigned a value of 0, for the second part, 0.5, third part 1 and so on upto 3 for the 7th part.
				
				if(int(StateID)==StateID) { //If StateID is a whole no., the generated Event falls in the dn state, else it is in the up-state
					bIsDnState = 1
				} else {
					bIsDnState = 0
				}
				
				if(abs(bIsDnState-bUpf)){ // If Dn-state spike train is requested, eliminate generated Events that fall in the up-state and deliver the remaining to Netcon. Similarly if Up-state train is requested, eliminate generated Events that fall in dn-state and deliver remaining to Netcon.
					ns.o[i].event(Event)
					if(i>83){ns.o[i+1].event(Event)} 
				}
			} else { // for all other values of eAct
				if (abs((Event<stim.del)-bUpf)) {
					ns.o[i].event(Event)
					if(i>83){ns.o[i+1].event(Event)}
				}
			}		
		}
		Event = start + 1000 * j/Statef + NormRand.repick() //Generate the next Event