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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskVisitor;

public class TaskWrapper extends AbstractTaskWrapper {
    /**  */
    private static final long serialVersionUID = 1L;

    private static final List<ITaskEntry> EMPTY_LIST = Collections.<ITaskEntry> emptyList();

    final ITask value;
    final ITaskWrapper parent;
    final List<ITaskEntry> children;
    final List<ITaskEntry> next;

    public TaskWrapper(ITask value) {
        this(value, null);
    }

    public TaskWrapper(ITask value, ITaskWrapper parent) {
        this(value, parent, EMPTY_LIST);
    }

    public TaskWrapper(ITask value, ITaskWrapper parent, ITaskEntry next) {
        this(value, parent, Arrays.asList(next));
    }

    public TaskWrapper(ITask value, ITaskWrapper parent, List<ITaskEntry> optional) {
        this.value = value;
        this.children = new ArrayList<ITaskEntry>(getChildrenCount(value));
        this.parent = parent;
        this.next = new ArrayList<ITaskEntry>(optional);
    }

    @Override
    public void addChild(ITaskWrapper child) {
        this.children.add(child);
    }

    @Override
    public void addChildren(List<ITaskWrapper> children) {
        this.children.addAll(children);
    }

    /**
     * <p>
     * Return the number of children the Task has. Sequences and Selections >= 0 Optional and
     * Iteration = 1 EventTask = 0
     * </p>
     * 
     * @param value
     * @return
     */
    private int getChildrenCount(ITask value) {
        if (value instanceof IStructuringTemporalRelationship) {
            return ((IStructuringTemporalRelationship) value).getChildren().size();
        }
        else if (value instanceof IMarkingTemporalRelationship)
            return 1;
        return 0;
    }

    @Override
    public List<ITaskEntry> getNext() {
        return Collections.unmodifiableList(next);
    }

    @Override
    public ITask getReference() {
        return value;
    }

    @Override
    public List<ITaskEntry> getChildren() {
        return Collections.unmodifiableList(children);
    }

    @Override
    public ITaskWrapper getParent() {
        return parent;
    }
    
    // ITask implementation
    
    @Override
    public String toString() {
        return value.toString();
    }

    @Override
    public int getId() {
        return value.getId();
    }

    @Override
    public String getDescription() {
        return value.getDescription();
    }

    @Override
    public Collection<ITaskInstance> getInstances() {
        return value.getInstances();
    }

    @Override
    public boolean equals(ITask task) {
        return value.equals(task);
    }

    @Override
    public void accept(ITaskVisitor visitor) {
        value.accept(visitor);
    }
    
    @Override
    public ITask clone() {
        return super.clone();
    }
}
