#include "AdvModel.hh"
#include <gsl/gsl_math.h>
#include <utility>

#ifndef LIBMXML4
#include <mxml.h>
#else
#include <libmxml4/mxml.h>
#define MXML_DESCEND MXML_DESCEND_ALL
#endif

class AdvModelDistribution;

class AdvModelParticle
{
public:
	AdvModelParticle(AdvModel* model);
	virtual ~AdvModelParticle();

	virtual void MeanFormFactor( double q[3], Complex* retval );

	virtual gsl_function getMeanFormFactorFunc ();

        enum PARTICLETYPE {
            NONE                   =   1,
            SPHERE                 = 100,
            SPHERE_LAYER           = 101,
            ELLIPSOID_2            = 102,
            ELLIPSOID_3            = 103,
            PARALLELEPIPED         = 200,
            CYLINDER               = 300,
            CYLINDER_ELLIPTICAL    = 301,
            CYLINDER_HOLLOW        = 302,
            CYLINDER_THINROD       = 303,
            CYLINDER_THINDISK      = 304,
        };

        void SetFuncParam(mxml_node_t*);
protected:
        AdvModel* m_model;

	void deleteParams();

	std::vector<std::pair<std::string, AdvModelDistribution*> >  particleParams;
};


typedef struct 
{
	AdvModelParticle*  model;
	Complex         retval[2];
} particleArgs;
/*
class AdvModelParticleNone : public AdvModelParticle
{
public:
	AdvModelParticleNone(Model* model);
	~AdvModelParticleNone();

	void MeanFormFactor( double q[3], Complex* retval );

        gsl_function getMeanFormFactorFunc ();
};
*/
class AdvModelParticleSphere : public AdvModelParticle
{
public:
	AdvModelParticleSphere(AdvModel* model);
	~AdvModelParticleSphere();

	void MeanFormFactor( double q[3], Complex* retval );

        gsl_function getMeanFormFactorFunc ();

protected:
	double FF_Sphere_primitive ( double x );

private:
	Complex MeanFormFactor_primitive( double q, double R );
};

