// 2011 © Bruno Chareyre <bruno.chareyre@grenoble-inp.fr>
// 2012 © Kneib Francois <francois.kneib@irstea.fr>
#pragma once
#include <pkg/dem/ScGeom.hpp>

namespace yade { // Cannot have #include directive inside.

class CylScGeom : public ScGeom {
public:
	/// Emulate a sphere whose position is the projection of sphere's center on cylinder sphere, and with motion linearly interpolated between nodes
	State fictiousState;
	// 		shared_ptr<Interaction> duplicate;

	virtual ~CylScGeom() {};
	// clang-format off
    YADE_CLASS_BASE_DOC_ATTRS_CTOR(CylScGeom,ScGeom,"Geometry of a cylinder-sphere contact.",
                                   ((bool,onNode,false,,"contact on node?"))
                                   ((int,isDuplicate,0,,"this flag is turned true (1) automatically if the contact is shared between two chained cylinders. A duplicated interaction will be skipped once by the constitutive law, so that only one contact at a time is effective. If isDuplicate=2, it means one of the two duplicates has no longer geometric interaction, and should be erased by the constitutive laws."))
                                   ((int,trueInt,-1,,"Defines the body id of the cylinder where the contact is real, when :yref:`CylScGeom::isDuplicate`>0."))
                                   ((Vector3r,start,Vector3r::Zero(),,"position of 1st node |yupdate|"))
                                   ((Vector3r,end,Vector3r::Zero(),,"position of 2nd node |yupdate|"))
                                   ((Body::id_t,id3,0,,"id of next chained cylinder |yupdate|"))
                                   ((Real,relPos,0,,"position of the contact on the cylinder (0: node-, 1:node+) |yupdate|")),
                                   createIndex(); /*ctor*/
                                  );
	// clang-format on
	REGISTER_CLASS_INDEX(CylScGeom, ScGeom);
};
REGISTER_SERIALIZABLE(CylScGeom);


class CylScGeom6D : public ScGeom6D {
public:
	virtual ~CylScGeom6D() {};
	void precomputeRotations(const State& rbp1, const State& rbp2, bool /*isNew*/, bool /*creep*/ = false) { initRotations(rbp1, rbp2); }
	void initRotations(const State& rbp1, const State& rbp2)
	{
		initialOrientation1 = rbp1.ori;
		initialOrientation2 = rbp2.ori;
		twist               = 0;
		bending             = Vector3r::Zero();
		twistCreep          = Quaternionr(1.0, 0.0, 0.0, 0.0);
	}
	State fictiousState;
	// clang-format off
    YADE_CLASS_BASE_DOC_ATTRS_INIT_CTOR_PY(CylScGeom6D,ScGeom6D,"Class representing :yref:`geometry<IGeom>` of two :yref:`bodies<Body>` in contact. The contact has 6 DOFs (normal, 2×shear, twist, 2xbending) and uses :yref:`ScGeom` incremental algorithm for updating shear.",
                                           ((bool,onNode,false,,"contact on node?"))
                                           ((int,isDuplicate,0,,"this flag is turned true (1) automatically if the contact is shared between two chained cylinders. A duplicated interaction will be skipped once by the constitutive law, so that only one contact at a time is effective. If isDuplicate=2, it means one of the two duplicates has no longer geometric interaction, and should be erased by the constitutive laws."))
                                           ((int,trueInt,-1,,"Defines the body id of the cylinder where the contact is real, when :yref:`CylScGeom::isDuplicate`>0."))
                                           ((Vector3r,start,Vector3r::Zero(),,"position of 1st node |yupdate|"))
                                           ((Vector3r,end,Vector3r::Zero(),,"position of 2nd node |yupdate|"))
                                           ((Body::id_t,id3,0,,"id of next chained cylinder |yupdate|"))
                                           ((Real,relPos,0,,"position of the contact on the cylinder (0: node-, 1:node+) |yupdate|")),
                                           /* extra initializers */,
                                           /* ctor */ createIndex();,
                                           /* py */
                                          );
	// clang-format on
	REGISTER_CLASS_INDEX(CylScGeom6D, ScGeom6D);
};
REGISTER_SERIALIZABLE(CylScGeom6D);

} // namespace yade
