#include "si_ext.h"

int	DEBUG_SpikeInterval = 0;

#define VOLTAGE 0
#define THRESHOLD 1



/* 8/91 Steve Nowlan */
void SpikeInterval (buffer,action)
register struct si_type *buffer;
Action		*action;
{
double  voltage;
float temp;
MsgIn	*msg;
int	stat;
char    *nptr;
static char default_fname[NAME_LEN],*old_fname;

    if(buffer->interval_fname == NULL) {
      nptr = default_fname;
      nptr = strcpy(nptr,buffer->name);
      nptr = strcat(nptr,".spikeinterval");
      buffer->interval_fname = nptr;
      old_fname = nptr;
    }

    

    if(Debug(DEBUG_SpikeInterval) > 1){
	ActionHeader("SpikeInterval",buffer,action);
    }
    SELECT_ACTION(action){
    case RESET:
        ClearBuffer(buffer);
	buffer->interval = 0.0;
	buffer->prev_time = 0.0;
	buffer->file_io = 0;
	if (buffer->interval_file != NULL) {
	  fclose(buffer->interval_file);
	  buffer->interval_file = NULL;
	}
	break;
    case PROCESS:
	if ((buffer->interval_file == NULL) && (buffer->file_io == 1) &&
	    (buffer->interval_fname != NULL)){
	  if((buffer->interval_file = fopen(buffer->interval_fname,"a")) == 0)
	    ErrorMessage("SpikeInterval","Couldn't open output file.",buffer);
	}
	else if ((buffer->interval_fname != old_fname) && 
		 (buffer->file_io == 1)) {
	  fclose(buffer->interval_file);
	  if((buffer->interval_file = fopen(buffer->interval_fname,"a")) == 0)
	    ErrorMessage("SpikeInterval","Couldn't open output file.",buffer);
	}
	voltage = - buffer->thresh;
	MSGLOOP(buffer,msg){
	case VOLTAGE:		/* potential */
	    voltage = (double)MSGVALUE(msg,0);
	    break;
	case THRESHOLD:		/* threshold */
	    buffer->thresh = MSGVALUE(msg,0);
	    break;
	}
	/*
	** evaluate the criteria for spiking.
	** has it exceeded threshold?
	** is it past its refractory state?
	*/
#ifdef FLOATTIME
	if((voltage >= buffer->thresh) &&
	  (!ValidEvent(buffer) ||   /* this is a test to see if there is an event in the buffer*/
	(buffer->prev_time <= 
	(SimulationTime() - buffer->abs_refract)+ClockValue(0)/2.0))) {
#else
	if(( voltage >= buffer->thresh) &&
	( !ValidEvent(buffer) ||    /* this is a test to see if there is an event */
	(buffer->prev_time <=
	(SimulationTime() - buffer->abs_refract)))) {
#endif
	    /*
	    ** compute interspike interval, and stuff in buffer and write to file
	    */
	    buffer->interval = SimulationTime() - buffer->prev_time;
	    buffer->prev_time = SimulationTime();
	    if(!ValidEvent(buffer)) { /* PutEvent only allows one event
					 to be put in buffer!! */
	      PutEvent(buffer,(double)buffer->prev_time,WRAP);
	    }
	    if (buffer->file_io == 1) {
	      fprintf(buffer->interval_file,"interval %f time %f\n",
		      buffer->interval,buffer->prev_time);
	    }

	  }
	break;
    case CHECK:
	stat = 0;
	MSGLOOP(buffer,msg){
	    case VOLTAGE:
		stat = 1;
		break;
	}
	if(!stat){
	    ErrorMessage("SpikeInterval","Voltage input is required.",buffer);
	}
	break;
    default:
	InvalidAction("SpikeInterval",buffer,action);
	break;
    }
}


