package scriptbuilder.structures;

import java.util.ArrayList;
import junit.framework.TestCase;
import static org.mockito.Matchers.*;
import scriptbuilder.structures.events.*;
import static org.mockito.Mockito.*;
import scriptbuilder.structures.ScriptIncident.IncidentFocusedEvent;
import scriptbuilder.structures.ScriptIncident.SliceChangedEvent;

/**
 *
 * @author Bryan McGuffin
 */
public class ScriptIncidentTest extends TestCase
{

    SimulationScript mockedScript;

    public ScriptIncidentTest(String testName)
    {
        super(testName);
    }

    /**
     * Test of setCollapsed method, of class ScriptIncident.
     */
    public void testSetCollapsed()
    {
        System.out.println("setCollapsed");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        assertFalse(instance.collapsed);
        verify(mockedScript, times(0)).update();
        instance.setCollapsed(false);
        assertFalse(instance.collapsed);
        verify(mockedScript, times(1)).update();
        instance.setCollapsed(true);
        assertTrue(instance.collapsed);

        verify(mockedScript, times(2)).update();
    }

    /**
     * Test of setOffset method, of class ScriptIncident.
     */
    public void testSetOffset()
    {
        System.out.println("setOffset");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        int offset = 10;
        assertEquals(0, instance.offset);
        verify(mockedScript, times(0)).update();
        instance.setOffset(offset);
        assertEquals(10, instance.offset);
        verify(mockedScript, times(1)).update();
        instance.setOffset(0);
        assertEquals(0, instance.offset);
        verify(mockedScript, times(2)).update();
    }

    /**
     * Test of addNewEvent method, of class ScriptIncident.
     */
    public void testAddNewEvent()
    {
        System.out.println("addNewEvent");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        assertEquals(0, instance.length);
        assertEquals(0, instance.eventCount);
        I_ScriptEvent ev1 = mock(I_ScriptEvent.class);
        when(ev1.getLength()).thenReturn(1);
        I_ScriptEvent ev2 = mock(I_ScriptEvent.class);
        when(ev2.getLength()).thenReturn(4);
        I_ScriptEvent ev3 = mock(I_ScriptEvent.class);
        when(ev3.getLength()).thenReturn(4);
        int start = 0;
        instance.addNewEvent(ev1, start);
        assertEquals(1, instance.length);
        assertEquals(1, instance.eventCount);

        start = 0;
        instance.addNewEvent(ev2, start);
        assertEquals(4, instance.length);
        assertEquals(2, instance.eventCount);

        start = 2;
        instance.addNewEvent(ev3, start);
        assertEquals(6, instance.length);
        assertEquals(3, instance.eventCount);

    }

    /**
     * Test of getSlices method, of class ScriptIncident.
     */
    public void testGetSlices()
    {
        System.out.println("getSlices");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        //Empty list; no events in incident
        ArrayList<TimeSlice> result = instance.getSlices();
        assertEquals(0, result.size());

        I_ScriptEvent ev1 = mock(I_ScriptEvent.class);
        when(ev1.getLength()).thenReturn(1);

        //One event, one timeslice
        instance.addNewEvent(ev1, 0);
        result = instance.getSlices();
        assertEquals(1, result.size());

        //Two simultaneous events start in the same timeslice
        instance.addNewEvent(ev1, 0);
        result = instance.getSlices();
        assertEquals(1, result.size());

        //A third event starts at a different time so it requires a new timeslice
        instance.addNewEvent(ev1, ev1.getLength() + 100);
        result = instance.getSlices();
        assertEquals(2, result.size());

    }

    /**
     * Test of setSliceActive method, of class ScriptIncident.
     */
    public void testSetSliceActive()
    {
        boolean passFlag = false;
        System.out.println("setSliceActive");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        int time_a = 0;
        int time_b = 5;
        instance.setSliceActive(time_a);
        verify(mockedScript, never()).broadcastEvent(isA(SliceChangedEvent.class));
        instance.setSliceActive(time_b);
        verify(mockedScript, never()).broadcastEvent(isA(SliceChangedEvent.class));
        instance.addNewEvent(mock(I_ScriptEvent.class), time_a);
        instance.setSliceActive(time_a);
        verify(mockedScript, times(1)).broadcastEvent(isA(SliceChangedEvent.class));
        instance.setSliceActive(time_b);
        verify(mockedScript, times(1)).broadcastEvent(isA(SliceChangedEvent.class));
    }

    /**
     * Test of setIncidentActive method, of class ScriptIncident.
     */
    public void testSetIncidentActive()
    {
        System.out.println("setIncidentActive");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        verify(mockedScript, never()).broadcastEvent(isA(IncidentFocusedEvent.class));
        instance.setIncidentActive();
        verify(mockedScript, times(1)).broadcastEvent(isA(IncidentFocusedEvent.class));
        
    }

    /**
     * Test of toString method, of class ScriptIncident.
     */
    public void testToString()
    {
        System.out.println("toString");
        mockedScript = mock(SimulationScript.class);
        ScriptIncident instance = new ScriptIncident(101, "Test_Incident", "Description", mockedScript);
        String expResult = "101 - Test_Incident";
        String result = instance.toString();
        assertEquals(expResult, result);

    }

}
