package de.ugoe.cs.autoquest.plugin.usability2.rules.operator.filter;

import de.ugoe.cs.autoquest.eventcore.IEventType;
import de.ugoe.cs.autoquest.eventcore.StringEventType;
import de.ugoe.cs.autoquest.eventcore.gui.KeyboardFocusChange;
import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
import de.ugoe.cs.autoquest.plugin.usability2.rules.operator.wrapper.ITaskEntry;
import de.ugoe.cs.autoquest.plugin.usability2.rules.results.DefaultMatch;
import de.ugoe.cs.autoquest.plugin.usability2.rules.results.IResult;
import de.ugoe.cs.autoquest.plugin.usability2.rules.results.SingleMatchResult;
import de.ugoe.cs.autoquest.plugin.usability2.rules.results.UnmatchableResult;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;

public class EventTypeFilter extends AbstractTaskFilter {

    public static final EventTypeFilter MOUSE_CLICK = new EventTypeFilter(MouseClick.class);
    public static final EventTypeFilter TEXT_INPUT = new EventTypeFilter(TextInput.class);
    public static final EventTypeFilter KEYBOARD_FOCUS_CHANGE = new EventTypeFilter(KeyboardFocusChange.class);
    public static final EventTypeFilter SCROLL = new EventTypeFilter(Scroll.class);

    private Class<? extends IEventType> eventTypeClazz;

    protected EventTypeFilter(Class<? extends IEventType> eventTypeClazz) {
        this.eventTypeClazz = eventTypeClazz;
    }    
    
    @Override
    public IResult match(ITask task) {
        if (isEvent(task)) {
            IEventType type = getType(task);
            if(matchesType(type, eventTypeClazz))
                return new SingleMatchResult(new DefaultMatch(task));
        }
        return UnmatchableResult.NO_MATCH_FOUND;
    }
    
    protected boolean matchesType(IEventType type, Class<? extends IEventType> eventTypeClazz) {
        if (type instanceof StringEventType) {
            String cur = nameOfEventType(type);
            String other = eventTypeClazz.getSimpleName();
            if (cur.equals(other))
                return true;
        } else if (eventTypeClazz.isInstance(type)) {
            return true;
        }
        
        return false;
    }
    
    protected String nameOfEventType(IEventType type) {
        return type.toString();
    }


    private boolean isEvent(ITask task) {
        if(task instanceof ITaskEntry)
            task = ((ITaskEntry) task).getReference();
        
        if(task instanceof IEventTask)
            return true;
        
        return false;
    }

    public IEventType getType(ITask task){
        ITaskInstance firstInstance = task.getInstances().iterator().next();
        return ((IEventTaskInstance) firstInstance).getEvent().getType();
    }
    
}
