package jetbrains.mps.internal.collections.runtime;

/*Generated by MPS */

import java.io.Serializable;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.Queue;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import java.util.Deque;
import jetbrains.mps.internal.collections.runtime.impl.NullLinkedListSequence;
import java.util.Collection;
import java.util.List;
import java.util.Arrays;

public class LinkedListSequence<T> extends AbstractListSequence<T> implements ILinkedListSequence<T>, ILinkedList<T>, Serializable {
  private static final long serialVersionUID = 3534032475696821184L;
  protected LinkedListSequence(LinkedListSequence<T> other) {
    super(other);
  }
  private LinkedListSequence(LinkedList<T> list) {
    super(list);
  }
  @Override
  public void addFirst(T t) {
    getList().addFirst(t);
  }
  @Override
  public void addLast(T t) {
    getList().addLast(t);
  }
  @Override
  public boolean offerFirst(T t) {
    return getList().offerFirst(t);
  }
  @Override
  public boolean offerLast(T t) {
    return getList().offerLast(t);
  }
  @Override
  public T removeFirst() {
    return getList().removeFirst();
  }
  @Override
  public T removeLast() {
    return getList().removeLast();
  }
  @Override
  public T pollLast() {
    return getList().pollLast();
  }
  @Override
  public T getFirst() {
    return getList().getFirst();
  }
  @Override
  public T getLast() {
    return getList().getLast();
  }
  @Override
  public T peekFirst() {
    return getList().peekFirst();
  }
  @Override
  public T peekLast() {
    return getList().peekLast();
  }
  @Override
  public boolean removeFirstOccurrence(Object o) {
    return getList().removeFirstOccurrence(o);
  }
  @Override
  public boolean offer(T t) {
    return getList().offer(t);
  }
  @Override
  public T remove() {
    return getList().remove();
  }
  @Override
  public T poll() {
    return getList().poll();
  }
  @Override
  public T element() {
    return getList().element();
  }
  @Override
  public T peek() {
    return getList().peek();
  }
  @Override
  public void push(T t) {
    getList().push(t);
  }
  @Override
  public T pop() {
    return getList().pop();
  }
  @Override
  public Iterator<T> descendingIterator() {
    return null;
  }
  @Override
  public T pollFirst() {
    return getList().pollFirst();
  }
  @Override
  public boolean removeLastOccurrence(Object o) {
    return getList().removeLastOccurrence(o);
  }
  @Override
  public T addLastElement(T t) {
    getList().addLast(t);
    return t;
  }
  @Override
  public T removeFirstElement() {
    if (Sequence.NULL_WHEN_EMPTY) {
      if (getList().isEmpty()) {
        return null;
      }
    }
    return getList().removeFirst();
  }
  @Override
  public Queue<T> toQueue() {
    return getList();
  }
  @Override
  public T addFirstElement(T t) {
    if (Sequence.IGNORE_NULL_VALUES) {
      if (t == null) {
        return null;
      }
    }
    getList().addFirst(t);
    return t;
  }
  @Override
  public T peekElement() {
    if (Sequence.NULL_WHEN_EMPTY) {
      if (getList().isEmpty()) {
        return null;
      }
    }
    return getList().peek();
  }
  @Override
  public T popElement() {
    if (Sequence.NULL_WHEN_EMPTY) {
      if (getList().isEmpty()) {
        return null;
      }
    }
    return getList().pop();
  }
  @Override
  public T pushElement(T t) {
    getList().push(t);
    return t;
  }
  @Override
  public LinkedListSequence<T> asUnmodifiable() {
    throw new UnsupportedOperationException();
  }
  @Override
  public LinkedListSequence<T> asSynchronized() {
    throw new UnsupportedOperationException();
  }
  @Override
  public ILinkedListSequence<T> addSequence(ISequence<? extends T> seq) {
    throw new UnsupportedOperationException();
  }
  @Override
  public ILinkedListSequence<T> removeSequence(ISequence<? extends T> seq) {
    return (ILinkedListSequence<T>) super.removeSequence(seq);
  }
  @Override
  public ILinkedListSequence<T> removeWhere(_FunctionTypes._return_P1_E0<? extends Boolean, ? super T> filter) {
    return (ILinkedListSequence<T>) super.removeWhere(filter);
  }
  @Override
  public IListSequence<T> reversedList() {
    LinkedListSequence<T> reversed = new LinkedListSequence<T>(this);
    reversed._reverse();
    return reversed;
  }
  @Override
  public IListSequence<T> subListSequence(int fromIdx, int upToIdx) {
    return new ListSequence<T>(getList().subList(fromIdx, upToIdx));
  }
  @Override
  public IListSequence<T> headListSequence(int upToIdx) {
    return new ListSequence<T>(getList().subList(0, upToIdx));
  }
  @Override
  public IListSequence<T> tailListSequence(int fromIdx) {
    return new ListSequence<T>(getList().subList(fromIdx, getList().size()));
  }
  @Override
  protected LinkedList<T> getList() {
    return (LinkedList<T>) super.getList();
  }
  public static <U> ILinkedListSequence<U> fromLinkedList(Deque<U> list) {
    // shall update templates to generate fromLinkedList() again, and then can remove fromLinkedListNew
    if (list instanceof ILinkedListSequence<?>) {
      return (ILinkedListSequence<U>) list;
    }
    if (list == null && Sequence.USE_NULL_SEQUENCE) {
      return NullLinkedListSequence.instance();
    }
    if (list instanceof LinkedList) {
      return new LinkedListSequence<U>((LinkedList<U>) list);
    }
    return LinkedListSequence.fromIterable(list);
  }
  /**
   * 
   * @deprecated use non-new method
   */
  @Deprecated
  public static <U> ILinkedListSequence<U> fromLinkedListNew(Deque<U> list) {
    return fromLinkedList(list);
  }
  public static <U> ILinkedListSequence<U> fromIterable(Iterable<U> it) {
    if (Sequence.USE_NULL_SEQUENCE) {
      if (it == null) {
        return NullLinkedListSequence.instance();
      }
    }
    if (it instanceof ILinkedListSequence<?>) {
      return (ILinkedListSequence<U>) it;
    }
    LinkedList<U> list = new LinkedList<U>();
    if (Sequence.IGNORE_NULL_VALUES) {
      for (U u : it) {
        if (u != null) {
          list.add(u);
        }
      }
    } else
    if (it instanceof Collection<?>) {
      list.addAll((Collection<? extends U>) it);
    } else {
      for (U u : it) {
        list.add(u);
      }
    }
    return new LinkedListSequence<U>(list);
  }

  public static <U> ILinkedListSequence<U> fromListAndArray(LinkedList<U> list, U... array) {
    if (Sequence.NULL_ARRAY_IS_SINGLETON) {
      if (array == null) {
        array = (U[]) Sequence.nullSingletonArray();
      }
    }
    if (Sequence.USE_NULL_SEQUENCE) {
      if (list == null && array == null) {
        return NullLinkedListSequence.instance();
      } else
      if (list == null) {
        list = new LinkedList<U>();
      } else
      if (array == null) {
        if (list instanceof IListSequence<?>) {
          return (ILinkedListSequence<U>) list;
        }
        return new LinkedListSequence<U>(list);
      }
    }
    List<U> input = Arrays.asList(array);
    if (Sequence.IGNORE_NULL_VALUES) {
      for (U u : input) {
        if (u != null) {
          list.add(u);
        }
      }
    } else {
      list.addAll(input);
    }
    if (list instanceof ILinkedListSequence<?>) {
      return (ILinkedListSequence<U>) list;
    }
    return new LinkedListSequence<U>(list);
  }
  /**
   * 
   * @deprecated use non-new method
   */
  @Deprecated
  public static <U> ILinkedListSequence<U> fromListAndArrayNew(LinkedList<U> list, U... array) {
    return fromListAndArray(list, array);
  }

  public static <U> ILinkedListSequence<U> fromListWithValues(LinkedList<U> list, Iterable<? extends U> it) {
    LinkedList<U> tmp = list;
    if (Sequence.USE_NULL_SEQUENCE) {
      if (list == null && it == null) {
        return NullLinkedListSequence.instance();
      } else
      if (list == null) {
        tmp = new LinkedList<U>();
      } else
      if (it == null) {
        return LinkedListSequence.fromLinkedListNew(list);
      }
    }
    if (Sequence.IGNORE_NULL_VALUES) {
      for (U u : it) {
        if (u != null) {
          tmp.add(u);
        }
      }
    } else
    if (it instanceof Collection<?>) {
      tmp.addAll((Collection<? extends U>) it);
    } else {
      for (U u : it) {
        tmp.add(u);
      }
    }
    if (tmp instanceof ILinkedListSequence<?>) {
      return (ILinkedListSequence<U>) tmp;
    }
    return new LinkedListSequence<U>(tmp);
  }
  /**
   * 
   * @deprecated use non-new method
   */
  @Deprecated
  public static <U> ILinkedListSequence<U> fromListWithValuesNew(LinkedList<U> list, Iterable<? extends U> it) {
    return fromListWithValues(list, it);
  }
}
