/*
** SellaNMS
** $Id: term.cxx,v 1.6 2005/08/18 06:51:45 sella Exp $
** Copyright (c) 2001-2005 Digital Genesis Software, LLC. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
*/

static char rcsid[] = "$Id: term.cxx,v 1.6 2005/08/18 06:51:45 sella Exp $";

#include "term.h"
#include <stdio.h>

/*
	The default constructor for this class.
*/
Term::Term() {
	this->from = NULL;
  	this->then = NULL;

	this->name = "unknown";
}

Term::Term(Term const &src): from(NULL), then(NULL) {
	/* Utilize operator=(). */
	*this = src;
}

Term const& Term::operator=(Term const &src) {
	/* Clear destination Term. */
	this->clear();

	/* Perform a deep copy. */
	this->name = src.name;

	if (src.from != NULL) {
		this->from = src.getNewFromClause();
		if (this->from != NULL) {
			*this->from = *src.from;
		}
	} else {
		this->from = NULL;
	}

	if (src.then != NULL) {
		this->then = src.getNewThenClause();
		if (this->then != NULL) {
			*this->then = *src.then;
		}
	} else {
		this->then = NULL;
	}

	/* Release storage */
	this->setStorage(src.storage);

	return *this;
}

/*
	The default destructor for this class.
*/
Term::~Term() {
	SAFE_DELETE(this->from);
	SAFE_DELETE(this->then);
}

ACTION Term::evaluate(variable_binding_t &input) {
	if (this->from) {
		if (this->from->evaluate(input) == ACTION_THEN) {
			if (this->then) {
				return this->then->evaluate(input);
			}
		}
	} else {
		if (this->then) {
			return this->then->evaluate(input);
		}
	}
	return ACTION_NEXT_TERM;
}

/*
	Get a new instance of a from clause for this term type.

	Return Values
		A new instance (allocated via the new operator) of a from clause for this term type.
*/
From *Term::getNewFromClause() const {
	LMSG("DEBUG: Term::getNewFromClause() returned NULL.");
	return NULL;
}

/*
	Get a new instance of a then clause for this term type.

	Return Values
		A new instance (allocated via the new operator) of a then clause for this term type.
*/
Then *Term::getNewThenClause() const {
	LMSG("DEBUG: Term::getNewThenClause() returned NULL.");
	return NULL;
}

/*
	Compile this term.

	Parameters
		config:	the section of the configuration from the level "policy-options <statement-type> <statement-name> term <term-name>"

	Return Values
		SUCCESS:	if the term was successfully compiled.
		FAILURE: if the term failed to compile.
*/
RESULT Term::compile(ConfigNode *config) {
	RESULT result = SUCCESS;

	ConfigNode	from_config;
	ConfigNode	then_config;

	SAFE_DELETE(this->from);
	SAFE_DELETE(this->then);

	if (config->assignNode("from", from_config)) {
		this->from = this->getNewFromClause();
		this->from->setStorage(this->storage);
		
		if (this->from != NULL) {
			if (this->from->compile(&from_config) != SUCCESS) {
				SAFE_DELETE(this->from);
				result = FAILURE;
			}
		} else {
			result = FAILURE;
		}
		from_config.clear();
	}

	if (config->assignNode("then", then_config)) {
		this->then = this->getNewThenClause();
		this->then->setStorage(this->storage);

		if (this->then != NULL) {
			if (this->then->compile(&then_config) != SUCCESS) {
				SAFE_DELETE(this->then);
				result = FAILURE;
			}
		} else {
			result = FAILURE;
		}
		then_config.clear();
	}

	return result;
}

/*
	Clear this term.

	Return Values
		SUCCESS:	this term was successfully cleared.
		FAILURE: this term was not cleared.
*/
RESULT Term::clear() {
	RESULT result = SUCCESS;

	this->name = "unknown";

	SAFE_DELETE(this->from);
	SAFE_DELETE(this->then);

	this->storage = NULL;

	return result;
}

/*
	Get the name of this term.

	Return Values
		The name of this term.
*/
string Term::getName() {
	return this->name;
}

/*
	Set the name of this term.

	Parameters
		name:		the new name to set for this term.
	
	Return Values
		SUCCESS:	the name of this term was successfully set.
		FAILURE: the name of this term could not be set.
*/
RESULT Term::setName(const string &name) {
	RESULT result = SUCCESS;

	this->name = name;

	return result;
}

/*
	Set the from clause of this term.

	Parameters
		from:		the new from clause for this term.
	
	Return Values
		SUCCESS:	the from clause of this term was successfully set.
		FAILURE: the from clause of this term was not set.
*/
RESULT Term::setFrom(From *from) {
	RESULT result = SUCCESS;

	SAFE_DELETE(this->from);

	this->from = from;

	return result;
}

/*
	Set the then clause of this term.

	Parameters
		then:		the new then clause for this term.
	
	Return Values
		SUCCESS:	the then clause of this term was successfully set.
		FAILURE: the then clause of this term was not set.
*/
RESULT Term::setThen(Then *then) {
	RESULT result = SUCCESS;

	SAFE_DELETE(this->then);

	this->then = then;

	return result;
}

/*
	Print the contents of this statement term.

	Return Values
		SUCCESS:	this term was successfully printed.
		FAILURE: this term was not printed.
*/
RESULT Term::print(unsigned long depth) {
	RESULT result = SUCCESS;

	string	tab = "";
	for (unsigned long i = 0; i < depth; i++) {
		tab.append("   ");
	}

	LMSG("%sterm %s {", tab.c_str(), this->name.c_str());

	if (this->from != NULL) {
		this->from->print(depth + 1);
	}

	if (this->then != NULL) {
		this->then->print(depth + 1);
	}

	LMSG("%s}", tab.c_str());
	
	return result;
}

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim600: fdm=marker
** vim: noet ts=3 sw=3 sts=3
*/
