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

import de.ugoe.cs.autoquest.eventcore.IEventType;
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.IIteration;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;

public class TaskTypeFilter extends AbstractTaskFilter {

    public static final TaskTypeFilter ITERATION = new TaskTypeFilter(IIteration.class);
    public static final TaskTypeFilter OPTIONAL = new TaskTypeFilter(IOptional.class);
    public static final TaskTypeFilter SELECTION = new TaskTypeFilter(ISelection.class);
    public static final TaskTypeFilter SEQUENCE = new TaskTypeFilter(ISequence.class);
    public static final TaskTypeFilter EVENT = new TaskTypeFilter(IEventTask.class);

    private Class<? extends ITask> taskTypeClazz;

    protected TaskTypeFilter(Class<? extends ITask> taskTypeClazz) {
        this.taskTypeClazz = taskTypeClazz;
    }    
    
    @Override
    public IResult match(ITask task) {
        if (isEvent(task)) {
           return new SingleMatchResult(new DefaultMatch(task));
        }
        return UnmatchableResult.NO_MATCH_FOUND;
    }

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

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