/* -----------------------------------------------------------------------------
 * scicontainer.swg
 *
 * Scilab list <-> C++ container wrapper
 *
 * This wrapper, and its iterator, allows a general use (and reuse) of
 * the mapping between C++ and Scilab, thanks to the C++ templates.
 *
 * Of course, it needs the C++ compiler to support templates, but
 * since we will use this wrapper with the STL containers, that should
 * be the case.
 * ----------------------------------------------------------------------------- */

%{
#include <iostream>
%}

#if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
# if !defined(SWIG_EXPORT_ITERATOR_METHODS)
#  define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
# endif
#endif


// #define (SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS)
// if defined: sequences in return are converted from/to Scilab lists or matrices
// if not defined: sequences are passed from/to Scilab as pointers

%{
#define SWIG_STD_NOASSIGN_STL
%}

%include <sciiterators.swg>
%include <scisequence.swg>

%{
#include <stdexcept>
%}

%include <exception.i>
%include <std_except.i>

%fragment("SciSequence_Cont", "header",
	  fragment="StdTraits",
	  fragment="SwigSciIterator_T")
{
namespace swig
{
  template <class T>
  struct SciSequence_Ref
  {
    SciSequence_Ref(const SwigSciObject& seq, int index)
      : _seq(seq), _index(index)
    {
      if (traits_as_sequence<T>::get(_seq, &piSeqAddr) != SWIG_OK)
      {
        throw std::invalid_argument("Cannot get sequence data.");
      }
    }

    operator T () const
    {
      return traits_asval_sequenceitem<T>::asval(_seq, piSeqAddr, _index);
    }

    SciSequence_Ref& operator=(const T& v)
    {
      // TODO
      return *this;
    }

    private:
      SwigSciObject _seq;
      int _index;
      void *piSeqAddr;
  };


  template <class T>
  struct SciSequence_ArrowProxy
  {
    SciSequence_ArrowProxy(const T& x): m_value(x) {}
    const T* operator->() const { return &m_value; }
    operator const T*() const { return &m_value; }
    T m_value;
  };

  template <class T, class Reference >
  struct SwigSciSequence_InputIterator
  {
    typedef SwigSciSequence_InputIterator<T, Reference > self;

    typedef std::random_access_iterator_tag iterator_category;
    typedef Reference reference;
    typedef T value_type;
    typedef T* pointer;
    typedef int difference_type;

    SwigSciSequence_InputIterator()
    {
    }

    SwigSciSequence_InputIterator(const SwigSciObject& seq, int index)
      : _seq(seq), _index(index)
    {
    }

    reference operator*() const
    {
      return reference(_seq, _index);
    }

    SciSequence_ArrowProxy<T>
    operator->() const {
      return SciSequence_ArrowProxy<T>(operator*());
    }

    bool operator==(const self& ri) const
    {
      return (_index == ri._index);
    }

    bool operator!=(const self& ri) const
    {
      return !(operator==(ri));
    }

    self& operator ++ ()
    {
      ++_index;
      return *this;
    }

    self& operator -- ()
    {
      --_index;
      return *this;
    }

    self& operator += (difference_type n)
    {
      _index += n;
      return *this;
    }

    self operator +(difference_type n) const
    {
      return self(_seq, _index + n);
    }

    self& operator -= (difference_type n)
    {
      _index -= n;
      return *this;
    }

    self operator -(difference_type n) const
    {
      return self(_seq, _index - n);
    }

    difference_type operator - (const self& ri) const
    {
      return _index - ri._index;
    }

    bool operator < (const self& ri) const
    {
      return _index < ri._index;
    }

    reference
    operator[](difference_type n) const
    {
      return reference(_seq, _index + n);
    }

  private:
    SwigSciObject _seq;
    difference_type _index;
  };

  template <class T>
  struct SciSequence_Cont
  {
    typedef SciSequence_Ref<T> reference;
    typedef const SciSequence_Ref<T> const_reference;
    typedef T value_type;
    typedef T* pointer;
    typedef int difference_type;
    typedef int size_type;
    typedef const pointer const_pointer;
    typedef SwigSciSequence_InputIterator<T, reference> iterator;
    typedef SwigSciSequence_InputIterator<T, const_reference> const_iterator;

    SciSequence_Cont(const SwigSciObject& seq) : _seq(seq)
    {
    }

    ~SciSequence_Cont()
    {
    }

    size_type size() const
    {
      int iSeqSize;
      if (traits_as_sequence<value_type>::size(_seq, &iSeqSize) == SWIG_OK)
      {
        return iSeqSize;
      }
      else
      {
        return SWIG_ERROR;
      }
    }

    bool empty() const
    {
      return size() == 0;
    }

    iterator begin()
    {
      return iterator(_seq, 0);
    }

    const_iterator begin() const
    {
      return const_iterator(_seq, 0);
    }

    iterator end()
    {
      return iterator(_seq, size());
    }

    const_iterator end() const
    {
      return const_iterator(_seq, size());
    }

    reference operator[](difference_type n)
    {
      return reference(_seq, n);
    }

    const_reference operator[](difference_type n)  const
    {
      return const_reference(_seq, n);
    }

  private:
    SwigSciObject _seq;
  };
}
}

%define %swig_sequence_iterator(Sequence...)
#if defined(SWIG_EXPORT_ITERATOR_METHODS)
  class iterator;
  class reverse_iterator;
  class const_iterator;
  class const_reverse_iterator;

  %typemap(out,noblock=1,fragment="SciSequence_Cont")
    iterator, reverse_iterator, const_iterator, const_reverse_iterator {
    %set_output(SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &)),
           swig::SciSwigIterator::descriptor(),SWIG_POINTER_OWN));
  }
  %typemap(out,fragment="SciSequence_Cont")
    std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> {
    // TODO: return a Scilab list from the pair (see code for Octave)
  }

  %fragment("SciSwigPairBoolOutputIterator", "header",
    fragment=SWIG_From_frag(bool), fragment="SciSequence_Cont") {}

  %typemap(out,fragment="SciSwigPairBoolOutputIterator")
    std::pair<iterator, bool>, std::pair<const_iterator, bool> {
    // TODO: return a Scilab list from the pair (see code for Octave)
  }

  %typemap(in,noblock=1,fragment="SciSequence_Cont")
    iterator(swig::SciSwigIterator *iter = 0, int res),
    reverse_iterator(swig::SciSwigIterator *iter = 0, int res),
    const_iterator(swig::SciSwigIterator *iter = 0, int res),
    const_reverse_iterator(swig::SciSwigIterator *iter = 0, int res) {
    res = SWIG_ConvertPtr((SwigSciObject)$input, %as_voidptrptr(&iter), swig::SciSwigIterator::descriptor(), 0);
    if (!SWIG_IsOK(res) || !iter) {
      %argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
    } else {
      swig::SwigSciIterator_T<$type > *iter_t = dynamic_cast<swig::SwigSciIterator_T<$type > *>(iter);
      if (iter_t) {
	$1 = iter_t->get_current();
      } else {
	%argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
      }
    }
  }

  %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SciSequence_Cont")
    iterator, reverse_iterator, const_iterator, const_reverse_iterator {
    swig::SciSwigIterator *iter = 0;
    int res = SWIG_ConvertPtr((SwigSciObject)$input, %as_voidptrptr(&iter), swig::SciSwigIterator::descriptor(), 0);
    $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigSciIterator_T<$type > *>(iter) != 0));
  }

  %fragment("SciSequence_Cont");
#endif //SWIG_EXPORT_ITERATOR_METHODS
%enddef

// The Scilab container methods

%define %swig_container_methods(Container...)
%enddef

%define %swig_sequence_methods_common(Sequence...)
  %swig_sequence_iterator(%arg(Sequence))
  %swig_container_methods(%arg(Sequence))

%enddef

%define %swig_sequence_methods(Sequence...)
  %swig_sequence_methods_common(%arg(Sequence))
%enddef

%define %swig_sequence_methods_val(Sequence...)
  %swig_sequence_methods_common(%arg(Sequence))
%enddef

//
// Common fragments
//

%fragment("StdSequenceTraits","header",
	  fragment="StdTraits",
	  fragment="SciSequence_Cont",
    fragment=SWIG_Traits_SequenceItem_frag(ptr))
{
namespace swig {
  template <class SciSeq, class Seq>
  inline void
  assign(const SciSeq& sciSeq, Seq* seq) {
%#ifdef SWIG_STD_NOASSIGN_STL
    typedef typename SciSeq::value_type value_type;
    typename SciSeq::const_iterator it = sciSeq.begin();
    for (;it != sciSeq.end(); ++it) {
      seq->insert(seq->end(),(value_type)(*it));
    }
%#else
    seq->assign(sciSeq.begin(), sciSeq.end());
%#endif
  }

  template <class Seq, class T = typename Seq::value_type >
  struct traits_asptr_stdseq {
    typedef Seq sequence;
    typedef T value_type;

    static int asptr(const SwigSciObject& obj, sequence **seq)
    {
      swig_type_info *typeInfo = swig::type_info<sequence>();
      if (typeInfo)
      {
          sequence *p;
          if (SWIG_ConvertPtr(obj, (void**)&p, typeInfo, 0) == SWIG_OK)
          {
            if (seq)
              *seq = p;
            return SWIG_OLDOBJ;
          }
      }

      if (traits_as_sequence<value_type>::check(obj) == SWIG_OK)
      {
        try
        {
          SciSequence_Cont<value_type> sciSeq(obj);
          if (seq)
          {
            *seq = new sequence();
            assign(sciSeq, *seq);
            return SWIG_NEWOBJ;
          }
          else
          {
            return SWIG_ERROR;
          }
        }
        catch (std::exception& e)
        {
          SWIG_exception(SWIG_RuntimeError, e.what());
          return SWIG_ERROR;
        }
      }
      else 
      {
        return SWIG_ERROR;
      }
    }
  };

  template <class Seq, class T = typename Seq::value_type >
  struct traits_from_stdseq {
    typedef Seq sequence;
    typedef T value_type;
    typedef typename Seq::size_type size_type;
    typedef typename sequence::const_iterator const_iterator;

    static SwigSciObject from(const sequence& seq)
    {
      %#ifdef SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS
      swig_type_info *typeInfo = swig::type_info<sequence>();
      if (typeInfo)
      {
        return SWIG_NewPointerObj(new sequence(seq), typeInfo, SWIG_POINTER_OWN);
      }
      %#endif

      try
      {
        void *data;
        size_type size = seq.size();
        if (traits_from_sequence<value_type>::create(size, &data) == SWIG_OK) {
          const_iterator it;
          int index = 0;
          for (it = seq.begin(); it != seq.end(); ++it)
          {
            traits_from_sequenceitem<value_type>::from(data, index, *it);
            index++;
          }
          return traits_from_sequence<value_type>::set(size, data);
        }
        return SWIG_OK;
      }
      catch (std::exception& e)
      {
        SWIG_exception(SWIG_RuntimeError, e.what());
        return SWIG_ERROR;
      }
    }
  };
}
}
