/* $Id: DefaultModuleProperties.java,v 1.1 2007/05/10 00:37:51 m31 Exp $
 *
 * This file is part of the project "Hilbert II" - http://www.qedeq.org
 *
 * Copyright 2000-2007,  Michael Meyling <mime@qedeq.org>.
 *
 * "Hilbert 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 org.qedeq.kernel.bo.load;

import java.net.URL;

import org.qedeq.kernel.bo.module.LoadingState;
import org.qedeq.kernel.bo.module.ModuleAddress;
import org.qedeq.kernel.bo.module.ModuleProperties;
import org.qedeq.kernel.bo.module.QedeqBo;


/**
 * Represents a module and its states.
 *
 * @version $Revision: 1.1 $
 * @author  Michael Meyling
 */
public class DefaultModuleProperties implements ModuleProperties {

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

    /** Completeness during loading from web. */
    private int loadingCompleteness;

    /** describes QEDEQ module loading state. */
    private LoadingState state;

    /** loaded QEDEQ module. */
    private QedeqBo module;

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


    /**
     * Creates new module properties.
     *
     * @param   address     module address
     */
    public DefaultModuleProperties(final ModuleAddress address) {
        this.address = address;
        this.state = LoadingState.STATE_UNDEFINED;
        this.loadingCompleteness = 0;
    }

    public final boolean hasFailures() {
        return this.state.isFailure();
    }

    public final String getAddress() {
        if (address == null) {
            return "null";
        }
        return address.getAddress();
    }

    public final ModuleAddress getModuleAddress() {
        return address;
    }

    public final void setLoadingCompleteness(final int completeness) {
        this.loadingCompleteness = completeness;
    }

    public final void setLoadingProgressState(final LoadingState state) {
        if (state == LoadingState.STATE_LOADED) {
            throw new IllegalArgumentException(
                "this state could only be set by calling method setCheckedAndLoaded");
        }
        if (this.state == LoadingState.STATE_LOADED) {
            this.module = null;
        }
        if (state.isFailure()) {
            throw new IllegalArgumentException(
                "this is a failure state, call setLoadingFailureState");
        }
        this.exception = null;
        this.state = state;
    }

    public final void setLoadingFailureState(final LoadingState state, final Exception e) {
        if (!state.isFailure()) {
            throw new IllegalArgumentException(
                "this is no failure state, call setProgressState");
        }
        if (this.state == LoadingState.STATE_LOADED) {
            this.module = null;
        }
        this.state = state;
        this.exception = e;
    }

    public final LoadingState getLoadingState() {
        return this.state;
    }

    public final Exception getException() {
        return this.exception;
    }

    public final String getStateDescription() {
        if (this.state == LoadingState.STATE_LOADING_FROM_WEB) {
            return this.state.getText() + " (" + this.loadingCompleteness + "%)";
        } else {
            return this.state.getText();
        }
    }

    public final String getName() {
        if (address == null) {
            return "null";
        }
        return address.getName();
    }

    public final String getRuleVersion() {
        if (address == null || module == null || module.getHeader() == null
                || module.getHeader().getSpecification() == null
                || module.getHeader().getSpecification().getRuleVersion() == null) {
            return "null";
        }
        return module.getHeader().getSpecification().getRuleVersion();
    }

    public final URL getUrl() {
        if (address == null) {
            return null;
        }
        return address.getURL();
    }

    public final boolean isLoaded() {
        return (this.state == LoadingState.STATE_LOADED);
    }

    public final void setLoaded(final QedeqBo module) {
        this.state = LoadingState.STATE_LOADED;
        this.module = module;
    }

    public final QedeqBo getModule() {
        if (this.state != LoadingState.STATE_LOADED) {
            throw new IllegalStateException(
                "module could only be set if state is \"" + LoadingState.STATE_LOADED.getText()
                +   "\"");
        }
        return this.module;
    }

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

}
