// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/CONCEPT/classTest.h>
#include <BALLTestConfig.h>

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

#include <BALL/FORMAT/HMOFile.h>
#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/molecule.h>

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

START_TEST(HMOFile)

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

using namespace BALL;

HMOFile* cf = 0;
CHECK(HMOFile())
	cf = new HMOFile;
	TEST_NOT_EQUAL(cf, 0)
RESULT


CHECK(~HMOFile())
	delete cf;
RESULT


CHECK(HMOFile(const String& filename, File::OpenMode open_mode = std::ios::in))
	HMOFile f(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	TEST_EXCEPTION(Exception::FileNotFound, HMOFile f2("invalid.hmo"))
RESULT

CHECK(bool open(const String& name, File::OpenMode open_mode))
	HMOFile f2;
	bool f2_result = f2.open(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	TEST_EQUAL(f2_result, true)

	HMOFile f3;
	TEST_EXCEPTION(Exception::FileNotFound, f3.open(BALL_TEST_DATA_PATH(file_does_not.exist), std::ios::in));
RESULT

CHECK(clear())
	HMOFile f(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	Surface S;
	f.read(S);
	f.clear();

	TEST_EQUAL(f.getName(), "")
	TEST_EQUAL(f.getCharges().size(), 0)
	TEST_EQUAL(f.getComments().size(), 0)
RESULT

CHECK(bool operator == (const HMOFile& file))
	HMOFile f(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	HMOFile f2(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	HMOFile f3;

	TEST_EQUAL(f == f, true)
	TEST_EQUAL(f == f2, true)
	TEST_EQUAL(f == f3, false)
RESULT

HMOFile f(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
CHECK(virtual bool read(Surface& surface))
	Surface S;

	bool result = f.read(S);
	TEST_EQUAL(result, true)

	TEST_EQUAL(f.getComments().size(), 1)
	TEST_EQUAL(f.getComments()[0], "# HYPERMESH for the solvent excluded surface of N.hin; Generated by ./createBEMMesh")

	TEST_EQUAL(S.vertex.size(), 642)
	TEST_REAL_EQUAL(S.vertex[3].x, -14.4721)
	TEST_REAL_EQUAL(S.vertex[3].y,  10.5146)
	TEST_REAL_EQUAL(S.vertex[3].z,  8.94427)

	TEST_EQUAL(S.triangle.size(), 1280)
	TEST_EQUAL(S.triangle[5].v1, 418)
	TEST_EQUAL(S.triangle[5].v2, 419)
	TEST_EQUAL(S.triangle[5].v3, 420)

	TEST_EQUAL(f.getCharges().size(), 1)
	HMOFile::HMOCharge& c = f.getCharges()[0];

	TEST_REAL_EQUAL(c.value, 1)
	TEST_REAL_EQUAL(c.position.x, 0)
	TEST_REAL_EQUAL(c.position.y, 0)
	TEST_REAL_EQUAL(c.position.z, 0)

	Surface S2;
	HMOFile f_no_charge(BALL_TEST_DATA_PATH(HMOFile_test_no_charge.hmo), std::ios::in);
	result = f_no_charge.read(S2);
	TEST_EQUAL(result, true)

	TEST_EQUAL(f_no_charge.getComments().size(), 1)
	TEST_EQUAL(f_no_charge.getComments()[0], "# HYPERMESH file written by BALL::HMOFile")

	TEST_EQUAL(S2.vertex.size(), 642)
	TEST_REAL_EQUAL(S2.vertex[3].x, -14.4721)
	TEST_REAL_EQUAL(S2.vertex[3].y,  10.5146)
	TEST_REAL_EQUAL(S2.vertex[3].z,  8.94427)

	TEST_EQUAL(S2.triangle.size(), 1280)
	TEST_EQUAL(S2.triangle[5].v1, 418)
	TEST_EQUAL(S2.triangle[5].v2, 419)
	TEST_EQUAL(S2.triangle[5].v3, 420)

	TEST_EQUAL(f_no_charge.hasCharges(), false)
	TEST_EQUAL(f_no_charge.getCharges().size(), 0)

RESULT

f.clear();
f.open(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
CHECK(bool hasCharges() const)
	TEST_EQUAL(f.hasCharges(), false)
	Surface S;
	f.read(S);
	TEST_EQUAL(f.hasCharges(), true)
RESULT

CHECK(std::vector<HMOFile::HMOCharge>& getCharges())
	std::vector<HMOFile::HMOCharge>& charges = f.getCharges();
	TEST_EQUAL(charges.size(), 1)
RESULT

CHECK(std::vector<HMOFile::HMOCharge> const& getCharges() const)
	HMOFile const& f_const = f;
	std::vector<HMOFile::HMOCharge> const& charges = f_const.getCharges();
	TEST_EQUAL(charges.size(), 1)
RESULT

f.clear();
f.open(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
CHECK(bool hasComments() const)
	TEST_EQUAL(f.hasComments(), false)
	Surface S;
	f.read(S);
	TEST_EQUAL(f.hasComments(), true)
RESULT

CHECK(std::vector<String>& getComments())
	std::vector<String>& comments = f.getComments();
	TEST_EQUAL(comments.size(), 1)
RESULT

CHECK(std::vector<String> const& getComments() const)
	HMOFile const& f_const = f;
	std::vector<String> const& comments = f_const.getComments();
	TEST_EQUAL(f.getComments().size(), 1)
RESULT

CHECK(virtual bool write(Surface const& surface))
	HMOFile f_in(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	Surface S;
	f_in.read(S);

	String filename;
	NEW_TMP_FILE(filename);
	HMOFile f_out(filename, std::ios::out);

	f_out.write(S);
	f_out.close();

	TEST_FILE_REGEXP(filename.c_str(), BALL_TEST_DATA_PATH(HMOFile_test_no_charge.hmo))
RESULT

CHECK(virtual bool write(Surface const& surface, AtomContainer const& ac))
	HMOFile f_in(BALL_TEST_DATA_PATH(HMOFile_test.hmo), std::ios::in);
	Surface S;
	f_in.read(S);

	Molecule m;

	Atom a;
	a.setPosition(Vector3(0,0,0));
	a.setCharge(1);

	m.insert(a);

	String filename;
	NEW_TMP_FILE(filename);
	HMOFile f_out(filename, std::ios::out);
	f_out.getComments().push_back("# HYPERMESH for the solvent excluded surface of N.hin; Generated by ./createBEMMesh");

	f_out.write(S, m);
	f_out.close();

	TEST_FILE_REGEXP(filename.c_str(), BALL_TEST_DATA_PATH(HMOFile_test.hmo))
RESULT
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
