#include "Molecule.h"



//////////////////////////////////////////////////////////////////////
// Constructors for the Molecule object
//

Molecule :: Molecule(){

	initialize();
}



Molecule :: Molecule(Point & p){

	// Molecule with specified position
	pos.x = p.x;	pos.y = p.y;	pos.z = p.z;
	
	initialize();
}

//////////////////////////////////////////////////////////////////////
// Destructor for the Molecule object
//
Molecule::~Molecule(){

	// Destructing the Molecule
	printf("Deleting Molecule\n");
}



void Molecule::initialize(){
	// Environment Manager
	lEnv = LatticeEnvironment :: getLatticeEnv();
	
	// Default mobility
	mobility = 1.0;
	
	// Default Diffusibility
	diffusible = true;
	
	// Molecule initially non-active
	activated = false;
}



//////////////////////////////////////////////////////////////////////
// Print the current location of the molecule
//
string Molecule::position(){

	// String representation of the current position of the molecule
	// in the Lattice
	return "(" + floatToStr(pos.x) + ", " + 
			floatToStr(pos.y) + ", " + 
			floatToStr(pos.z) + ")";
}

//////////////////////////////////////////////////////////////////////
// Molecule translates/moves by the specified vector
//
void Molecule::translate(Vector3D & v){
	
	// Apply translation
	pos.x += v.x; pos.y += v.y; pos.z += v.z;
}



//////////////////////////////////////////////////////////////////////
// Set molecule's Diffusibility
//
void Molecule::setDiffusible(bool diff){
	diffusible = diff;
}



//////////////////////////////////////////////////////////////////////
// Get molecule's Diffusibility
//
bool Molecule::isDiffusible(){
	return diffusible;
}



//////////////////////////////////////////////////////////////////////
// Set molecule to Position
//
void Molecule::setPosition(Point & p){
	pos.x = p.x; pos.y = p.y; pos.z = p.z;
}

//////////////////////////////////////////////////////////////////////
// Get the molecule's mobility
//
float Molecule::getMobility(){

	return mobility;
}



//////////////////////////////////////////////////////////////////////
// Is the molecule activated?
//
bool Molecule::isActivated(){

	// return activation status of the molecule
	return activated;
}



//////////////////////////////////////////////////////////////////////
// Activate the molecule
//
void Molecule::activate(){

	// change status of molecule to active
	activated = true;
}



//////////////////////////////////////////////////////////////////////
// Activate the activatee molecule
//
void Molecule::activates(Molecule * activatee){
	// change status of activatee to active
	activatee->activate();
}



//////////////////////////////////////////////////////////////////////
// De-activate the molecule
//
void Molecule::deactivate(){
	// change status of molecule to non-active
	activated = false;
}



//////////////////////////////////////////////////////////////////////
// Is the molecule activated?
//
bool Molecule::isActivated(Molecule * activator){
	return activated;
	
}



//////////////////////////////////////////////////////////////////////
// Get Molecule type
//
moltype Molecule::getType(){}



//////////////////////////////////////////////////////////////////////
// Get Molecule type name
//
string Molecule::getTypeName(){}



//////////////////////////////////////////////////////////////////////
// Determine if a molecule is near
//
bool Molecule::isNear(Molecule * m){

	Vector3D diff;
	// Get relative distances of the 2 molecules	
	diff.setDiff(pos, m->pos);

	float dist = diff.magnitude();
	
	float threshold = 1.5 * resolution;
	
	// Molecules are not within the attraction distance
	if(dist > threshold) return false;
	
	float pActivate = (pow(threshold,2) - pow(dist,2)) / pow(threshold,2);
	
	// Return whether their distances is less than a magnitude of 1
	return prob(pActivate);
}

// Movement for the molecule
void Molecule::move(){}

//////////////////////////////////////////////////////////////////////
