/*
 * GrounderMessage.java
 *
 * Copyright (C) 2006 - 2007 Martin Slota
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/*
 * History:
 * v0.1 (2007-02-08): initial version
 * v1.0.0 (2007-05-05):
 * - documentation added
 */

package lp.trans;

import lp.struct.LpRule;

/**
 * An error or warning message that is issued by lparse. It can be related to a
 * specific rule.
 *
 * @author Martin Slota
 * @version 1.0.0
 */
public class GrounderMessage extends RuntimeException {
	/**
	 * The rule that is the reason of this message. Can be {@code null} if no
	 * such rule is specified by lparse.
	 */
	private final LpRule sourceRule;
	
	/**
	 * Is {@code true} if this is a warning message and {@code false} if it is
	 * an error message.
	 */
	private final boolean warning;
	
	/**
	 * Creates a new instance of {@code GrounderMessage} with the specified
	 * message that relates to the given rule.
	 *
	 * @param message the error or warning message
	 * @param sourceRule the rule that is the reason of this error or warning
	 * @param isWarning {@code true} if a warning message should be created,
	 * {@code false} if an error message should be created
	 */
	public GrounderMessage(String message, LpRule sourceRule,
			boolean isWarning) {
		this(message, sourceRule, isWarning, null);
	}
	
	/**
	 * Creates a new instance of {@code GrounderMessage} with the specified
	 * message that relates to the given rule.
	 *
	 * @param message the error or warning message
	 * @param sourceRule the rule that is the reason of this error or warning
	 * @param isWarning {@code true} if a warning message should be created,
	 * {@code false} if an error message should be created
	 * @param cause the cause of this exception
	 */
	public GrounderMessage(String message, LpRule sourceRule,
			boolean isWarning, Throwable cause) {
		super(message, cause);
		this.sourceRule = sourceRule;
		this.warning = isWarning;
	}
	
	/**
	 * Returns the rule that is the reason of this message. Can be {@code null}
	 * if no such rule is specified by lparse.
	 *
	 * @return as specified above
	 */
	public LpRule getSourceRule() {
		return sourceRule;
	}
	
	/**
	 * Returns {@code true} if this is a warning message and {@code false} if it
	 * is an error message.
	 */
	public boolean isWarning() {
		return warning;
	}
	
	/**
	 * Returns {@code true} if {@code obj} is a {@code GrounderMessage} with the
	 * same members as this one.
	 *
	 * @param obj the object to compare with
	 * @return as specified above
	 */
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof GrounderMessage))
			return false;
		
		GrounderMessage e = (GrounderMessage) obj;
		return (isWarning() == e.isWarning() &&
				((getSourceRule() == null) ? (e.getSourceRule() == null) :
					getSourceRule().equals(e.getSourceRule())) &&
				((getMessage() == null) ? (e.getMessage() == null) :
					getMessage().equals(e.getMessage())));
	}
	
	/**
	 * Overriden in order to maintain the general contract of
	 * {@link Object#hashCode()}.
	 *
	 * @return the hash of this object
	 */
	@Override
	public int hashCode() {
		int result = (isWarning() ? 1 : 0);
		result += (getSourceRule() == null) ? 0 : getSourceRule().hashCode();
		result += (getMessage() == null) ? 0 : getMessage().hashCode();
		return result;
	}
}