//##########################################################################
//#                                                                        #
//#                              CLOUDCOMPARE                              #
//#                                                                        #
//#  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; version 2 or later of the License.      #
//#                                                                        #
//#  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.                          #
//#                                                                        #
//#          COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI)             #
//#                                                                        #
//##########################################################################

#ifndef CC_SHAPEFILE_DBF_FIELDS_HEADER
#define CC_SHAPEFILE_DBF_FIELDS_HEADER

#ifdef CC_SHP_SUPPORT

//local
#include "qCC_io.h"

//CCCoreLib
#include <CCGeom.h>

//Qt
#include <QString>

//system
#include <vector>

//Shapelib
#include <shapefil.h>

//! Generic shapefile 'field'
/** Fields contain one value per record (i.e. primitive)
**/
class GenericDBFField
{
public:

	//! Default constructor
	GenericDBFField(QString name) : m_name(name) {}

	//! Returns field name
	const QString& name() const { return m_name; }

	//! Returns whehter the field is 3D or not
	virtual bool is3D() const  { return false; }

	//to be reimplemented by siblings
	virtual DBFFieldType type() const = 0;
	virtual int width() const = 0;
	virtual int decimal() const = 0;
	virtual bool save(DBFHandle handle, int fieldIndex) const { return false; } //1D version
	virtual bool save(DBFHandle handle, int xFieldIndex, int yFieldIndex, int zFieldIndex) const { return false; } //3D version

protected:

	//! Field name
	QString m_name;
};

//! Int-valued shapefile field
class QCC_IO_LIB_API IntegerDBFField : public GenericDBFField
{
public:

	//! Default constructor
	IntegerDBFField(QString name) : GenericDBFField(name) {}

	//inherited from GenericDBFField
	virtual DBFFieldType type() const { return FTInteger; }
	virtual int width() const { return 6; }
	virtual int decimal() const { return 0; }
	virtual bool save(DBFHandle handle, int fieldIndex) const;

	//! Field values
	std::vector<int> values;
};

//! Double-valued shapefile field
class QCC_IO_LIB_API DoubleDBFField : public GenericDBFField
{
public:

	//! Default constructor
	DoubleDBFField(QString name) : GenericDBFField(name) {}

	//inherited from GenericDBFField
	virtual DBFFieldType type() const { return FTDouble; }
	virtual int width() const { return 8; }
	virtual int decimal() const { return 8; }
	virtual bool save(DBFHandle handle, int fieldIndex) const;

	//! Field values
	std::vector<double> values;
};

//! Double-valued 3D shapefile field
class QCC_IO_LIB_API DoubleDBFField3D : public GenericDBFField
{
public:

	//! Default constructor
	DoubleDBFField3D(QString name) : GenericDBFField(name) {}
	virtual ~DoubleDBFField3D() {}

	//inherited from GenericDBFField
	virtual bool is3D() const  { return true; }
	virtual DBFFieldType type() const { return FTDouble; }
	virtual int width() const { return 8; }
	virtual int decimal() const { return 8; }
	virtual bool save(DBFHandle handle, int xFieldIndex, int yFieldIndex, int zFieldIndex) const;

	//! Field values
	std::vector<CCVector3d> values;
};

#endif //CC_SHP_SUPPORT

#endif //CC_SHAPEFILE_DBF_FIELDS_HEADER
