import NetCDF
import NetCDF: NcDim,NcVar
"""
This function save a DataCube object `d` generated by genDataCube to a NetCDF file `filename` in the directory `savedir`. The resulting NetCDF will have 3
variables, `datacube`, which is the actual multivariate dataset to be analysed, `components` will store the independent components used
to generate the cube and `events` will contain a map of events that should be detected by the algorithm. All settings will also be written
 as to the NetCDF file as attributes.
"""
function save_cube(d::DataCube, savedir = joinpath(Pkg.dir(),"SurrogateCube","data"),filename="")
	# Test if output directory exists
	isdir(savedir) || mkdir(savedir)
	# Generate new file name if none is given
	if filename==""
		i=1
		while isfile(joinpath(savedir,"file$(i).nc"))
			i=i+1
		end
		filename = "file$(i).nc"
	else
		isfile(joinpath(savedir,filename)) && rm(joinpath(savedir,filename))
	end
	fullname=joinpath(savedir,filename)
	# Now create essential variables
	Ntime,Nlat,Nlon,Nvar = size(d.variables)
	Ncomp = size(d.components,4)

	#Create variables
	#First define variable attributes
	varatts = Dict()
	compatts= Dict()
	objectToAtt(varatts,d.varnoise,"VarNoise")
	objectToAtt(compatts,d.compnoise,"CompNoise")
	objectToAtt(compatts,d.baselines,"Baseline")
	objectToAtt(compatts,d.events,"Event")

	dvar = NcDim("variable", Nvar)
	dcomp= NcDim("component", Ncomp)
	dlon = NcDim("longitude", Nlon)
	dlat = NcDim("latitude", Nlat)
	dtim = NcDim("time", Ntime)

	vcube = NcVar("datacube",[dtim,dlat,dlon,dvar],atts=varatts)
	vcomp = NcVar("components",[dtim,dlat,dlon,dcomp],atts=compatts)
	veven = NcVar("events",[dtim,dlat,dlon,dcomp])

	nc = NetCDF.create(fullname,NcVar[vcube,vcomp,veven])

	NetCDF.putvar(nc,"datacube",d.variables)
	NetCDF.putvar(nc,"components",d.components)
	NetCDF.putvar(nc,"events",d.eventmap)

	NetCDF.close(nc)
end
export save_cube

function objectToAtt(atts::Dict,t,prestring)

	T=string(typeof(t))
	n=fieldnames(t)
	atts[prestring]=T
	for i=1:length(n)
		atts[@sprintf("%s_%s",prestring,string(n[i]))]=t.(n[i])
	end
end

# Define a special function for Trend Events
function objectToAtt(atts::Dict,t::TrendEvent,prestring)

	T=string(typeof(t))
	n=fieldnames(t.ev)
	atts[prestring]=T
	for i=1:length(n)
		atts[@sprintf("%s_%s",prestring,string(n[i]))]=t.ev.(n[i])
	end
end

function objectToAtt(atts::Dict,t::Vector,prestring)

	for i=1:length(t)
		objectToAtt(atts,t[i],@sprintf("%s_%d",prestring,i))
	end
end
