#ifndef MOLECULE_H
#define MOLECULE_H

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <math.h>
#include "Point.h"
#include "ParameterManager.h"
#include "RandomNG.h"
#include "definition.h"
#include "functionLib.h"
#include "RandomNG.h"
#include "LatticeEnvironment.h"
#include "Vector3D.h"

extern float resolution;
extern double TIMESCALE, SPACESCALE;

class Molecule{

	public:
	
		//////////////////////////////////////////////////////////////////////
		// Constructor and Destructor
		
		Molecule();
		Molecule(Point &);
		virtual ~Molecule();
		
		static vector <envtype> compatibleEnvList;

		//////////////////////////////////////////////////////////////////////
		// Operations on the Molecule
		
		// Position/Location of the Molecule
		Point pos;		
		
		// Get the activation status of the molecule
		bool isActivated();
		
		// Determine if the specified molecule is near
		bool isNear(Molecule *);
		
		// Get the diffusibility of the molecule
		bool isDiffusible();
		
		// Set the diffusibility of the molecule
		void setDiffusible(bool);
		
		// Set the activation status of the molecule
		void setActivationStatus(bool);
		
		// Deactivate the molecule
		void deactivate();
		
		// Get the string representation of the postion of the molecule
		string position();
		
		// set molecule to the specified position
		void setPosition(Point &);		

		// Translate the molecule by the specified (x,y,z) vector
		void translate(Vector3D &);

		// Get the mobility of the molecule
		float getMobility();
		
		
		//////////////////////////////////////////////////////////////////////
		// Virtual Methods
		
		// Set activation state of the molecule to true
		virtual void activate();
		
		// Activate the specified molecule
		virtual void activates(Molecule *);

		// Get the activation status of the molecule
		virtual bool isActivated(Molecule *);
		
		//////////////////////////////////////////////////////////////////////
		// Pure Virtual Operations
				
		// Movement for the molecule
		virtual void move() = 0;
		
		// Get the type name of the molecule
		virtual string getTypeName() = 0;
		
		// Get the group name of the molecule
		virtual string getGroupName() = 0;
		
		// Get the type of the molecule
		virtual moltype getType() = 0;
		
		// Get the Group of the molecule
		virtual int getGroup() = 0;

	protected:

		//////////////////////////////////////////////////////////////////////
		// Member variables
		
		// Environment Manager
		LatticeEnvironment * lEnv;
		
		// The mobility of the molecule
		float mobility;
		
		// diffusibility of the molecule
		bool diffusible;

		// The activation status of the molecule
		bool activated;
		
		// The degradation timer of a molecule if applicable
		int degradationTimer;
		
		void initialize();
}
;

#endif
