
package de.ugoe.cs.quest.eventcore.gui;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import de.ugoe.cs.quest.eventcore.Event;
import de.ugoe.cs.quest.eventcore.guimodel.AbstractDefaultGUIElement;
import de.ugoe.cs.quest.eventcore.guimodel.IGUIElement;
import de.ugoe.cs.quest.eventcore.guimodel.IGUIElementSpec;
import de.ugoe.cs.tasktree.keyboardmaps.VirtualKey;

/**
 * @author Patrick Harms
 */
public class InteractionEventListTest {

    /**
   * 
   */
    @Test
    public void testDifferentCombinationKeyCombinations() {
        List<Event> checkList = new ArrayList<Event>();
        InteractionEventList eventList = new InteractionEventList();

        IGUIElement guiElement = new AbstractDefaultGUIElement(null, null) {

            /**  */
            private static final long serialVersionUID = 1L;

            @Override
            public void updateSpecification(IGUIElementSpec furtherSpec) {
                // ignore
            }

            @Override
            public String getPlatform() {
                return "TEST";
            }

        };

        // check first of all a normal pressing and releasing of A and B
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_B), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_B), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_B), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_B), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // check what happens if A is pressed and not released before B is pressed
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_C), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_D), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_C), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_D), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_C), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_C), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_D), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_D), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // now SHIFT is pressed and released after all keys are pressed
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_E), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_E), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_F), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_F), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_E), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_E), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_F), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_F), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // now SHIFT is released before the last key is released
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_G), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_G), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_H), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_H), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_G), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_G), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_H), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_H), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // now SHIFT is released before all other keys are released
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_I), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_J), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_K), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_J), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_K), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_I), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_I), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_I), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_J), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_J), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_K), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_K), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // now SHIFT, CTRL and ALT are pressed and released after all keys are pressed
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.CONTROL), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.ALT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_L), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_L), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_M), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_M), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.ALT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.CONTROL), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.CONTROL), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.ALT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_L), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_L), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_M), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_M), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.ALT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.CONTROL), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // now SHIFT, CTRL and ALT are released before the last key is released
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.CONTROL), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.ALT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_N), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_N), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_O), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.ALT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.CONTROL), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_O), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.CONTROL), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.ALT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_N), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_N), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_O), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_O), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.ALT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.CONTROL), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // now SHIFT, CTRL and ALT are released in another order and before some other keys are
        // released
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.CONTROL), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.ALT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_P), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_Q), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_R), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_Q), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.ALT), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.CONTROL), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_R), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_P), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.CONTROL), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.ALT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_P), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_P), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_Q), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_Q), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_R), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_R), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.ALT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.CONTROL), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }
    }

    /**
   * 
   */
    @Test
    public void testSeveralSubsequentKeyPressedEvents() {
        List<Event> checkList = new ArrayList<Event>();
        InteractionEventList eventList = new InteractionEventList();

        IGUIElement guiElement = new AbstractDefaultGUIElement(null, null) {

            /**  */
            private static final long serialVersionUID = 1L;

            @Override
            public void updateSpecification(IGUIElementSpec furtherSpec) {
                // ignore
            }

            @Override
            public String getPlatform() {
                return "TEST";
            }

        };

        // check first of all a normal pressing and releasing of A and B
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }

        // check first of all a normal pressing and releasing of A and B
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        eventList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        eventList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.SHIFT), guiElement));
        checkList.add(new Event(new KeyPressed(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.LETTER_A), guiElement));
        checkList.add(new Event(new KeyReleased(VirtualKey.SHIFT), guiElement));

        assertEquals(checkList.size(), eventList.size());

        for (int i = 0; i < checkList.size(); i++) {
            assertEquals(checkList.get(i).getType(), eventList.get(i).getType());
        }
    }

}
