/// NewSpmVolume.h
/**
*/

#ifndef NEW_SPM_VOLUME_H_
#define NEW_SPM_VOLUME_H_

#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>

#include <wx/defs.h>
#include <wx/log.h>

#include "ByteSwap.h"
#include "StringConvert.h"
#include "Globals.h"
#include "Volume.h"
#include "BasicVolumeFormat.h"

namespace jcs {

struct NewSpmHeader:public Basic3DHeader {

	struct  header_key{
		wxInt32	sizeof_hdr;
		char	data_type[10];
		char	db_name[18];
		wxInt32	extents;
		wxInt16	session_error;
		char	regular;
		char	hkey_un0;
	} hk;

	struct image_dimension {
		wxInt16	dim[8];
		wxInt16	unused8;
		wxInt16	unused9; 
		wxInt16	unused10;
		wxInt16	unused11;
		wxInt16	unused12;
		wxInt16	unused13;
		wxInt16	unused14;
		wxInt16	datatype;
		wxInt16	bitpix;
		wxInt16	dim_un0;
		float	pixdim[8];
		float	vox_offset;
		float	scale;				// funused1
		float	intercept;	// funused2
		float	funused3;
		float	cal_max;
		float	cal_min;
		float	compressed;
		float	verified;
		wxInt32	glmax, glmin;
	} dime;

	struct data_history {
		char	descrip[80];
		char	aux_file[24];
		char	orient;
		wxInt16	origin[5];
		char	generated[10];
		char	scannum[10];
		char	patient_id[10];
		char	exp_date[10];
		char	exp_time[10];
		char	hist_un0[3];
		wxInt32	views;
		wxInt32	vols_added;
		wxInt32	start_field;
		wxInt32	field_skip;
		wxInt32	omax, omin;
		wxInt32	smax, smin;
	} hist;

	virtual void SetNumberOfSlices(int slices) { dime.dim[3] = slices; }
	virtual void SetSliceSpacing(double spacing) 
		{ dime.pixdim[3] = static_cast<float>(spacing); }
	virtual int GetNumberOfSlices() { return dime.dim[3]; }

	void InitHeader();

};

class NewSpmVolume: public BasicVolumeFormat {

public :

	NewSpmVolume(const char* filename, 
		const char* header_extension,
		const char* raw_extension);

	~NewSpmVolume();
	
	NewSpmHeader GetHeader()						{ return mHeader; } 

	void WriteHeader(Basic3DHeader* header); 

	void ViewHeader();

protected:


private :

	std::fstream mMatFile;
	
	NewSpmHeader mHeader;
	
	enum aEndianType { aLITTLE_ENDIAN, aBIG_ENDIAN } ;
	aEndianType mByteOrder;

	void mInitHeader()	{ mHeader.InitHeader(); }

	int  mOpenMatFile(std::ios::openmode mode);
	void mCloseMatFile()	{ mMatFile.close(); }


	int  mReadHeaderFile();
	int  mWriteHeaderFile();


};

}

#endif
