// $Id: ModuleProperties.java,v 1.11 2004/07/01 20:15:54 m31 Exp $
//
// This file is part of the program suite "Principia Mathematica II"
// which is a working prototype for the main project:
// "Hilbert II" - http://www.qedeq.org
//
// Copyright 2001-2004  Michael Meyling <mime@qedeq.org>.
//
// "Principia Mathematica II" 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.

package com.meyling.principia.module;



/**
 * Represents a module and its state.
 *
 * @version $Revision: 1.11 $
 * @author      Michael Meyling
 */
public final class ModuleProperties {

    /** address and module specification. */
    private final ModuleAddress address;

    /** completeness during loading into memory */
    private int completeness;

    /** describes module state. */
    private ModuleState state;

    /** loaded and verified modul. */
    private Module module;

    /** failure exception. */
    private Exception exception;



    /**
     * Creates new module properties.
     *
     * @param   address     module address
     * @param   state       module state
     */
    public ModuleProperties(final ModuleAddress address) {
        this.address = address;
        this.state = ModuleState.STATE_UNDIFINED;
        this.completeness = 0;
    }


    /**
     * Creates new module properties.
     *
     * @param   address     module address
     * @param   state       module state
     *
    public ModuleProperties(final ModuleAddress address, final ModuleState state) {
        this.address = address;
        this.state = state;
        this.completeness = 0;
    }
*/

    /**
     * Is this a failure state the module is in?
     *
     * @return  were there any errors?
     */
    public final boolean hasFailures() {
        return this.state.isFailure();
    }


    /**
     * Get address of module.
     *
     * @return  address of module.
     */
    public final String getAddress() {
        if (address == null) {
            return "null";
        }
        return address.getAddress();
    }


    /**
     * Get {@link ModuleAddress} of module. Maybe <code>null</code>.
     *
     * @return  address of module.
     */
    public final ModuleAddress getModuleAddress() {
        return address;
    }


    /**
     * Set completeness percentage.
     *
     * @param   state   completeness of loading into memory.
     */
    public final void setCompleteness(final int completeness) {
        this.completeness = completeness;
    }


    /**
     * Set progress module state.
     *
     * @param   state   module state
     */
    public final void setProgressState(final ModuleState state) {
        if (this.state == ModuleState.STATE_LOADED_AND_VERIFIED) {
            this.module = null;
        }
        if (state == ModuleState.STATE_LOADED_AND_VERIFIED) {
            throw new IllegalStateException(
                "this state could only be set by calling method setCheckedAndLoaded");
        }
        if (state.isFailure()) {
            throw new IllegalArgumentException(
                "this is a failure state, call setFailureState");
        }
        this.exception = null;
        this.state = state;
    }


    /**
     * Set failure module state.
     *
     * @param   state   module state
     * @throws  IllegalArgumentException    <code>state</code> is no failure state
     */
    public final void setFailureState(final ModuleState state, final Exception e) {
        if (this.state == ModuleState.STATE_LOADED_AND_VERIFIED) {
            this.module = null;
        }
        if (!state.isFailure()) {
            throw new IllegalArgumentException(
                "this is no failure state, call setProgressState");
        }
        this.state = state;
        this.exception = e;
    }


    /**
     * Get module state.
     *
     * @return  module state.
     */
    public final ModuleState getState() {
        return this.state;
    }


    /**
     * Get exception.
     *
     * @return  exception.
     */
    public final Exception getException() {
        return this.exception;
    }


    /**
     * Get module state description.
     *
     * @return  module state description.
     */
    public final String getStateDescription() {
        if (this.state == ModuleState.STATE_LOADING_INTO_MEMORY) {
            return this.state.getText() + " (" + this.completeness + "%)";
        } else {
            return this.state.getText();
        }
    }


    /**
     * Get name of module.
     *
     * @return  module name.
     */
    public final String getName() {
        if (address == null) {
            return "null";
        }
        return address.getName().getText();
    }


    /**
     * Get module version information.
     *
     * @return  module version.
     */
    public final String getModuleVersion() {
        if (address == null) {
            return "null";
        }
        return address.getModuleVersion().getText();
    }


    /**
     * Get rule version information.
     *
     * @return  rule version.
     */
    public final String getRuleVersion() {
        if (address == null) {
            return "null";
        }
        return address.getRuleVersion().getText();
    }


    /**
     * Get orginal URL of module.
     *
     * @return  URL of module.
     */
    public final String getUrl() {
        if (address == null) {
            return "null";
        }
        return address.getURL().toString();
    }


    /**
     * Get orginal URL of module.
     *
     * @return  URL of module.
     */
    public final boolean isCheckedAndLoaded() {
        return (this.state == ModuleState.STATE_LOADED_AND_VERIFIED);
    }


    /**
     * Set checked and loaded state and module.
     *
     * @param  module   checked and loaded module.
     */
    public final void setCheckedAndLoaded(final Module module) {
        this.state = ModuleState.STATE_LOADED_AND_VERIFIED;
        this.module = module;
    }


    /**
     * Get module.
     */
    public final Module getModule() {
        if (this.state != ModuleState.STATE_LOADED_AND_VERIFIED) {
            throw new IllegalStateException(
                "module could only be set if state is \"loaded and verified\"");
        }
        return this.module;
    }
        

    /*
     * @inherited
     */
    public final String toString() {
       return super.toString() + ":" + address + ";" + state;
    }


}
