//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package de.ugoe.cs.autoquest.tasktrees.treeifc;

import java.util.LinkedList;

/**
 * <p>
 * TODO comment
 * </p>
 * 
 * @author Patrick Harms
 */
public class TaskPath {

    /** */
    private LinkedList<Entry> taskList;
    
    /**
     *
     *
     */
    public TaskPath() {
        super();
        taskList = new LinkedList<Entry>();
    }

    /**
     *
     */
    public TaskPath(TaskPath path) {
        this();
        taskList.addAll(path.taskList);
    }

    /**
     * 
     */
    public TaskPath subPath(int fromIndex, int toIndex) {
        TaskPath result = new TaskPath();
        result.taskList.addAll(taskList.subList(fromIndex, toIndex));
        return result;
    }

    /**
     * 
     */
    public ITask removeLast() {
        Entry last = taskList.removeLast();
        if (last != null) {
            return last.getTask();
        }
        else {
            return null;
        }
    }

    /**
     * 
     */
    public ITask getLast() {
        Entry last = taskList.getLast();
        if (last != null) {
            return last.getTask();
        }
        else {
            return null;
        }
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return taskList.toString();
    }

    /**
     *
     */
    public int size() {
        return taskList.size();
    }

    /**
     *
     */
    public boolean isEmpty() {
        return taskList.isEmpty();
    }
    
    /**
     * 
     */
    public void add(ITask task, int index) {
        taskList.add(new Entry(task, index));
    }

    /**
     *
     */
    public ITask getTask(int index) {
        Entry last = taskList.get(index);
        if (last != null) {
            return last.getTask();
        }
        else {
            return null;
        }
    }

    /**
     *
     */
    public Entry get(int index) {
        return taskList.get(index);
    }

    /**
     *
     */
    public void remove(int index) {
        taskList.remove(index);
    }

    
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        ITask last = getLast();
        if (last != null) {
            return last.hashCode();
        }
        else {
            return 0;
        }
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        else if (obj instanceof TaskPath) {
            TaskPath other = (TaskPath) obj;
            if ((other != null) && (this.size() == other.size())) {
                for (int i = 0; i < this.size(); i++) {
                    if (!this.get(i).equals(other.get(i))) {
                        return false;
                    }
                }
                return true;
            }
        }
        
        return false;
    }


    /**
     * 
     */
    public static class Entry {
        
        /** */
        private ITask task;
        
        /** */
        private int index;
        
        /**
         * 
         */
        private Entry(ITask task, int index) {
            this.task = task;
            this.index = index;
        }

        /* (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return "(" + task + "," + index + ")";
        }

        /**
         * @return the task
         */
        public ITask getTask() {
            return task;
        }

        /**
         * @return the index
         */
        public int getIndex() {
            return index;
        }

        /* (non-Javadoc)
         * @see java.lang.Object#hashCode()
         */
        @Override
        public int hashCode() {
            return task.hashCode();
        }

        /* (non-Javadoc)
         * @see java.lang.Object#equals(java.lang.Object)
         */
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            else if (obj instanceof TaskPath.Entry) {
                return (this.getIndex() == ((TaskPath.Entry) obj).getIndex()) &&
                    (this.getTask().equals(((TaskPath.Entry) obj).getTask()));
            }
            
            return false;
        }
        
        
    }
    
}
