package at.oefai.aaa.agent.jam;

import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Date;

/**
 * The internal output method for an agent.
 * logs debug messages and holds debug output flags
 * @author Stefan Rank
 */
public class AgentLogger implements Serializable {
    private static final AgentLogger STATIC_INSTANCE = new AgentLogger("");

    private final Logger log;

    // Debug output flags
    private boolean showWorldModel = false;
    private boolean showGoalList = false;
    private boolean showIntentionStructure = false;
    private boolean showAPL = false;
    private boolean showActionFailure = false;
    private boolean showAppraisal = false;

    AgentLogger(final String name) {
        this.log = Logger.getLogger(name);
        this.config("Created AgentLogger " + new Date());
    }

    AgentLogger(final String name, final boolean pShowWorldModel, final boolean pShowGoalList,
                final boolean pShowIntentionStructure, final boolean pShowAPL, final boolean pShowActionFailure) {
        this(name);
        this.showWorldModel = pShowWorldModel;
        this.showGoalList = pShowGoalList;
        this.showIntentionStructure = pShowIntentionStructure;
        this.showAPL = pShowAPL;
        this.showActionFailure = pShowActionFailure;
    }

    static AgentLogger getStaticInstance() {
        return STATIC_INSTANCE;
    }

    public final void setShowWorldModel(final boolean flag) {
        this.showWorldModel = flag;
        this.config("*** JAM: Showing the World Model turned " + (flag ? "ON" : "OFF") + ". ***");
    }

    public final void setShowGoalList(final boolean flag) {
        this.showGoalList = flag;
        this.config("*** JAM: Showing the Goal List turned " + (flag ? "ON" : "OFF") + ". ***");
    }

    public final void setShowAPL(final boolean flag) {
        this.showAPL = flag;
        this.config("*** JAM: Showing APL generation turned " + (flag ? "ON" : "OFF") + ". ***");
    }

    public final void setShowIntentionStructure(final boolean flag) {
        this.showIntentionStructure = flag;
        this.config("*** JAM: Showing the Intention Structure turned " + (flag ? "ON" : "OFF") + ". ***");
    }

    public final void setShowActionFailure(final boolean flag) {
        this.showActionFailure = flag;
        this.config("*** JAM: Showing Action Failures turned " + (flag ? "ON" : "OFF") + ". ***");
    }

    public final void setShowAppraisal(final boolean flag) {
        this.showAppraisal = flag;
        this.config("*** JAM: Showing Appraisal turned " + (flag ? "ON" : "OFF") + ". ***");
    }

    public final boolean getShowWorldModel() { return this.showWorldModel; }
    public final boolean getShowGoalList() { return this.showGoalList; }
    public final boolean getShowAPL() { return this.showAPL; }
    public final boolean getShowIntentionStructure() { return this.showIntentionStructure; }
    public final boolean getShowActionFailure() { return this.showActionFailure; }
    public final boolean getShowAppraisal() { return this.showAppraisal; }

    public final boolean getShowAPLorIS() {
        return (this.showAPL || this.showIntentionStructure);
    }

    public final boolean getShowISorGoalList() {
        return (this.showIntentionStructure || this.showGoalList);
    }

    // OUTPUT METHODS
    public final void severe(final String s) {
        this.log.logp(Level.SEVERE, null, null, s);
    }

    public final void warning(final String s) {
        this.log.logp(Level.WARNING, null, null, s);
    }

    public final void info(final String s) {
        this.log.logp(Level.INFO, null, null, s);
    }

    public final void config(final String s) {
        this.log.logp(Level.CONFIG, null, null, s);
    }

    public final void fine(final String s) {
        this.log.logp(Level.FINE, null, null, s);
    }

    public final void finer(final String s) {
        this.log.logp(Level.FINER, null, null, s);
    }

    public final void finest(final String s) {
        this.log.logp(Level.FINEST, null, null, s);
    }

    // OUTPUT METHODS with throwables
    public final void severe(final String s, final Throwable t) {
        this.log.logp(Level.SEVERE, null, null, s, t);
    }

    public final void warning(final String s, final Throwable t) {
        this.log.logp(Level.WARNING, null, null, s, t);
    }
}
