/* -----------------------------------------------------------------------------
 * std_list.i
 *
 * SWIG typemaps for std::list<T>
 * C# implementation
 * The C# wrapper is made to look and feel like a C# System.Collections.Generic.LinkedList<> collection.
 *
 * Note that IEnumerable<> is implemented in the proxy class which is useful for using LINQ with
 * C++ std::list wrappers. The ICollection<> interface is also implemented to provide enhanced functionality
 * whenever we are confident that the required C++ operator== is available. This is the case for when
 * T is a primitive type or a pointer. If T does define an operator==, then use the SWIG_STD_LIST_ENHANCED
 * macro to obtain this enhanced functionality, for example:
 *
 *   SWIG_STD_LIST_ENHANCED(SomeNamespace::Klass)
 *   %template(ListKlass) std::list<SomeNamespace::Klass>;
 * ----------------------------------------------------------------------------- */

%include <std_common.i>

// MACRO for use within the std::list class body
%define SWIG_STD_LIST_MINIMUM_INTERNAL(CSINTERFACE, CTYPE...)
%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"

%apply void *VOID_INT_PTR { std::list< CTYPE >::iterator * };

%proxycode %{
  public $csclassname(global::System.Collections.IEnumerable c) : this() {
    if (c == null)
      throw new global::System.ArgumentNullException("c");
    foreach ($typemap(cstype, CTYPE) element in c) {
      this.AddLast(element);
    }
  }

  public bool IsReadOnly {
    get {
      return false;
    }
  }

  public int Count {
    get {
      return (int)size();
    }
  }

  public $csclassnameNode First {
    get {
      if (Count == 0)
        return null;
      return new $csclassnameNode(getFirstIter(), this);
    }
  }

  public $csclassnameNode Last {
    get {
      if (Count == 0)
        return null;
      return new $csclassnameNode(getLastIter(), this);
    }
  }

  public $csclassnameNode AddFirst($typemap(cstype, CTYPE) value) {
    push_front(value);
    return new $csclassnameNode(getFirstIter(), this);
  }

  public void AddFirst($csclassnameNode newNode) {
    ValidateNewNode(newNode);
    if (!newNode.inlist) {
      push_front(newNode.csharpvalue);
      newNode.iter = getFirstIter();
      newNode.inlist = true;
    } else {
      throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name);
    }
  }

  public $csclassnameNode AddLast($typemap(cstype, CTYPE) value) {
    push_back(value);
    return new $csclassnameNode(getLastIter(), this);
  }

  public void AddLast($csclassnameNode newNode) {
    ValidateNewNode(newNode);
    if (!newNode.inlist) {
      push_back(newNode.csharpvalue);
      newNode.iter = getLastIter();
      newNode.inlist = true;
    } else {
      throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name);
    }
  }

  public $csclassnameNode AddBefore($csclassnameNode node, $typemap(cstype, CTYPE) value) {
    return new $csclassnameNode(insertNode(node.iter, value), this);
  }

  public void AddBefore($csclassnameNode node, $csclassnameNode newNode) {
    ValidateNode(node);
    ValidateNewNode(newNode);
    if (!newNode.inlist) {
      newNode.iter = insertNode(node.iter, newNode.csharpvalue);
      newNode.inlist = true;
    } else {
      throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name);
    }
  }

  public $csclassnameNode AddAfter($csclassnameNode node, $typemap(cstype, CTYPE) value) {
    node = node.Next;
    return new $csclassnameNode(insertNode(node.iter, value), this);
  }

  public void AddAfter($csclassnameNode node, $csclassnameNode newNode) {
    ValidateNode(node);
    ValidateNewNode(newNode);
    if (!newNode.inlist) {
      if (node == this.Last)
        AddLast(newNode);
      else
      {
        node = node.Next;
        newNode.iter = insertNode(node.iter, newNode.csharpvalue);
        newNode.inlist = true;
      }
    } else {
      throw new global::System.InvalidOperationException("The " + newNode.GetType().Name + " node already belongs to a " + this.GetType().Name);
    }
  }

  public void Add($typemap(cstype, CTYPE) value) {
    AddLast(value);
  }

  public void Remove($csclassnameNode node) {
    ValidateNode(node);
    eraseIter(node.iter);
  }

  public void CopyTo($typemap(cstype, CTYPE)[] array, int index) {
    if (array == null)
      throw new global::System.ArgumentNullException("array");
    if (index < 0 || index > array.Length)
      throw new global::System.ArgumentOutOfRangeException("index", "Value is less than zero");
    if (array.Rank > 1)
      throw new global::System.ArgumentException("Multi dimensional array.", "array");
    $csclassnameNode node = this.First;
    if (node != null) {
      do {
        array[index++] = node.Value;
        node = node.Next;
      } while (node != null);
    }
  }

  internal void ValidateNode($csclassnameNode node) {
    if (node == null) {
      throw new System.ArgumentNullException("node");
    }
    if (!node.inlist || node.list != this) {
      throw new System.InvalidOperationException("node");
    }
  }

  internal void ValidateNewNode($csclassnameNode node) {
    if (node == null) {
      throw new System.ArgumentNullException("node");
    }
  }

  global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>.GetEnumerator() {
    return new $csclassnameEnumerator(this);
  }

  global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() {
    return new $csclassnameEnumerator(this);
  }

  public $csclassnameEnumerator GetEnumerator() {
    return new $csclassnameEnumerator(this);
  }

  public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator,
    global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)>
  {
    private $csclassname collectionRef;
    private $csclassnameNode currentNode;
    private int currentIndex;
    private object currentObject;
    private int currentSize;

    public $csclassnameEnumerator($csclassname collection) {
      collectionRef = collection;
      currentNode = collection.First;
      currentIndex = 0;
      currentObject = null;
      currentSize = collectionRef.Count;
    }

    // Type-safe iterator Current
    public $typemap(cstype, CTYPE) Current {
      get {
        if (currentIndex == -1)
          throw new global::System.InvalidOperationException("Enumeration not started.");
        if (currentIndex > currentSize)
          throw new global::System.InvalidOperationException("Enumeration finished.");
        if (currentObject == null)
          throw new global::System.InvalidOperationException("Collection modified.");
        return ($typemap(cstype, CTYPE))currentObject;
      }
    }

    // Type-unsafe IEnumerator.Current
    object global::System.Collections.IEnumerator.Current {
      get {
        return Current;
      }
    }

    public bool MoveNext() {
      if (currentNode == null) {
        currentIndex = collectionRef.Count + 1;
        return false;
      }
      ++currentIndex;
      currentObject = currentNode.Value;
      currentNode = currentNode.Next;
      return true;
    }

    public void Reset() {
      currentIndex = -1;
      currentObject = null;
      if (collectionRef.Count != currentSize) {
        throw new global::System.InvalidOperationException("Collection modified.");
      }
    }

    public void Dispose() {
      currentIndex = -1;
      currentObject = null;
    }
  }

  public sealed class $csclassnameNode {
    internal $csclassname list;
    internal System.IntPtr iter;
    internal $typemap(cstype, CTYPE) csharpvalue;
    internal bool inlist;

    public $csclassnameNode($typemap(cstype, CTYPE) value) {
      csharpvalue = value;
      inlist = false;
    }

    internal $csclassnameNode(System.IntPtr iter, $csclassname list) {
      this.list = list;
      this.iter = iter;
      inlist = true;
    }

    public $csclassname List {
      get {
        return this.list;
      }
    }

    public $csclassnameNode Next {
      get {
        if (list.getNextIter(iter) == System.IntPtr.Zero)
          return null;
        return new $csclassnameNode(list.getNextIter(iter), list);
      }
    }

    public $csclassnameNode Previous {
      get {
        if (list.getPrevIter(iter) == System.IntPtr.Zero)
          return null;
        return new $csclassnameNode(list.getPrevIter(iter), list);
      }
    }

    public $typemap(cstype, CTYPE) Value {
      get {
        return list.getItem(this.iter);
      }
      set {
        list.setItem(this.iter, value);
      }
    }

    public static bool operator==($csclassnameNode node1, $csclassnameNode node2) {
      if (object.ReferenceEquals(node1, null) && object.ReferenceEquals(node2, null))
        return true;
      if (object.ReferenceEquals(node1, null) || object.ReferenceEquals(node2, null))
        return false;
      return node1.Equals(node2);
    }

    public static bool operator!=($csclassnameNode node1, $csclassnameNode node2) {
      if (node1 == null && node2 == null)
        return false;
      if (node1 == null || node2 == null)
        return true;
      return !node1.Equals(node2);
    }

    public bool Equals($csclassnameNode node) {
      if (node == null)
        return false;
      if (!node.inlist || !this.inlist)
        return object.ReferenceEquals(this, node);
      return list.equals(this.iter, node.iter);
    }

    public override bool Equals(object node) {
      return Equals(($csclassnameNode)node);
    }

    public override int GetHashCode() {
      int hash = 13;
      if (inlist) {
        hash = (hash * 7) + this.list.GetHashCode();
        hash = (hash * 7) + this.Value.GetHashCode();
        hash = (hash * 7) + this.list.getNextIter(this.iter).GetHashCode();
        hash = (hash * 7) + this.list.getPrevIter(this.iter).GetHashCode();
      } else {
        hash = (hash * 7) + this.csharpvalue.GetHashCode();
      }
      return hash;
    }

    public void Dispose() {
      list.deleteIter(this.iter);
    }
  }
%}

public:
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  typedef CTYPE value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;
  typedef value_type& reference;
  typedef const value_type& const_reference;

  class iterator;

  void push_front(CTYPE const& x);
  void push_back(CTYPE const& x);
  %rename(RemoveFirst) pop_front;
  void pop_front();
  %rename(RemoveLast) pop_back;
  void pop_back();
  size_type size() const;
  %rename(Clear) clear;
  void clear();
  %extend {
    const_reference getItem(iterator *iter) {
      return **iter;
    }

    void setItem(iterator *iter, CTYPE const& val) {
      *(*iter) = val;
    }

    iterator *getFirstIter() {
      if ($self->size() == 0)
        return NULL;
      return new std::list< CTYPE >::iterator($self->begin());
    }

    iterator *getLastIter() {
      if ($self->size() == 0)
        return NULL;
      return new std::list< CTYPE >::iterator(--$self->end());
    }

    iterator *getNextIter(iterator *iter) {
      std::list< CTYPE >::iterator it = *iter;
      if (std::distance(it, --$self->end()) != 0) {
        std::list< CTYPE >::iterator* itnext = new std::list< CTYPE >::iterator(++it);
        return itnext;
      }
      return NULL;
    }

    iterator *getPrevIter(iterator *iter) {
      std::list< CTYPE >::iterator it = *iter;
      if (std::distance($self->begin(), it) != 0) {
        std::list< CTYPE >::iterator* itprev = new std::list< CTYPE >::iterator(--it);
        return itprev;
      }
      return NULL;
    }

    iterator *insertNode(iterator *iter, CTYPE const& value) {
      std::list< CTYPE >::iterator it = $self->insert(*iter, value);
      return new std::list< CTYPE >::iterator(it);
    }

    void eraseIter(iterator *iter) {
      std::list< CTYPE >::iterator it = *iter;
      $self->erase(it);
    }

    void deleteIter(iterator *iter) {
      delete iter;
    }

    bool equals(iterator *iter1, iterator *iter2) {
      if (iter1 == NULL && iter2 == NULL)
        return true;
      std::list< CTYPE >::iterator it1 = *iter1;
      std::list< CTYPE >::iterator it2 = *iter2;
      return it1 == it2;
    }
  }
%enddef

// Extra methods added to the collection class if operator== is defined for the class being wrapped
// The class will then implement ICollection<>, which adds extra functionality
%define SWIG_STD_LIST_EXTRA_OP_EQUALS_EQUALS(CTYPE...)
  %extend {
    bool Contains(CTYPE const& value) {
      return std::find($self->begin(), $self->end(), value) != $self->end();
    }

    bool Remove(CTYPE const& value) {
      std::list< CTYPE >::iterator it = std::find($self->begin(), $self->end(), value);
      if (it != $self->end()) {
        $self->erase(it);
        return true;
      }
      return false;
    }

    iterator *find(CTYPE const& value) {
      if (std::find($self->begin(), $self->end(), value) != $self->end()) {
        return new std::list< CTYPE >::iterator(std::find($self->begin(), $self->end(), value));
      }
      return NULL;
    }
  }
%proxycode %{
  public $csclassnameNode Find($typemap(cstype, CTYPE) value) {
    System.IntPtr tmp = find(value);
    if (tmp != System.IntPtr.Zero) {
      return new $csclassnameNode(tmp, this);
    }
    return null;
  }
%}
%enddef

// Macros for std::list class specializations/enhancements
%define SWIG_STD_LIST_ENHANCED(CTYPE...)
namespace std {
  template<> class list< CTYPE > {
    SWIG_STD_LIST_MINIMUM_INTERNAL(ICollection, %arg(CTYPE));
    SWIG_STD_LIST_EXTRA_OP_EQUALS_EQUALS(CTYPE)
  };
}
%enddef


%{
#include <list>
#include <algorithm>
#include <stdexcept>
%}

%csmethodmodifiers std::list::size "private"
%csmethodmodifiers std::list::getItem "private"
%csmethodmodifiers std::list::setItem "private"
%csmethodmodifiers std::list::push_front "private"
%csmethodmodifiers std::list::push_back "private"
%csmethodmodifiers std::list::getFirstIter "private"
%csmethodmodifiers std::list::getNextIter "private"
%csmethodmodifiers std::list::getPrevIter "private"
%csmethodmodifiers std::list::getLastIter "private"
%csmethodmodifiers std::list::find "private"
%csmethodmodifiers std::list::deleteIter "private"

namespace std {
  // primary (unspecialized) class template for std::list
  // does not require operator== to be defined
  template<class T>
  class list {
    SWIG_STD_LIST_MINIMUM_INTERNAL(IEnumerable, T)
  };
  // specialization for pointers
  template<class T>
  class list<T *> {
    SWIG_STD_LIST_MINIMUM_INTERNAL(ICollection, T *)
    SWIG_STD_LIST_EXTRA_OP_EQUALS_EQUALS(T *)
  };
}

// template specializations for std::list
// these provide extra collections methods as operator== is defined
SWIG_STD_LIST_ENHANCED(char)
SWIG_STD_LIST_ENHANCED(signed char)
SWIG_STD_LIST_ENHANCED(unsigned char)
SWIG_STD_LIST_ENHANCED(short)
SWIG_STD_LIST_ENHANCED(unsigned short)
SWIG_STD_LIST_ENHANCED(int)
SWIG_STD_LIST_ENHANCED(unsigned int)
SWIG_STD_LIST_ENHANCED(long)
SWIG_STD_LIST_ENHANCED(unsigned long)
SWIG_STD_LIST_ENHANCED(long long)
SWIG_STD_LIST_ENHANCED(unsigned long long)
SWIG_STD_LIST_ENHANCED(float)
SWIG_STD_LIST_ENHANCED(double)
SWIG_STD_LIST_ENHANCED(std::string) // also requires a %include <std_string.i>
SWIG_STD_LIST_ENHANCED(std::wstring) // also requires a %include <std_wstring.i>
