#include <iostream.h>
#include <string.h>

class Molecule
{
	private:
		double hasMass ;
		int numberOfAtoms ;
		char* symbol ;
		char* nme ;

	public:
		Molecule()
		{
			nme = "" ;
			hasMass = 0 ;
			numberOfAtoms = 0 ;
			symbol = "" ;
		}
		void setMolecule(double m, int number, char* s)
		{
			hasMass = m ;
			numberOfAtoms = number ;
			symbol = s ;
		}
		void mass()
		{
			cout << hasMass << endl ;
		}
		int getNumberOfAtoms()
		{
			return (numberOfAtoms) ;
		}
		void chemicalSymbol()
		{
			cout << symbol << endl ;
		}
		void setName(char* n)
		{
			nme = n ;
		}
		void name() 
		{
			cout << nme << endl ;
		}
} ;

class MaterialObject
{
	private:
		char* nme ;
		bool hasSpontaneousMovement ;
		
	public:
		MaterialObject(char* n) 
		{
			nme = n ;
			hasSpontaneousMovement = false ;
		}
		void name()
		{
			cout << nme << endl ;
		}
		void setSpontaneousMovement(bool setTo)
		{
			hasSpontaneousMovement = setTo ;
		}
		void spontaneousMovement()
		{
		if (hasSpontaneousMovement == 0)
			cout << "False" << endl ;
		else
			cout << "True" << endl ;
		}
		char* getName()
		{
			return (nme) ;
		}
} ;		

class Animal : public MaterialObject
{
	private:
		double weight ;
		double topSpeedIs ;
		int noOfLegs ;
		char* voice ;
		bool sex ;
		bool liveYoung ;

	public:
		Animal(char* n, double w, double t, int l, char s) : MaterialObject(n)
		{
			weight = w ;
			topSpeedIs = t ;
			noOfLegs = l ;
			voice = "" ;
			setSpontaneousMovement(true) ;
			if(s == 'm')
				sex = 0 ;
			else sex = 1 ;
			liveYoung = false ;
		}
		void setLegs(int l)
		{
			noOfLegs = l ;
		}
		void legs()
		{
			cout << noOfLegs << endl ;
		}
		void setTopSpeed(double l)
		{
			topSpeedIs = l ;
		}
		void speak()
		{
			cout << voice << endl ;
		}
		void topSpeed()
		{
			cout << topSpeedIs << endl ;
		}
		void setVoice(char* v)
		{
			voice = v ;
		}
		void hasSex() 
		{
			if(sex == 0)
				cout << "Male" << endl ;
			else
				cout << "Female" << endl ;
		}
		void setLiveYoung(bool y)
		{
			liveYoung = y ;
		}
		void hasLiveYoung()
		{
			if (liveYoung == 0)
				cout << "False" << endl ;
			else
				cout << "True" << endl ;
		}
} ;

class Plant : public MaterialObject
{
	private:
		bool live ;

	public:
		Plant(char* n) : MaterialObject(n)
		{
			live = true ;
		}
		void alive()
		{
			if (live == 0)
				cout << "False" << endl ;
			else
				cout << "True" << endl ;
		}
		void kill()
		{
			live = false ;
		}
} ;

class Mineral : public MaterialObject
{
	private:
		Molecule molecule ;
	
	public:
		Mineral(char* n) : MaterialObject(n) {}
		void setMolecule(double m, int number, char* s)
		{
			molecule.setMolecule(m, number, s) ;
		}
} ;

class Mammal : public Animal
{
	public:
		Mammal(char* n, double m, double t, int l, char s) : Animal(n, m, t, l, s)
		{
			setLiveYoung(true) ;
		}
} ;

class Quadruped : public Mammal
{
	public:
		Quadruped(char* n, double m, double t, char s) : Mammal(n, m, t, 4, s) {}
} ;

class Biped : public Mammal
{
	public:
		Biped(char* n, double m, double t, char s) : Mammal(n, m, t, 2, s) {}
} ;

class Human : public Biped
{
	public:
		Human(char* n, double m, double t, char s) : Biped(n, m, t, s) {}
} ;

class CouchPotato : public Human
{
	public:
		CouchPotato(char* n, double m, double t, char s) : Human(n, m, t, s)
		{
			setSpontaneousMovement(false) ;
		}
} ;

class Student : public Human
{
	public:
		Student(char* n, double m, double t, char s) : Human(n, m, t, s) {}
} ;

class Sprinter : public Human
{
	public:
		Sprinter(char* n, double m, double t, char s) : Human(n, m, t, s)
		{
			setTopSpeed(1000) ;
		}
} ;

class Dog : public Quadruped
{
	public:
		Dog(char* n, double m, double t, char s) : Quadruped(n, m, t, s)
		{
			setVoice("Whoof, whoof") ;
		}
} ;

class Cat : public Quadruped
{
	public:
		Cat(char* n, double m, double t, char s) : Quadruped(n, m, t, s)
		{
			setVoice("Meow") ;
		}
} ;

class Tree : public Plant
{
	private:
		double hasHeight ;
		double weight ;
		bool isDeciduous ;

	public:
		Tree(char* n, double h, double w) : Plant(n)
		{
			hasHeight = h ;
			weight = w ;
			isDeciduous = true ;
		}
		void height()
		{
			cout << hasHeight << endl ;
		}
		void setHeight(double h)
		{
			hasHeight = h ;
		}
		double getWeight()
		{
			return (weight) ;
		}
		void setWeight(double w)
		{
			weight = w ;
		}
		void setIsDeciduous(bool to)
		{
			isDeciduous = to ;
		}
		void deciduous()
		{
			if (isDeciduous == 0)
				cout << "False" << endl ;
			else
				cout << "True" << endl ;
		}
} ;

class Deciduous : public Tree
{
	public:
		Deciduous(char* n, double h, double w) : Tree(n, h, w) {}
} ;

class Evergreen : public Tree
{
	public:
		Evergreen(char* n, double h, double w) : Tree(n, h, w)
		{
			setIsDeciduous(false) ;
		}
} ;

class Pine : public Evergreen
{
	public:
		Pine(double h, double w) : Evergreen("Pine", h, w) {}
} ;

class Metal : public Mineral
{
	public:
		Metal(char* n) : Mineral(n) {}
} ;

class Magnesium : public Metal
{
	public:
		Magnesium(char* n) : Metal(n)
		{
			setMolecule(24.305, 1, "Mg") ;
		}
} ;

class Liquid : public Mineral
{
	public:
		Liquid(char* n) : Mineral(n) {}
} ;

class Water : public Liquid
{
	public:
		Water() : Liquid("Water")
		{
			setMolecule(18.01528, 3, "H2O") ;
		}
} ;

class Gas : public Mineral
{
	private:
		char* fam ;

	public:
		Gas(char* n) : Mineral(n) {}
		void setFamily(char* f)
		{
			fam = f ;
		}
		void family()
		{
			cout << fam ;
		}
} ;

class Krypton : public Gas
{
	public:
		Krypton() : Gas("Krypton")
		{
			setMolecule(83.8, 1, "Kr") ;
			setFamily("Noble Gas") ;
		}
} ;

class Hydrogen : public Gas
{
	public:
		Hydrogen() : Gas("Hydrogen")
		{
			setMolecule(1.00794, 1, "H") ;
			setFamily("Non-metal") ;
		}
} ;

class Chlorine : public Gas
{
	public:
		Chlorine() : Gas("Chlorine")
		{
			setMolecule(35.4527, 1, "Cl") ;
			setFamily("Halogen") ;
		}
} ;

class Beaker : public Mineral
{
	private:
		int atoms ;

	public:
		Beaker(char* n) : Mineral(n)
		{
			atoms = 0 ;
		}
		void add() 
		{
			++atoms; 
		}
		void remove()
		{
			--atoms ;
		}
} ;

class BeakerHolder
{
	private:
		class List
		{
			public:
				Beaker* value ;
				List* next ;
		} ;

		List* contents ;

	public:
		BeakerHolder()
		{
			contents = NULL ;
		}
		void hold(Beaker* b)
		{
			List* newElement ;
			newElement = new List ;
			newElement->value = b ;
			newElement->next = contents ;
			contents = newElement ;
		}
		void giveBack()
		{
			List* temp = contents ;
			contents = contents->next ;
			delete temp ;
		}
		Beaker& find(Beaker& b)
		{
/*		
		***** This is not working *****
  	  
		List* search ;
			search = contents ;
			while(search != NULL)
			{
				if((search->value).getName == b.getName())
					return (search->value) ;
				search = search->next ;
			}
*/		}
} ;

			
int main() 
{

	Dog myDog("Rex", 18, 10, 'm') ;
	Cat myCat("Felixia", 5, 8, 'f') ;
	Krypton k ;
	Hydrogen h ;
	Beaker b("myBeaker") ;
	BeakerHolder mine ;
	Sprinter lynford("Lynford", 75, 25, 'm') ;
	lynford.legs() ;
	myCat.legs() ;
	k.family() ;

	return (0) ;
}

