/*
 * MiningMart Version 1.0
 * 
 * Copyright (C) 2006 Martin Scholz, Timm Euler, 
 *                    Daniel Hakenjos, Katharina Morik
 *
 * Contact: miningmart@ls8.cs.uni-dortmund.de
 *
 * A list of contributing developers (other than the copyright 
 * holders) can be found at
 * http://mmart.cs.uni-dortmund.de/downloads/download.html
 * 
 * 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, see the file MM_HOME/LICENSE; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 */
package edu.udo.cs.miningmart.m4;

import java.util.Collection;

import edu.udo.cs.miningmart.exception.M4Exception;
import edu.udo.cs.miningmart.m4.core.BaseAttribute;

/**
 * @author Timm Euler, Daniel Hakenjos
 * @version $Id: Step.java,v 1.6 2006/04/11 14:10:12 euler Exp $
 */
public interface Step extends GraphicalM4Object {

	//methods from core

	/**
	 * Active getter method.
	 * @return the M4 operator object related to this <code>Step</code>
	 */
	public Operator getTheOperator();

	/**
	 * Setter method.
	 * There is no back-reference from <code>Operator</code>, so we do
	 * not need another primitive setter.
	 * 
	 * @param theOp The new operator
	 */
	public void setTheOperator(Operator theOp);

	/** Getter method.
	 * 
	 * @return the <code>Chain</code> of this <code>Step</code>
	 */
	public Chain getTheChain();

	/**
	 * Setter method.
	 * 
	 * @param chain The new chain
	 */
	public void setTheChain(Chain chain) throws M4Exception;

	/**
	 * Getter method.
	 * 
	 * @return the id
	 */
	public long getCaseId();

	/**
	 * Getter method.
	 * 
	 * @return the number
	 */
	public long getNumber();

	/**
	 * Setter method.
	 * 
	 * @param myCase The new case
	 */
	public void setTheCase(Case myCase) throws M4Exception;

	/**
	 * Setter method.
	 * 
	 * @param nr the new step number
	 */
	public void setNumber(long nr);

	/**
	 * Getter method.
	 * 
	 * @return the loop count
	 */
	public int getLoopCount();

	/**
	 * Getter method.
	 * 
	 * @return the multistep condition
	 */
	public String getMultiStepCondition();

	/**
	 * Adds a parameter to this step's parameter list on tuple level.
	 *
	 * @param par the <code>Parameter</code> object representing the parameter tuple
	 */
	public void addParameterTuple(Parameter par) throws M4Exception;

	/**
	 * Removes a parameter from this step's parameter list on tuple level.
	 *
	 * @param par the <code>Parameter</code> object representing the parameter tuple
	 * @return <code>true</code> iff the object was part of the parameter list and
	 *         could be removed
	 */
	public boolean removeParameterTuple(Parameter par) throws M4Exception;

	public void removeAllParameterTuples() throws M4Exception;
	
	public void removeParameter(String parName) throws M4Exception;
	
	/**
	 * Checks if this step has a successor among any of the steps in the
	 * given chain, including steps in any direct or indirect subchain of
	 * the given chain.
	 * 
	 * @param toChain the given chain
	 * @return TRUE iff this step has a successor among any of the steps in the
	 * given chain.
	 * @throws M4Exception
	 */
	public boolean dependencyExists(Chain toChain) throws M4Exception;	
	
	/**
	 * Setter method.
	 * 
	 * @param lc the new loop count
	 */
	public void setLoopCount(int lc) throws M4Exception;

	/**
	 * Setter method.
	 * 
	 * @param msc The new multistep condition
	 */
	public void setMultiStepCondition(String msc);

	/**
	 * This method returns all concepts that are input concept to this step's
	 * operator, even those that are attached to an input relation but not modelled 
	 * by an input parameter. 
	 */
	public Collection getAllInputConcepts() throws M4Exception;

	/**
	 * This method returns all concepts that are input concept to this step's
	 * operator. (For Join and other operators, there can be more than one input
	 * concept.) Note that concepts attached to an input relation are not returned!
	 */
	public Collection getInputConceptsThatAreParameters() throws M4Exception;
	
	/**
	 * Returns all relations that are a parameter object of an input
	 * parameter of this Step. 
	 * @return a collection of relations
	 * @throws M4Exception
	 */
	public Collection getAllInputRelations() throws M4Exception;

	/**
	 * This method checks if this Step creates a relationship from or to its
	 * output concept. If no, null is returned. If yes, it checks whether the 
	 * output concept and its features have been created yet. If yes, it 
	 * returns the BaseAttributes that form the keys of the relationship
	 * in a two-dimensional array.
	 * 
	 * @return a two-dimensional array of the BaseAttributes that are the
	 * keys of the relationship created by this Step, or null
	 * @throws M4Exception
	 */
	public BaseAttribute[][] getKeysOfRelationshipAssertion() throws M4Exception;
	
	/**
	 * Returns the output concept of this step, if it exists, and NULL otherwise.
	 * 
	 * @return a concept or NULL
	 */
	public Concept getOutputConcept() throws M4Exception;
	
	/**
	 * Getter method.
	 * 
	 * @return this step's case
	 */
	public Case getTheCase();

	/**
	 * Active getter for the parameters of this <code>Step</code>
	 * <b>in tuple-wise form</b> (not aggregated by <code>OpParam</code>
	 * arrays!).
	 * 
	 * @return Returns a Collection of <code>Parameter</code> objects
	 */
	public Collection getParameterTuples() throws M4Exception;

	/**
	 * Active getter for this <code>Step</code>'s successors.
	 * 
	 * @return <code>Collection</code> of dependent <code>Step</code> objects
	 */
	public Collection getSuccessors() throws M4Exception;

	/**
	 * This method should only be called from the method
	 * <code>Case.addStepDependency(Step, Step)</code>!
	 * Please use that method instead of this one, because
	 * it also efficiently reorders the steps!
	 * 
	 * Adds a <code>Step</code> to this <code>Step</code>'s <code>Collection</code>
	 * of dependent <code>Step</code>s.
	 * 
	 * @param step the <code>Step</code> to add
	 */
	void addSuccessor(Step step) throws M4Exception;

	/**
	 * Removes a <code>Step</code> from this <code>Step</code>'s <code>Collection</code>
	 * of dependent <code>Step</code>s.
	 * 
	 * @param step the <code>Step</code> to remove
	 * @return <code>true</code> iff the <code>Step</code> was found in the
	 *         <code>Collection</code> and could be successfully removed
	 */
	boolean removeSuccessor(Step step) throws M4Exception;

	/**
	 * Removes a <code>Step</code> from this <code>Step</code>'s <code>Collection</code>
	 * of dependent <code>Step</code>s.
	 * 
	 * @param name the name of the step to remove
	 * @return <code>true</code> iff the <code>Step</code> was found in the
	 *         <code>Collection</code> and could be successfully removed
	 */
	boolean removeSuccessor(String name) throws M4Exception;
	
	/*
	 * Reads all of this operator's parameters specified in table <i>OP_PARAM_T</i> for
	 * the current <code>Step</code>  and stores them in a parameter dictionary.
	 * This is a service method for the compiler, aggregating all parameters to arrays
	 * as specified by the corresponding <code>OpParam</code> objects!
	 * This method should only be called by the method
	 * <code>ExecutableOperator.getParameterDictionary()</code>!
	 *
	public ParamDict readParametersForExecutableFromDB() throws M4Exception;
	*/

	/**
	 * Returns the parameter dictionary of the step. It contains the parameter
	 * tuples that are currently known to this steps in aggregated form. 
	 * A boolean parameter is used to specify whether the calling method 
	 * expects all parameters of this step 
	 * (as specified by this step's operator's OpParams)  
	 * to exist already.
	 * 
	 * @param expectingAllParamsToExist If true, the caller expects the step to
	 * be fully parameterised.
	 * @return ParamDict object for the current step
	 * @throws M4Exception
	 */
	public ParamDict getParameterDictionary(boolean expectingAllParamsToExist) throws M4Exception;	

	
	/**
	 * @return a <code>Collection</code> of <code>Step</code> to <code>Step</code>
	 * dependencies for sequentializing all <code>Step</code>s before writing updates
	 * to the database.
	 */
	public Collection getCrossReferences() throws M4Exception;

	/**
	 * Active getter for the compiler's M4 Trash information. 
	 * @return a <code>Collection</code> of <code>M4Data</code>
	 * objects created by the M4 compiler that have to be removed
	 * before this <code>Step</code> can be compiled anew.
	 */
	public Collection getM4Trash() throws M4Exception;

	/**
	 * This method should only be called by the compiler after a new M4 object
	 * has been created by calling a constructor.
	 * @param m4data the <code>M4Data</code> object to be added to the table
	 *        <code>M4TRASH_T</code> for being garbage collected before compiling
	 *        this <code>Step</code> or any of its predecessors.
	 */
	public void addToTrash(M4Data m4data) throws M4Exception;

	/**
	 * This method realizes the M4Compiler's garbage collection on the objects
	 * created during compilation of this <code>Step</code>.
	 */
	public void deleteM4Trash() throws M4Exception;

	/** Helper method to store the information about a database object in the trash index */
	public void addDatabaseObjectToTrash(
		String objectName,
		String schemaName,
		String objectType)
		throws M4Exception;

	/**
	 * This method takes care of deleting trash objects from the
	 * business data schema.
	 */
	public void deleteDbTrash() throws M4Exception;

	/** 
	 * After a <code>Step</code> has been successfully compiled a flag in the
	 * M4 database is set, which is removed by the next garbage collection.
	 * This method checks, if this flag is set.
	 * 
	 * @return <code>true</code> iff this <code>Step</code> has been
	 *         successfully compiled and no garbage collection involving this
	 *         <code>Step</code> has been run afterwards.
	 */
	public boolean isCompiled() throws M4Exception;

	/**
	 * This method may only be called by the control structure!
	 * It marks this <code>Step</code> as successfully compiled.
	 * This information is used when it is checked for succeeding
	 * <code>Step</code>s, if all of the dependent resources are
	 * already available.
	 */
	public void setCompiled() throws M4Exception;

	/**
	 * This method returns TRUE if the coordinated parameters in this 
	 * step (ab)use the loop mechanism for their coordination.
	 * 
	 * @return TRUE iff parameters of the coordinated parameter groups
	 * should be read and set using positive loop numbers.
	 * @throws M4Exception
	 */
	public boolean usesLoopsForCoordination() throws M4Exception;
	
	//methods from old interface

	/* Attribute methods */

	/**
	 * 
	 */
	public boolean isRelationallyValid(); 

	/* Association methods */

	public Step copy(Case newCase, Chain newChain)	throws M4Exception;

	public void addPredecessor(Step step) throws M4Exception;

	public Collection getAllPredecessors() throws M4Exception;

	/** 
	 * Returns a collection of concepts; these concepts represent
	 * the data model that the current Case produced up to this Step.
	 * 
	 * @return a collection of concepts
	 * @throws M4Exception
	 */
	public Collection getResultingDataModel() throws M4Exception;
	
	/**
	 * This method returns TRUE if this Step belongs to the given
	 * Chain, or to a direct or indirect subchain of the given Chain.
	 * 
	 * @param theChain the given Chain
	 * @return TRUE iff this Step belongs to the given Chain or one of 
	 * its (direct or indirect) subchains.
	 */
	public boolean belongsToChainOrSubChain(Chain theChain) throws M4Exception;
	
	/**
	 * This method returns TRUE if this Step has a direct predecessor
	 * that does not belong to the same chain, nor one of its subchains.
	 * @return TRUE if a predecessor of this Step exists outside this Step's Chain
	 * @throws M4Exception
	 */
	public boolean hasPredecessorOutsideChain() throws M4Exception;	

	/**
	 * This method returns TRUE if this Step has a direct successor
	 * that does not belong to the same chain, nor one of its subchains.
	 * @return TRUE if a successor of this Step exists outside this Step's Chain
	 * @throws M4Exception
	 */
	public boolean hasSuccessorOutsideChain() throws M4Exception;
	
	/**
	 * Return the parameter (tuple) of this step with the given name and loop number.
	 * 
	 * @param name the Name
	 * @param loopNr the loop number as in M4
	 */
	public Parameter getParameterTuple(String name, int loopNr) throws M4Exception;
	
	/**
	 * Returns the instance of the given <code>OpParam</code> that is currently set 
	 * in this Step. The returned <code>Collection</code> contains instances
	 * of <code>ParameterObject</code>s. For single parameters, only one
	 * object is contained in the collection; for array parameters, there can
	 * be more; for optional parameters, the collection can be empty.
	 * 
	 * @param theOpParam an OpParam object specifying the parameter to be returned
	 * @param loopNr the loop index for this parameter (ignored for non-loopable parameters)
	 * @return a Collection of ParameterObjects
	 * @throws M4Exception
	 */
	public Collection getParameter(OpParam theOpParam, int loopNr) throws M4Exception;
	
	/**
	 * Sets the parameter specified by the given <code>OpParam</code>. Depending
	 * on the type of parameter, the given <code>Collection</code> can contain
	 * exactly one (for a single parameter), or several (for an array parameter), 
	 * <code>ParameterObject</code>s. 
	 * 
	 * @param theOpParam an OpParam object specifying the parameter to be set
	 * @param theParameterObjects a Collection of ParameterObjects
	 * @param loopNr the loop index for this parameter (ignored for non-loopable parameters)
	 * @throws M4Exception
	 */
	public void setParameter(OpParam theOpParam, Collection theParameterObjects, int loopNr) throws M4Exception;
	
	/**
	 * This method checks, for the current set of values of input parameters 
	 * in this step, whether they fulfill all parameter contraints.
	 * If not, an exception is thrown whose message can be used by the
	 * GUI as an error message for the user. The user can then correct
	 * the corresponding parameter entry, then this method should be called
	 * again, until it returns TRUE and does not throw an exception. The method
	 * can be called before the output is created, as it will only check the
	 * validity of the input parameter values.
	 * 
	 * @return TRUE iff the current set of input parameters is valid
	 * for this step, in terms of all constraints holding for the parameters.
	 * 
	 * @throws M4Exception An exception carrying a meaningful error message,
	 * intended to direct the user to improve the parameter settings.
	 */
	public boolean checkInputParameterEntries() throws M4Exception;

	/**
	 * This method checks, for the current set of values of output parameters 
	 * in this step, whether they fulfill all parameter contraints.
	 * If not, an exception is thrown whose message can be used by the
	 * GUI as an error message for the user. The user can then correct
	 * the corresponding parameter entry, then this method should be called
	 * again, until it returns TRUE and does not throw an exception. 
	 * 
	 * @return TRUE iff the current set of output parameters is valid
	 * for this step, in terms of all constraints holding for the parameters.
	 * 
	 * @throws M4Exception An exception carrying a meaningful error message,
	 * intended to direct the user to improve the parameter settings.
	 */
	public boolean checkOutputParameterEntries() throws M4Exception;
	
	/**
	 * This method returns TRUE iff the given Feature may be displayed
	 * in the input concept, or in a list of Features to choose from for a
	 * parameter. If FALSE is returned, it means that the given Feature is
	 * constructed by a FeatureConstruction operator in a different branch
	 * of the chain of steps, thus the Feature has no meaning for this step.
	 *
	 * @param theFeature The feature for which visibility is tested
	 * @return TRUE iff the feature can be used in this Step
	 * @throws M4Exception
	 */
	public boolean isVisible(Feature theFeature) throws M4Exception;
	
	/**
	 * This method must only be called if no output objects existed
	 * for this Step before!
	 * This method creates the output concept or output feature(s) 
	 * for this step. What is to be created is specified by the given 
	 * OpParam object. The name(s) for the new object(s) are given 
	 * in the collection theNames. If there are both output concept AND
	 * output feature(s), please call this method FIRST with the concept!
	 * 
	 * @param theOpParam the OpParam object specifying which output parameter is meant
	 * @param theNames a Collection of Strings giving the name(s) for the new object(s)
	 * @throws M4Exception
	 */
	public void createOutput(OpParam theOpParam, Collection theNames) throws M4Exception;
	
	/**
	 * This method changes the names of the output parameter objects; the latter
	 * are assumed to exist. If the input parameters of the step have also changed,
	 * call the method <code>updateOutput</code> before this one. 
	 * 
	 * @param theOpParam the OpParam object specifying which output parameter is meant
	 * @param theNames a Collection of Strings giving the new name(s)
	 * @throws M4Exception
	 */
	public void renameOutput(OpParam theOpParam, Collection theNames) throws M4Exception;

	/**
	 * This method must only be called if any input parameter of this Step
	 * was changed. It ensures consistency of the output parameter objects
	 * with the input parameter objects. If the name of the output parameter
	 * has also changed, call the method <code>renameOutput</code> afterwards.
	 * 
	 * @param theOpParam the OpParam object specifying which output parameter is meant
	 * @throws M4Exception
	 */
	public void updateOutput(OpParam theOpParam) throws M4Exception;

	/**
	 * Returns TRUE iff a change to the given input OpParam can have any effect
	 * on the output parameters of this Step. For example, if the NewRangeMin-parameter
	 * of a Scaling-Step is changed then the output parameters are not affected. 
	 * In contrast, if the number of features selected in a manual FeatureSelection
	 * step changes, then the output concept must be updated.
	 * 
	 * @param theOpParam an input OpParam of the operator of this step
	 * @return TRUE if the output may have to be updated if the input was updated
	 * @throws M4Exception
	 */
	public boolean inputChangeCanAffectOutput(OpParam theOpParam)
	throws M4Exception;
	
	/**
	 * Whenever an input of type BaseAttribute or MultiColumnFeature is expected
	 * the possible Concepts the Features may come from are explicitly given by
	 * constraints. These constraints refer to the parameter names as used for the
	 * OpParam objects. This method returns a Collection of such OpParam names for
	 * input Concept parameters, e.g. &quotTheInputConcept&quot;.
	 *  
	 * @param opParam the <code>OpParam</code> parameter referring to an
	 *         input feature.
	 * @return a <code>Collection</code> consisting of the <code>OpParam</code>
	 *         names (Strings) of the <code>Concept</code>s this feature is
	 *         allowed to be selected from (due to an 'IN' constraint).
	 * @throws M4Exception
	 */
	public Collection getPossibleConceptsForParam(OpParam opParam) throws M4Exception;

	/**
	 * This method finds all Concepts that are either of type DB or are
	 * created as an output concept by a Step that precedes this Step in
	 * the chain.
	 * 
	 * @return a Collection of Concepts
	 * @throws M4Exception
	 */
	public Collection getPossibleInputConcepts() throws M4Exception;
	
	/**
	 * This method must only be called for an output feature. It is checked 
	 * whether the output feature is constrained to be IN the input concept.
	 * 
	 * @param outputFeature the OpParam representing the output feature
	 * @return TRUE iff the outputFeature's name should be selected from the
	 *         names of the features of the input concept; FALSE if any new
	 *         name can be given to the outputFeature.
	 */
	public boolean isContainedInInputConcept(OpParam outputFeature) throws M4Exception;
	
	/**
	 * Removes the link to the specified Predecessor.
	 */
	public void removePredecessor() throws M4Exception;

	/**
	 * Creates a Parameter that will be connected to this Step. The name of
	 * the Parameter must be unique for this Step.
	 * @param name The name for the new Parameter.
	 * @param object The parameter object. It must be a Concept, Relationship
	 * , BaseAttribute, MultiColumnFeature or Value
	 * @param number the parameter number
	 * @param loopNumber the loop number
	 * @param type the parameter type. Possible values are
	 * Parameter.TYPE_INPUT or Parameter.TYPE_OUTPUT
	 * @return The new Parameter object.
	 * @throws M4Exception
	 */
	Parameter createParameterTuple(
		String name,
		ParameterObject object,
		long number,
		int loopNumber,
		String type)
		throws M4Exception;

	/**
	 * Creates a Parameter and a Value that will be connected to this Step. The name of
	 * the Parameter must be unique for this Step. A Value object will be created
	 * that will be connected to the created Parameter.
	 * @param value The value for the Value Object.
	 * @param datatype The datatype for the value. Use one of the predefined types
	 * available for @link DomainDatatype
	 * @param name The name for the new Parameter.
	 * @param number the parameter number
	 * @param loopNumber the loop number
	 * @param type the parameter type. Possible values are
	 * Parameter.TYPE_INPUT or Parameter.TYPE_OUTPUT
	 * @return The new Parameter object.
	 * @throws M4Exception
	 */
	Parameter createValueParameterTuple(
		String value,
		String datatype,
		String name,
		long number,
		int loopNumber,
		String type)
		throws M4Exception;
}
/*
 * Historie
 * --------
 * 
 * $Log: Step.java,v $
 * Revision 1.6  2006/04/11 14:10:12  euler
 * Updated license text.
 *
 * Revision 1.5  2006/04/06 16:31:12  euler
 * Prepended license remark.
 *
 * Revision 1.4  2006/03/21 09:50:34  euler
 * *** empty log message ***
 *
 * Revision 1.3  2006/03/02 16:49:59  euler
 * Many bugfixes
 *
 * Revision 1.2  2006/01/18 16:58:58  euler
 * Added some basic estimations of statistics.
 * Will need improvements.
 *
 * Revision 1.1  2006/01/03 09:54:24  hakenjos
 * Initial version!
 *
 */
