'''
Created on Jan 5, 2011
@author:  = Dilum Bandara
@version:  = 0.1
@copyright:  = Copyright(c) 2011, Dilum Bandara
@contact:  = dilumb@engr.colostate.edu
@license:  = GPL
'''

class DES:
    '''
    Discrete event simulation engine
    '''
    def __init__(self):
        self._event_list = []
        self.now = 0.0


    def __del__(self):
        self._event_list = []


    def add_event(self, start_time, event_type, nid, data, sort):
        '''
        Add an event to waiting event list
        @param start_time: Event start time
        @param event_type: Type of event
        @param nid: Node responsible for event
        @param data: Data associated with event
        @param sort: Are events need to be sorted
        '''
        new_event = [start_time, event_type, nid, data]
        if sort == True: #Sort according to time
            for i in range(0, len(self._event_list)):  #Search for proper position
                if self._event_list[i][0] > start_time:
                    self._event_list.insert(i, new_event)
                    return
            #Fist or last item
            self._event_list.append(new_event)
        else: #If input is already sorted
            self._event_list.append(new_event)
            return


    def remove_event(self, start_time, event_type, nid):
        '''
        Remove given event from event list 
        @param start_time: Event start time
        @param event_type: Event type
        @param nid: Node responsible for event
        '''
        if len(self._event_list) == 0:
            print 'Error: Event list already empty.'
            return
        else :
            for i in range(0, len(self._event_list)):  #Search for proper position
                if self._event_list[i][0] == start_time and self._event_list[i][1] == \
                   event_type and self._event_list[i][2] == nid:
                    del self._event_list[i]
                    return
            print 'Error: No such event in event list'
            return

    def get_next_event(self):
        '''
        Get next event from list
        @return: Next event in cronological order. Has format 
        [start_time, event_type, nid, data]
        '''        
        if len(self._event_list) > 0:
            self.now = self._event_list[0][0]
            return self._event_list.pop(0)
        else :
            return self._event_list
