%module channelflow
%include <std_complex.i>
%include "std_string.i"
%include "typemaps.i"

typedef double Real;
typedef std::complex<double> Complex;

%typemap(out) double&{
  $result = PyFloat_FromDouble(*$1);
}

%apply int { fieldstate };


%{

#include "channelflow/mathdefs.h"
#include "channelflow/vector.h"
#include "channelflow/flowfield.h"
#include "channelflow/diffops.h"
#include "channelflow/dns.h"
#include "channelflow/symmetry.h"
#include "channelflow/chebyshev.h"

using namespace channelflow;

%}



%include "channelflow/flowfield.h"
%include "channelflow/vector.h"
%include "channelflow/diffops.h"
%include "channelflow/dns.h"
%include "channelflow/symmetry.h"
%include "channelflow/chebyshev.h"
%include "channelflow/mathdefs.h"

%extend channelflow::FlowField {
	FlowField __add__(const FlowField &other) {
		FlowField v = *$self;
		v += other;
		return v; 
	}

	FlowField __sub__(const FlowField &other) {
		FlowField v = *$self;
		v -= other;
		return v;
	}
	
	void setRealHelper(int nx, int ny, int nz, int nd, Real valu) {
	   (*$self)(nx,ny,nz,nd) = valu;
	}
	
	void setComplexHelper(int nx, int ny, int nz, int nd, Complex valu) {
	   $self->cmplx(nx,ny,nz,nd) = valu;
	}
	
	Real getRealHelper(int nx, int ny, int nz, int nd) {
	 return (*$self)(nx,ny,nz,nd);
        }
	
	Complex getComplexHelper(int nx, int ny, int nz, int nd) {
	 return $self->cmplx(nx,ny,nz,nd);
        }
	
	bool isXZPhysical()
	{
	   return $self->xzstate() == Physical;
	}
	
	%pythoncode %{
	 def __call__(self,*args):
	   
	   if self.isXZPhysical():
	     return self.getRealHelper(*args)
	   else:
	     return self.getComplexHelper(*args)

	 def __getitem__(self, key):
	   	   
	   if (type(key) != tuple) or (len(key) != self.Nd() + 1):
	     raise
	   
	   if self.xzstate == Spectral:
	     return self.cmplx(*key)
	   else:
	     return self(*key)
	   
	 def __setitem__(self,key,value):
	   
	   if(self.xzstate() == Physical):
	     if (type(value) != float) and (type(value) != int):
	       print "Wrong type of value"
	     if (type(key) != tuple) or (len(key) != self.Nd() + 1):
	       print "Wrong number of arguments"

	     self.setRealHelper(*(key + (value,)))
	   else:
	     if(type(value) != complex):
	       print "Wrong type of value"
	     if (type(key) != tuple) or (len(key) != self.Nd() + 1):
	       print "Wrong number of arguments"
	     
	     self.setComplexHelper(*(key + (value,)))
	%}

/*	FlowField __getitem__(
	
	%pythoncode %{
	import numpy as n
	
	def __getitem__(self,arg):
	  if(len(arg) != 4):
	    raise IndexError("4 arguments expected")
	  for i = range(0,4):
	    if(type(arg[i]) == int):
	      arg[i] == slice(arg[i])
	    else if(type(arg[i] != slice):
	      raise TypeError("Argument should be either ints or slices")
	  
	  z = n.zeros(
	}*/
}
using namespace channelflow;