static char *SccsId = "@(#)eventl.c 4.1 (TU-Delft) 05/24/90";
/**********************************************************

Name/Version      : sls/4.1

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : A.C. de Graaf, A.J. van Genderen
Creation date     : 10-Jul-1986
Modified by       : S. de Graaf
Modification date : 10-Jul-1986


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1986 , All rights reserved
**********************************************************/
#include "extern.h"

typedef struct eventl_el {
    NODE * node;
    int tswitch;
    struct eventl_el   *prev;
    struct eventl_el   *next;
} EVENTL_EL;

/* there are three separate event lists.     */
/* one for the Forced state transistions     */
/* one for the Normal state transistions and */
/* one for the Plot state transistions       */

EVENTL_EL * free_fevlarr;
EVENTL_EL * end_fevlarr;
EVENTL_EL * fevlbegin;
EVENTL_EL * fevlend;
EVENTL_EL * free_nevlarr;
EVENTL_EL * end_nevlarr;
EVENTL_EL * nevlbegin;
EVENTL_EL * nevlend;
EVENTL_EL * free_pevlarr;
EVENTL_EL * end_pevlarr;
EVENTL_EL * pevlbegin;
EVENTL_EL * pevlend;
EVENTL_EL * flastread;
EVENTL_EL * nlastread;
EVENTL_EL * plastread;

initeventl () {
    PALLOC (free_nevlarr, essnodes_cnt + 2, EVENTL_EL);
    end_nevlarr = free_nevlarr + essnodes_cnt + 1;
    nevlbegin = free_nevlarr;
    nevlbegin -> tswitch = -1;
    nevlend = free_nevlarr + 1;
    nevlend -> node = NULL;
    nevlbegin -> next = nevlend;
    nevlend -> prev = nevlbegin;
    free_nevlarr = free_nevlarr + 2;

    PALLOC (free_fevlarr, inpnodes_cnt + funcoutpnodes_cnt + 2, EVENTL_EL);
    end_fevlarr = free_fevlarr + inpnodes_cnt + funcoutpnodes_cnt + 1;
    fevlbegin = free_fevlarr;
    fevlbegin -> tswitch = -1;
    fevlend = free_fevlarr + 1;
    fevlend -> node = NULL;
    fevlbegin -> next = fevlend;
    fevlend -> prev = fevlbegin;
    free_fevlarr = free_fevlarr + 2;

    PALLOC (free_pevlarr, plotnodes_cnt + 2, EVENTL_EL);
    end_pevlarr = free_pevlarr + plotnodes_cnt + 1;
    pevlbegin = free_pevlarr;
    pevlbegin -> tswitch = -1;
    pevlend = free_pevlarr + 1;
    pevlend -> node = NULL;
    pevlbegin -> next = pevlend;
    pevlend -> prev = pevlbegin;
    free_pevlarr = free_pevlarr + 2;
}

reset_read_event () {
    flastread = fevlbegin;
    nlastread = nevlbegin;
    plastread = pevlbegin;
}

int time_read_event () {
    int t;
    int t_read_nevent ();
    int t_read_fevent ();
    int t_read_pevent ();
    int t_nev = t_read_nevent ();
    int t_fev = t_read_fevent ();
    int t_pev = t_read_pevent ();

    if (t_nev < 0)
        t = t_fev;
    else if (t_fev < 0)
        t = t_nev;
    else if (t_nev < t_fev)
	t = t_nev;
    else
	t = t_fev;

    if (t_pev < 0)
        t = t;
    else if (t < 0)
        t = t_pev;
    else if (t < t_pev)
	t = t;
    else
	t = t_pev;

    return (t);
}

NODE * read_event () {
    int t;
    int t_read_nevent ();
    int t_read_fevent ();
    int t_read_pevent ();
    int t_nev = t_read_nevent ();
    int t_fev = t_read_fevent ();
    int t_pev = t_read_pevent ();
    NODE * n;

    if (t_nev < 0)
        t = t_fev;
    else if (t_fev < 0)
        t = t_nev;
    else if (t_nev < t_fev)
	t = t_nev;
    else
	t = t_fev;

    if (t_pev < 0)
        t = t;
    else if (t < 0)
        t = t_pev;
    else if (t < t_pev)
	t = t;
    else
	t = t_pev;

    if (t == t_nev) {
	nlastread = nlastread -> next;
        n = nlastread -> node;
    }
    else if (t == t_fev) {
	flastread = flastread -> next;
        n = flastread -> node;
    }
    else {
	plastread = plastread -> next;
        n = plastread -> node;
    }

    return (n);
}

int t_read_nevent () {
    if (nlastread -> next == nevlend)
        return (-1);
    else
	return (nlastread -> next -> tswitch);
}

int t_read_fevent () {
    if (flastread -> next == fevlend)
        return (-1);
    else
	return (flastread -> next -> tswitch);
}

int t_read_pevent () {
    if (plastread -> next == pevlend)
        return (-1);
    else
	return (plastread -> next -> tswitch);
}

int time_next_event () {
    int t;
    int t_next_nevent ();
    int t_next_fevent ();
    int t_next_pevent ();
    int t_nev = t_next_nevent ();
    int t_fev = t_next_fevent ();
    int t_pev = t_next_pevent ();

    if (t_nev < 0)
        t = t_fev;
    else if (t_fev < 0)
        t = t_nev;
    else if (t_nev < t_fev)
	t = t_nev;
    else
	t = t_fev;

    if (t_pev < 0)
        t = t;
    else if (t < 0)
        t = t_pev;
    else if (t < t_pev)
	t = t;
    else
	t = t_pev;

    return (t);
}

NODE * next_event () {
    int t;
    int t_next_nevent ();
    int t_next_fevent ();
    int t_next_pevent ();
    int t_nev = t_next_nevent ();
    int t_fev = t_next_fevent ();
    int t_pev = t_next_pevent ();
    NODE * n;

    if (t_nev < 0)
        t = t_fev;
    else if (t_fev < 0)
        t = t_nev;
    else if (t_nev < t_fev)
	t = t_nev;
    else
	t = t_fev;

    if (t_pev < 0)
        t = t;
    else if (t < 0)
        t = t_pev;
    else if (t < t_pev)
	t = t;
    else
	t = t_pev;

    if (t == t_nev) {
        n = nevlbegin -> next -> node;
        del_event (n, Normal);
    }
    else if (t == t_fev) {
        n = fevlbegin -> next -> node;
        del_event (n, Forced);
    }
    else {
        n = pevlbegin -> next -> node;
        del_event (n, Plot);
    }

    return (n);
}

int t_next_nevent () {
    if (nevlbegin -> next == nevlend)
        return (-1);
    else
	return (nevlbegin -> next -> tswitch);
}

int t_next_fevent () {
    if (fevlbegin -> next == fevlend)
        return (-1);
    else
	return (fevlbegin -> next -> tswitch);
}

int t_next_pevent () {
    if (pevlbegin -> next == pevlend)
        return (-1);
    else
	return (pevlbegin -> next -> tswitch);
}

sched_event (n, eventtype, tswitch)
NODE * n;
int eventtype;
int tswitch;
{
    ins_event (n, eventtype, tswitch);
    if (debugsim) {
	fprintf (debug, "SCHEDULE: %s for t=%d ", hiername (n - N), tswitch);
	switch (eventtype) {
	    case Forced :
		fprintf (debug, "Forced ");
		if ( n->inp ) 
		    fprintf (debug, "forcedinfo -> nextfstate : %d\n",
		    n -> forcedinfo -> nextfstate);
		else if ( n->funcoutp) 
		    fprintf (debug, "combination of forcedinfo's \n");
		break;
	    case Normal :
		fprintf (debug, "Normal ");
	        fprintf (debug, "nextstate : %d\n", n -> nextstate);
		break;
	    case Plot :
		fprintf (debug, "Plot\n");
		break;
	}
    }
}

resched_event (n, eventtype, tswitch)
NODE * n;
int eventtype;
int tswitch;
{
    del_event (n, eventtype);
    ins_event (n, eventtype, tswitch);
    if (debugsim) {
	fprintf (debug, "RESCHEDULE: %s for t=%d ", hiername (n - N), tswitch);
	switch (eventtype) {
	    case Forced :
		fprintf (debug, "Forced ");
		if ( n->inp ) 
		    fprintf (debug, "forcedinfo -> nextfstate : %d\n",
		    n -> forcedinfo -> nextfstate);
		else if ( n->funcoutp) 
		    fprintf (debug, "combination of forcedinfo's \n");
		break;
	    case Normal :
		fprintf (debug, "Normal ");
	        fprintf (debug, "nextstate : %d\n", n -> nextstate);
		break;
	    case Plot :
		fprintf (debug, "Plot\n");
		break;
	}
    }
}

retr_event (n, eventtype)
NODE * n;
int eventtype;
{
    del_event (n, eventtype);
    if (debugsim) {
	fprintf (debug, "RETRIEVE: %s \n", hiername (n - N) );
    }
}

ins_event (n, eventtype, tswitch)
NODE * n;
int eventtype;
int tswitch;
{
    EVENTL_EL * search;
    EVENTL_EL * free_evlarr;

    switch (eventtype) {
	case Forced :
            if (free_fevlarr == end_fevlarr + 1) {
	        ERROR_EXIT (1);  /* event list overflow */
            }
            search = fevlend -> prev;
	    free_evlarr = free_fevlarr++;
	    break;
	case Normal :
            if (free_nevlarr == end_nevlarr + 1) {
	        ERROR_EXIT (1);  /* event list overflow */
            }
            search = nevlend -> prev;
	    free_evlarr = free_nevlarr++;
	    break;
	case Plot :
            if (free_pevlarr == end_pevlarr + 1) {
	        ERROR_EXIT (1);  /* event list overflow */
            }
            search = pevlend -> prev;
	    free_evlarr = free_pevlarr++;
	    break;
    }

    while (search -> tswitch > tswitch)
	search = search -> prev;
    free_evlarr -> node = n;
    free_evlarr -> tswitch = tswitch;
    free_evlarr -> next = search -> next;
    free_evlarr -> prev = search;
    free_evlarr -> next -> prev = free_evlarr;
    free_evlarr -> prev -> next = free_evlarr;
}

del_event (n, eventtype)
NODE * n;
int eventtype;
{
    EVENTL_EL * search;
    EVENTL_EL * free_evlarr;
    EVENTL_EL * evlend;

    switch (eventtype) {
	case Forced :
            search = fevlbegin -> next;
	    evlend = fevlend;
	    break;
	case Normal :
            search = nevlbegin -> next;
	    evlend = nevlend;
	    break;
	case Plot :
            search = pevlbegin -> next;
	    evlend = pevlend;
	    break;
    }

    while (search -> node != n && search != evlend)
	search = search -> next;

    if (search == evlend) {
	return;
    }
    search -> prev -> next = search -> next;
    search -> next -> prev = search -> prev;

    switch (eventtype) {
	case Forced :
	    free_evlarr = --free_fevlarr;
	    break;
	case Normal :
	    free_evlarr = --free_nevlarr;
	    break;
	case Plot :
	    free_evlarr = --free_pevlarr;
	    break;
    }
    if (search != free_evlarr) {
	search -> node = free_evlarr -> node;
	search -> tswitch = free_evlarr -> tswitch;
	search -> prev = free_evlarr -> prev;
	search -> next = free_evlarr -> next;
	search -> prev -> next = search;
	search -> next -> prev = search;
    }
}
