import os
import Magics
import numpy

class Context(object):
	def __init__(self):
		self.tmp = []
		pass

global context
context  = Context()

class Action(object):
	def __init__(self, verb, action, args):
		self.verb = verb
		self.action = action
		self.args = args

	def __repr__(self):
		x = ""
		for key in self.args.keys():
			x = x + " %s = '%s'\n" % (key, self.args[key])
		return x

	def inspect(self):
		print self


	def tofortran(self):
		print self


	def execute(self):
		for key in self.args.keys():
			if isinstance(self.args[key], str):
				if key == 'odb_data':
					Magics.setc('odb_filename', self.args[key])
				else:
					Magics.setc(key, self.args[key])
			elif isinstance(self.args[key], int):
				Magics.seti(key, self.args[key])
			elif isinstance(self.args[key], float):
				Magics.setr(key, self.args[key])
			elif isinstance(self.args[key], list) :
				if isinstance(self.args[key][0], str):
				   Magics.set1c(key, self.args[key])
				elif isinstance(self.args[key][0], int):
				   Magics.set1i(key, numpy.array(self.args[key], dtype='i'))
				elif isinstance(self.args[key][0], float):
				   Magics.set1r(key, numpy.array(self.args[key]))
			elif isinstance(self.args[key], numpy.ndarray) :
				type = self.args[key].dtype
				dim  = len(self.args[key].shape)
				if isinstance(self.args[key][0], int):
					if (dim == 2) :
						Magics.set2i(key, self.args[key].copy())
					else :
						Magics.set1i(key, self.args[key].copy())
				elif ( type == 'float64' or type == 'float32') :
					if (dim == 2) :
						Magics.set2r(key, self.args[key].copy())
					else :
						Magics.set1r(key, self.args[key].copy())
				else :
					print "type???->", key

			else:
				self.args[key].execute(key)

		if self.action != None :
			if self.action != Magics.new_page :
				self.action()
				if self.action != Magics.obs :
					for key in self.args.keys():
						Magics.reset(key)
			else:
				self.action("page")

def make_action(verb, action):
	def f(_m = None,**kw):
		args = {}
		if _m is not None: 
			args.update(_m)
		args.update(kw)
		return Action(verb, action, args)
	return f

mcoast = make_action("mcoast", Magics.coast)
pcoast = make_action("pcoast", Magics.coast)
maxis = make_action("maxis", Magics.axis)
paxis = make_action("paxis", Magics.axis)
mcont = make_action("mcont", Magics.cont)
pcont = make_action("pcont", Magics.cont)
msymb = make_action("msymb", Magics.symb)
psymb = make_action("psymb", Magics.symb)
mtaylor = make_action("mtaylor", Magics.taylor)
mgeo = make_action("mgeo", Magics.geo)
pgeo = make_action("pgeo", Magics.geo)
pgrib = make_action("pgrib", Magics.grib)
mgrib = make_action("mgrib", Magics.grib)
pmapgen = make_action("pmapgen", Magics.mapgen)
mmapgen = make_action("mmapgen", Magics.mapgen)
pnetcdf = make_action("pnetcdf", Magics.netcdf)
mnetcdf = make_action("mnetcdf", Magics.netcdf)
odb_geopoints = make_action("odb_geopoints", Magics.odb)
odb_geovectors = make_action("odb_geovectors", Magics.odb)
pmap = make_action("pmap", None)
mmap = make_action("mmap", None)
plegend = make_action("plegend", Magics.legend)
mlegend = make_action("mlegend", Magics.legend)
ptext = make_action("mtext", Magics.text)
mtext = make_action("ptext", Magics.text)
output = make_action("output", None)
pwind = make_action("pwind", Magics.wind)
mwind = make_action("mwind", Magics.wind)
pline = make_action("pline", Magics.line)
mline = make_action("mline", Magics.line)
pgraph = make_action("pgraph", Magics.graph)
mgraph = make_action("mgraph", Magics.graph)
pboxplot = make_action("pboxplot", Magics.boxplot)
mboxplot = make_action("mboxplot", Magics.boxplot)
pobs = make_action("pobs", Magics.obs)
mobs = make_action("mobs", Magics.obs)
page = make_action("page", Magics.new_page)



def examine(*args):
	for n in args:
		try :
			n.inspect()
		except:
			break


def plot(*args):
	Magics.init()
	for n in args:
		if isinstance(n, list):
			for nn in n:
				nn.execute()
		else:
				n.execute()
	
	#Collect the drivers!
	Magics.finalize()
	for f in context.tmp:
		if os.path.exists(f):
			os.remove(f)


def tofortran(*args):
	print "Magics.init()"
	for n in args:
		n.tofortran()
	print "Magics.finalize()"


class  odb_filter(object):
	def __init__(self, _m = None,**kw):
		args = {}
		self.verb = "odbfilter"
		if _m is not None:
			args.update(_m)
		self.args = args
	def execute(self, key):
		file = "data%d" % numpy.random.randint(1,1000)
		odb = "%s.odb" % file 
		context.tmp.append(odb)
		cmd = "odbsql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -f newodb -o " + odb
		print cmd 
		if (os.system(cmd)) :
			print "Error in filtering ODB data... Aborting"
			os.abort();
		Magics.setc('odb_filename', odb)
	def inspect(self):
		cmd = "odbsql -q \"" + self.args["query"] + "\" -i " + self.args["path"] + " -o data.ascii"
		if (os.system(cmd)) :
			print "Error in filtering ODB data... Aborting"
			os.abort();
		cmd =  os.environ['ODB_REPORTER'] + " %s" % "data.ascii"
		if (os.system(cmd)) :
			print "Error in viewing ODB data... Aborting"
			os.abort();
