/* -----------------------------------------------------------------------------
 * std_vector.i
 * ----------------------------------------------------------------------------- */

%include <std_common.i>

// ------------------------------------------------------------------------
// std::vector
// 
// The aim of all that follows would be to integrate std::vector with 
// Tcl as much as possible, namely, to allow the user to pass and 
// be returned Tcl lists.
// const declarations are used to guess the intent of the function being
// exported; therefore, the following rationale is applied:
// 
//   -- f(std::vector< T >), f(const std::vector< T >&), f(const std::vector< T >*):
//      the parameter being read-only, either a Tcl list or a
//      previously wrapped std::vector< T > can be passed.
//   -- f(std::vector< T >&), f(std::vector< T >*):
//      the parameter must be modified; therefore, only a wrapped std::vector
//      can be passed.
//   -- std::vector< T > f():
//      the vector is returned by copy; therefore, a Tcl list of T:s 
//      is returned which is most easily used in other Tcl functions procs
//   -- std::vector< T >& f(), std::vector< T >* f(), const std::vector< T >& f(),
//      const std::vector< T >* f():
//      the vector is returned by reference; therefore, a wrapped std::vector
//      is returned
// ------------------------------------------------------------------------

%{
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <string>

Tcl_Obj* SwigString_FromString(const std::string &s) {
    return Tcl_NewStringObj(s.data(), (int)s.length());
}

int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
  int v;
  int res = Tcl_GetBooleanFromObj(interp, o, &v);
  if (res == TCL_OK) {
    *val = v ? true : false;
  }
  return res;  
}
 
int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
    int len;
    const char* temp = Tcl_GetStringFromObj(o, &len);
    if (temp == NULL)
        return TCL_ERROR;
    val->assign(temp, len);
    return TCL_OK;
}

// behaviour of this is such as the real Tcl_GetIntFromObj
template <typename Type>
int SwigInt_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) {
    int temp_val, return_val;
    return_val = Tcl_GetIntFromObj(interp, o, &temp_val);
    *val = (Type) temp_val;
    return return_val;
}

// behaviour of this is such as the real Tcl_GetDoubleFromObj
template <typename Type>
int SwigDouble_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) {
    int return_val;
    double temp_val;
    return_val = Tcl_GetDoubleFromObj(interp, o, &temp_val);
    *val = (Type) temp_val;
    return return_val;
}

%}

// exported class

namespace std {
    
    template<class T> class vector {
        %typemap(in) vector< T > (std::vector< T > *v) {
            Tcl_Obj **listobjv;
            int       nitems;
            int       i;
            T*        temp;

            if (SWIG_ConvertPtr($input, (void **) &v, \
                                $&1_descriptor, 0) == 0){
                $1 = *v;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, \
                                          &nitems, &listobjv) == TCL_ERROR)
                    return TCL_ERROR;
                $1 = std::vector< T >();
                for (i = 0; i < nitems; i++) {
                    if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp,
                                         $descriptor(T *),0)) != 0) {
                        char message[] = 
                            "list of " #T " expected";
                        Tcl_SetResult(interp, message, TCL_VOLATILE);
                        return TCL_ERROR;
                    }
                    $1.push_back(*temp);
                } 
            }
        }

        %typemap(in) const vector< T >* (std::vector< T > *v, std::vector< T > w),
                     const vector< T >& (std::vector< T > *v, std::vector< T > w) {
            Tcl_Obj **listobjv;
            int       nitems;
            int       i;
            T*        temp;

            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $&1_descriptor, 0) == 0) {
                $1 = v;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    return TCL_ERROR;
                w = std::vector< T >();
                for (i = 0; i < nitems; i++) {
                    if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp,
                                         $descriptor(T *),0)) != 0) {
                        char message[] = 
                            "list of " #T " expected";
                        Tcl_SetResult(interp, message, TCL_VOLATILE);
                        return TCL_ERROR;
                    }
                    w.push_back(*temp);
                } 
                $1 = &w;
            }
        }

        %typemap(out) vector< T > {
            for (unsigned int i=0; i<$1.size(); i++) {
                T* ptr = new T((($1_type &)$1)[i]);
                Tcl_ListObjAppendElement(interp, $result, \
                                         SWIG_NewInstanceObj(ptr, 
                                                             $descriptor(T *), 
                                                             0));
            }
        }

        %typecheck(SWIG_TYPECHECK_VECTOR) vector< T > {
            Tcl_Obj **listobjv;
            int       nitems;
            T*        temp;
            std::vector< T > *v;
            
            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $&1_descriptor, 0) == 0) {
                /* wrapped vector */
                $1 = 1;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    $1 = 0;
                else
                    if (nitems == 0)
                        $1 = 1;
                //check the first value to see if it is of correct type
                    else if ((SWIG_ConvertPtr(listobjv[0],
                                              (void **) &temp, 
                                              $descriptor(T *),0)) != 0)
                        $1 = 0;
                    else
                        $1 = 1;
            }
        }
        
        %typecheck(SWIG_TYPECHECK_VECTOR) const vector< T >&,
                                          const vector< T >* {
            Tcl_Obj **listobjv;
            int       nitems;
            T*         temp;
            std::vector< T > *v;

            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $1_descriptor, 0) == 0){
                /* wrapped vector */
                $1 = 1;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    $1 = 0;
                else
                    if (nitems == 0)
                        $1 = 1;
                //check the first value to see if it is of correct type
                    else if ((SWIG_ConvertPtr(listobjv[0],
                                              (void **) &temp,
                                              $descriptor(T *),0)) != 0)
                        $1 = 0;
                    else
                        $1 = 1;
            }
        }
      
      public:
        vector(unsigned int size = 0);
        vector(unsigned int size, const T& value);
        vector(const vector< T > &);

        unsigned int size() const;
        bool empty() const;
        void clear();
        %rename(push) push_back;
        void push_back(const T& x);
        %extend {
            T pop() throw (std::out_of_range) {
                if (self->size() == 0)
                    throw std::out_of_range("pop from empty vector");
                T x = self->back();
                self->pop_back();
                return x;
            }
            T& get(int i) throw (std::out_of_range) {
                int size = int(self->size());
                if (i<0) i += size;
                if (i>=0 && i<size)
                    return (*self)[i];
                else
                    throw std::out_of_range("vector index out of range");
            }
            void set(int i, const T& x) throw (std::out_of_range) {
                int size = int(self->size());
                if (i<0) i+= size;
                if (i>=0 && i<size)
                    (*self)[i] = x;
                else
                    throw std::out_of_range("vector index out of range");
            }
        }
    };


    // specializations for built-ins

    %define specialize_std_vector(T, CONVERT_FROM, CONVERT_TO)
    template<> class vector< T > {

        %typemap(in) vector< T > (std::vector< T > *v){
            Tcl_Obj **listobjv;
            int       nitems;
            int       i;
            T         temp;

            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $&1_descriptor, 0) == 0) {
                $1 = *v;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    return TCL_ERROR;					      
                $1 = std::vector< T >();
                for (i = 0; i < nitems; i++) {
                    if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR)
                        return TCL_ERROR;
                    $1.push_back(temp);
                } 
            }
        }
      
        %typemap(in) const vector< T >& (std::vector< T > *v,std::vector< T > w),
                     const vector< T >* (std::vector< T > *v,std::vector< T > w) {
            Tcl_Obj **listobjv;
            int       nitems;
            int       i;
            T         temp;

            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $1_descriptor, 0) == 0) {
                $1 = v;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    return TCL_ERROR;
                w = std::vector< T >();
                for (i = 0; i < nitems; i++) {
                    if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR)
                        return TCL_ERROR;
                    w.push_back(temp);
                } 
                $1 = &w;
            }
        }

        %typemap(out) vector< T > {
            for (unsigned int i=0; i<$1.size(); i++) {
                Tcl_ListObjAppendElement(interp, $result, \
                                         CONVERT_TO((($1_type &)$1)[i]));
            }
        }
       
        %typecheck(SWIG_TYPECHECK_VECTOR) vector< T > {
            Tcl_Obj **listobjv;
            int       nitems;
            T         temp;
            std::vector< T > *v;

            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $&1_descriptor, 0) == 0){
                /* wrapped vector */
                $1 = 1;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    $1 = 0;
                else
                    if (nitems == 0)
                        $1 = 1;
                //check the first value to see if it is of correct type
                if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
                    $1 = 0;
                else
                    $1 = 1;
            }
        }      

        %typecheck(SWIG_TYPECHECK_VECTOR) const vector< T >&,
	                                      const vector< T >*{
            Tcl_Obj **listobjv;
            int       nitems;
            T         temp;
            std::vector< T > *v;

            if(SWIG_ConvertPtr($input, (void **) &v, \
                               $1_descriptor, 0) == 0){
                /* wrapped vector */
                $1 = 1;
            } else {
                // It isn't a vector< T > so it should be a list of T's
                if(Tcl_ListObjGetElements(interp, $input, 
                                          &nitems, &listobjv) == TCL_ERROR)
                    $1 = 0;
                else
                    if (nitems == 0)
                        $1 = 1;
                //check the first value to see if it is of correct type
                if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
                    $1 = 0;
                else
                    $1 = 1;
            }
        }
        
      public:
        vector(unsigned int size = 0);
        vector(unsigned int size, const T& value);
        vector(const vector< T > &);

        unsigned int size() const;
        bool empty() const;
        void clear();
        %rename(push) push_back;
        void push_back(T x);
        %extend {
            T pop() throw (std::out_of_range) {
                if (self->size() == 0)
                    throw std::out_of_range("pop from empty vector");
                T x = self->back();
                self->pop_back();
                return x;
            }
            T get(int i) throw (std::out_of_range) {
                int size = int(self->size());
                if (i<0) i += size;
                if (i>=0 && i<size)
                    return (*self)[i];
                else
                    throw std::out_of_range("vector index out of range");
            }
            void set(int i, T x) throw (std::out_of_range) {
                int size = int(self->size());
                if (i<0) i+= size;
                if (i>=0 && i<size)
                    (*self)[i] = x;
                else
                    throw std::out_of_range("vector index out of range");
            }
        }
    };
    %enddef

    specialize_std_vector(bool, Tcl_GetBoolFromObj, Tcl_NewBooleanObj);
    specialize_std_vector(char, SwigInt_As<char>,Tcl_NewIntObj);
    specialize_std_vector(int, Tcl_GetIntFromObj,Tcl_NewIntObj);
    specialize_std_vector(short, SwigInt_As<short>, Tcl_NewIntObj);
    specialize_std_vector(long, SwigInt_As<long>, Tcl_NewIntObj);
    specialize_std_vector(unsigned char, 
                          SwigInt_As<unsigned char>, Tcl_NewIntObj);
    specialize_std_vector(unsigned int, 
                          SwigInt_As<unsigned int>, Tcl_NewIntObj);
    specialize_std_vector(unsigned short, 
                          SwigInt_As<unsigned short>, Tcl_NewIntObj);
    specialize_std_vector(unsigned long, 
                          SwigInt_As<unsigned long>, Tcl_NewIntObj);
    specialize_std_vector(double, Tcl_GetDoubleFromObj, Tcl_NewDoubleObj);
    specialize_std_vector(float, SwigDouble_As<float>, Tcl_NewDoubleObj);
    specialize_std_vector(std::string, 
                          SwigString_AsString, SwigString_FromString);

}


