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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

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.IEventType;
import de.ugoe.cs.quest.eventcore.gui.MouseButtonDown;
import de.ugoe.cs.quest.eventcore.gui.MouseButtonInteraction;
import de.ugoe.cs.quest.eventcore.gui.MouseButtonUp;
import de.ugoe.cs.quest.eventcore.gui.MouseClick;
import de.ugoe.cs.quest.eventcore.guimodel.IGUIElement;
import de.ugoe.cs.quest.test.DummyGUIElement;
import de.ugoe.cs.quest.test.DummyInteraction;

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

    /** */
    private List<Event> events = new ArrayList<Event>();

    /**
     *
     */
    @Test
    public void testMouseClickInOneSequenceElement() {
        MouseButtonInteraction.Button leftBtn = MouseButtonInteraction.Button.LEFT;
        MouseButtonInteraction.Button middleBtn = MouseButtonInteraction.Button.MIDDLE;
        MouseButtonInteraction.Button rightBtn = MouseButtonInteraction.Button.RIGHT;

        IGUIElement element1 = new DummyGUIElement("elem1");
        IGUIElement element2 = new DummyGUIElement("elem2");

        simulateEvent(new MouseButtonDown(leftBtn), element1);
        simulateEvent(new MouseButtonUp(leftBtn), element1);
        simulateEvent(new MouseClick(leftBtn), element1);
        assertCondensedMouseClicks("elem1");

        simulateEvent(new DummyInteraction("bla", 1), element1);
        simulateEvent(new DummyInteraction("bli", 1), element1);
        simulateEvent(new MouseButtonDown(middleBtn), element1);
        simulateEvent(new MouseButtonUp(middleBtn), element1);
        simulateEvent(new MouseClick(middleBtn), element1);
        simulateEvent(new DummyInteraction("blo", 1), element1);
        simulateEvent(new DummyInteraction("blu", 1), element1);
        assertCondensedMouseClicks("elem1", "", "", "elem1", "", "");

        simulateEvent(new DummyInteraction("bla", 1), element2);
        simulateEvent(new DummyInteraction("bli", 1), element2);
        simulateEvent(new MouseButtonDown(rightBtn), element2);
        simulateEvent(new MouseButtonUp(rightBtn), element2);
        simulateEvent(new MouseClick(rightBtn), element2);
        simulateEvent(new DummyInteraction("blo", 1), element2);
        simulateEvent(new DummyInteraction("blu", 1), element2);
        assertCondensedMouseClicks("elem1", "", "", "elem1", "", "", "", "", "elem2", "", "");

        simulateEvent(new MouseButtonDown(leftBtn), element1);
        simulateEvent(new MouseButtonUp(leftBtn), element1);
        simulateEvent(new MouseClick(leftBtn), element2);
        assertCondensedMouseClicks("elem1", "", "", "elem1", "", "", "", "", "elem2", "", "",
                                   "", "", "elem2");

        simulateEvent(new MouseButtonDown(middleBtn), element1);
        simulateEvent(new MouseButtonUp(middleBtn), element1);
        simulateEvent(new MouseClick(rightBtn), element1);
        simulateEvent(new DummyInteraction("bla", 1), element2);
        assertCondensedMouseClicks("elem1", "", "", "elem1", "", "", "", "", "elem2", "", "",
                                   "", "", "elem2", "", "", "elem1", "");
    }

    /**
     *
     */
    private void simulateEvent(IEventType eventType, IGUIElement guiElement) {
        events.add(new Event(eventType, guiElement));
    }

    /**
    *
    */
   private void assertCondensedMouseClicks(String... clickedTargets) {
       MouseClickCondenser condenser = new MouseClickCondenser();
       List<Event> result = condenser.condenseMouseClicks(events);
       
       assertEquals(clickedTargets.length, result.size());
       
       for (int i = 0; i < clickedTargets.length; i++) {
           String clickedTarget = clickedTargets[i];
           
           if ((clickedTarget != null) && (!"".equals(clickedTarget))) {
               assertTrue(result.get(i).getType() instanceof MouseClick);
               assertTrue(result.get(i).getTarget() instanceof DummyGUIElement);
               assertEquals
                 (clickedTarget, ((DummyGUIElement) result.get(i).getTarget()).getStringIdentifier());
           }
           else {
               assertFalse(result.get(i).getType() instanceof MouseClick);
           }
       }
   }
}
