module("Molecule");

test("Check Creation", function(){
	var mol = new Molecule();
	expect(3);
    equals(0, mol.atoms.length, 'Check empty atoms');
    equals(0, mol.bonds.length, 'Check empty bonds');
    equals(0, mol.rings.length, 'Check empty rings');
});

test("Check Get Center", function(){
	var mol = readMOL(thiophene);
	expect(2);
	var center = mol.getCenter();
	equals(0, center.x, 'Check center x');
	equals(0, center.y, 'Check center y');
});

test("Check Get Center3D", function(){
	var mol = readMOL(thiophene);
	var mol3D = readMOL(threed);
	expect(6);
	var center = mol.getCenter3D();
	equals(0, center.x, 'Check flat center x');
	equals(0, center.y, 'Check flat center y');
	equals(0, center.z, 'Check flat center z');
	center = mol3D.getCenter3D();
	equals(-3.6969999999999885, center.x, 'Check center x');
	equals(-154.017, center.y, 'Check center y');
	equals(26.551999999999992, center.z, 'Check center z');
});

test("Check Get Dimension", function(){
	var mol3D = readMOL(threed);
	expect(2);
	var dim = mol3D.getDimension();
	equals(300.826, dim.x, 'Check width');
	equals(322.178, dim.y, 'Check height');
});

test("Check Find Lones", function(){
	var mol = readMOL(thiophene);
	mol.check();
	expect(5);
	for(var i = 0; i<mol.atoms.length; i++){
		ok(!mol.atoms[i].isLone, 'Check not lone');
	}
});

test("Check Find Rings", function(){
	var mol = readMOL(thiophene);
	mol.check();
	expect(6);
	equals(1, mol.rings.length, 'Check ring found');
	for(var i = 0; i<mol.bonds.length; i++){
		equals(mol.rings[0], mol.bonds[i].ring, 'Check ring owns bond');
	}
});

test("Check Doesn't Find Rings if Disabled", function(){
	var mol = readMOL(thiophene);
	mol.findRings = false;
	mol.check();
	expect(6);
	equals(0, mol.rings.length, 'Check ring not found');
	for(var i = 0; i<mol.bonds.length; i++){
		equals(null, mol.bonds[i].ring, 'Check bond owns no ring');
	}
});

test("Check Atom Z Sort", function(){
	var mol = readMOL(threed);
	mol.check();
	expect(mol.atoms.length-1);
	for(var i = 1; i<mol.atoms.length; i++){
		ok(mol.atoms[i].z>mol.atoms[i-1].z, 'Check greater than previous');
	}
});

test("Check Bond Z Sort", function(){
	var mol = readMOL(threed);
	mol.check();
	expect(mol.bonds.length-1);
	for(var i = 1; i<mol.bonds.length; i++){
		ok((mol.bonds[i].a1.z+mol.bonds[i].a2.z)>(mol.bonds[i-1].a1.z+mol.bonds[i-1].a2.z), 'Check greater than previous');
	}
});

test("Check Get Bonds", function(){
	var mol = new Molecule();
	mol.atoms[0] = new Atom();
	mol.atoms[1] = new Atom('C', 0,1);
	mol.atoms[2] = new Atom('C', 0,-1);
	mol.bonds[0] = new Bond(mol.atoms[0], mol.atoms[1]);
	mol.bonds[1] = new Bond(mol.atoms[0], mol.atoms[2]);
	expect(7);
	var b1 = mol.getBonds(mol.atoms[0]);
	equals(2, b1.length, 'Check all bonds found');
	equals(mol.bonds[0], b1[0], 'Check first bond is correct');
	equals(mol.bonds[1], b1[1], 'Check second bond is correct');
	var b2 = mol.getBonds(mol.atoms[1]);
	equals(1, b2.length, 'Check bond found');
	equals(mol.bonds[0], b2[0], 'Check bond is correct');
	var b3 = mol.getBonds(mol.atoms[2]);
	equals(1, b3.length, 'Check bond found');
	equals(mol.bonds[1], b3[0], 'Check bond is correct');
});

test("Check Coordination Numbers", function(){
	var mol = new Molecule();
	mol.atoms[0] = new Atom();
	mol.atoms[1] = new Atom('C', 0,1);
	mol.atoms[2] = new Atom('C', 0,-1);
	mol.bonds[0] = new Bond(mol.atoms[0], mol.atoms[1]);
	mol.bonds[1] = new Bond(mol.atoms[0], mol.atoms[2], 2);
	expect(3);
	equals(3, mol.getCoordinationNumber(mol.getBonds(mol.atoms[0])), 'Check calculation is correct for first atom');
	equals(1, mol.getCoordinationNumber(mol.getBonds(mol.atoms[1])), 'Check calculation is correct for second atom');
	equals(2, mol.getCoordinationNumber(mol.getBonds(mol.atoms[2])), 'Check calculation is correct for third atom');
});

test("Check Bond Angles", function(){
	//remember that angles are upside down because canvas y axis is inverted
	var mol = new Molecule();
	mol.atoms[0] = new Atom();
	mol.atoms[1] = new Atom('C', 0,1);
	mol.atoms[2] = new Atom('C', 0,-1);
	mol.bonds[0] = new Bond(mol.atoms[0], mol.atoms[1]);
	mol.bonds[1] = new Bond(mol.atoms[0], mol.atoms[2]);
	expect(7);
	var a1 = mol.getAngles(mol.atoms[0]);
	equals(2, a1.length, 'Check bond angles calculated');
	equals(Math.PI/2, a1[0], 'Check first angle');
	equals(3*Math.PI/2, a1[1], 'Check second angle');
	var a2 = mol.getAngles(mol.atoms[1]);
	equals(1, a2.length, 'Check angle');
	equals(Math.PI/2, a2[0], 'Check angle calculated');
	var a3 = mol.getAngles(mol.atoms[2]);
	equals(1, a3.length, 'Check angle');
	equals(3*Math.PI/2, a3[0], 'Check angle calculated');
});

test("Check Lone Carbons", function(){
	var mol = new Molecule();
	mol.atoms[0] = new Atom();
	mol.atoms[1] = new Atom('C', 0,1);
	mol.atoms[2] = new Atom('C', 0,-1);
	mol.bonds[0] = new Bond(mol.atoms[0], mol.atoms[1]);
	mol.bonds[1] = new Bond(mol.atoms[0], mol.atoms[2]);
	mol.setupMetaData();
	expect(12);
	ok(mol.atoms[0].isHidden, 'Center atom is hidden');
	ok(!mol.atoms[1].isHidden, 'First terminal atom is not hidden');
	ok(!mol.atoms[2].isHidden, 'Second terminal atom is not hidden');
	//change bond order
	mol.bonds[0].bondOrder = 2;
	mol.setupMetaData();
	ok(!mol.atoms[0].isHidden, 'Center atom is not hidden');
	ok(!mol.atoms[1].isHidden, 'First terminal atom is not hidden');
	ok(!mol.atoms[2].isHidden, 'Second terminal atom is not hidden');
	//change other bond order
	mol.bonds[1].bondOrder = 2;
	mol.setupMetaData();
	ok(mol.atoms[0].isHidden, 'Center atom is hidden again');
	ok(!mol.atoms[1].isHidden, 'First terminal atom is not hidden');
	ok(!mol.atoms[2].isHidden, 'Second terminal atom is not hidden');
	//change angle
	mol.atoms[2].x = 1;
	mol.atoms[2].y = 0;
	mol.setupMetaData();
	ok(!mol.atoms[0].isHidden, 'Center atom is not hidden');
	ok(!mol.atoms[1].isHidden, 'First terminal atom is not hidden');
	ok(!mol.atoms[2].isHidden, 'Second terminal atom is not hidden');
});

test("Check Bond Length Scaling", function(){
	var mol = new Molecule();
	mol.atoms[0] = new Atom();
	mol.atoms[1] = new Atom('C', 0,1);
	mol.atoms[2] = new Atom('C', 0,-1);
	mol.bonds[0] = new Bond(mol.atoms[0], mol.atoms[1]);
	mol.bonds[1] = new Bond(mol.atoms[0], mol.atoms[2]);
	expect(6);
	equals(1, mol.getAverageBondLength(), 'Check average is 1');
	mol.scaleToAverageBondLength(20);
	equals(20, mol.getAverageBondLength(), 'Check average is 20');
	mol.scaleToAverageBondLength(.2);
	equals(.2, mol.getAverageBondLength(), 'Check average is .2');
	//check on 3D molecule
	var mol3d = readMOL(threed);
	mol3d.scaleToAverageBondLength(100);
	equals(100, Math.round(mol3d.getAverageBondLength()), 'Check average of 3D coordinates is 10');
	//check does nothing when all atoms are at the origin
	mol.atoms[1].y=0;
	mol.atoms[2].y=0;
	mol.scaleToAverageBondLength(.2);
	equals(0, mol.getAverageBondLength(), 'Check average is still 0');
	//check that an empty molecule does nothing
	var mol2 = new Molecule();
	mol.scaleToAverageBondLength(10);
	equals(0, mol.getAverageBondLength());
});
	
test("Check Ownership", function(){
	var mol = readMOL(thiophene);
	var ring = new Ring();
	ring.atoms = mol.atoms;
	ring.bonds = mol.bonds;
	ring.setupBonds();
	expect(5);
	for(var i = 0; i<ring.bonds.length; i++){
		equals(ring, ring.bonds[i].ring, 'Check ring owns bond');
	}
});


