/*
 *	voxelLoad.h - 3D voxel load header
 *	Copyright (C) 2015, D Haley 

 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.

 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.

 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VOXELLOAD_H
#define VOXELLOAD_H

#include "../filter.h"
#include "../../common/translation.h"
#include "filterCommon.h"

enum
{
	VOXELLOAD_FILE_READFAIL=1,
	VOXELLOAD_ERR_GENERIC,
	VOXELLOAD_ERRS_ENUM_END,
};

enum
{
	VOXEL_FILETYPE_VTK_ASCII,
	VOXEL_FILETYPE_RAW_FLOAT,
	VOXEL_FILETYPE_ENUM_END
};
//!Filter to place drawing objects to help annotate
// the 3D scene
class VoxelLoadFilter : public Filter
{
	private:
		//!Name of the file to load voxel data from
		string fileName;

		//Is the voxel field drawing enabled
		bool enabled;

		//!Upper and lower bounds for voxel storage
		Point3D pMin,pMax;

		//Storage for the voxel cache
		Voxels<float> voxelCache;

		bool overrideBounds;

		//!What is the current file type we want to load
		unsigned int curVoxelFileType;

		//!Visual appearance of voxel data
		VoxelAppearanceProperties voxAppearance;
	
		//!Bounds from last refresh
		BoundCube lastBounds;

	public:
		//!Constructor
		VoxelLoadFilter();

		//!Duplicate filter contents, excluding cache.
		Filter *cloneUncached() const;

		//!Apply filter to new data, updating cache as needed. Vector
		// of returned pointers must be deleted manually, first checking
		// ->cached.
		unsigned int refresh(const std::vector<const FilterStreamData *> &dataIn,
							std::vector<const FilterStreamData *> &dataOut,
							ProgressData &progress);
		//!Get (approx) number of bytes required for cache
		size_t numBytesForCache(size_t nObjects) const;

		//!return type ID
		unsigned int getType() const { return FILTER_TYPE_VOXEL_LOAD;}

		//!Return filter type as std::string
		std::string typeString() const { return std::string(TRANS("Voxel Load"));};

		//!Get the properties of the filter, in key-value form. First vector is for each output.
		void getProperties(FilterPropGroup &propertyList) const;

		//!Set the properties for the nth filter,
		//!needUpdate tells us if filter output changes due to property set
		bool setProperty( unsigned int key,
					const std::string &value, bool &needUpdate);


		void setPropFromBinding( const SelectionBinding &b) ;

		//!Get the human readable error string associated with a particular error code during refresh(...)
		std::string getSpecificErrString(unsigned int code) const;

		//!Dump state to output stream, using specified format
		/* Current supported formats are STATE_FORMAT_XML
		 */
		bool writeState(std::ostream &f, unsigned int format,
							unsigned int depth) const;

		//!Read state from XML  stream, using xml format
		/* Current supported formats are STATE_FORMAT_XML
		 */
		bool readState(xmlNodePtr& n, const std::string &packDir="");

		//!Get the bitmask encoded list of filterStreams that this filter blocks from propagation.
		// i.e. if this filterstream is passed to refresh, it is not emitted.
		// This MUST always be consistent with ::refresh for filters current state.
		unsigned int getRefreshBlockMask() const;

		//!Get the bitmask encoded list of filterstreams that this filter emits from ::refresh.
		// This MUST always be consistent with ::refresh for filters current state.
		unsigned int getRefreshEmitMask() const;

		//!Get the refresh's ignore mask - filter streams that will not be considered
		// as part of the computation
		unsigned int getRefreshUseMask() const;
		
		//Are we a pure data source  - i.e. can function with no input
		virtual bool isPureDataSource() const { return true;};
		
		//Can we be a useful filter, even if given no input specified by the Use mask?
		virtual bool isUsefulAsAppend() const { return true;}
		
		//Set the filename 	
		void setFilename(const char *name) { fileName = name;}
		//Set the filenaem 	
		void setFileMode(unsigned int mode) {ASSERT(mode < VOXEL_FILETYPE_ENUM_END);curVoxelFileType = mode;}
#ifdef DEBUG
		bool runUnitTests();
#endif
};


#endif
