


#ifndef DATAFLOW_NETWORK_MODULEREEXECUTIONSTRATEGIES_H
#define DATAFLOW_NETWORK_MODULEREEXECUTIONSTRATEGIES_H

#include <boost/lexical_cast.hpp>
#include <Dataflow/Network/ModuleInterface.h>
#include <Dataflow/Network/PortManager.h>
#include <Dataflow/Network/share.h>

namespace SCIRun {
namespace Dataflow {
namespace Networks {

  class SCISHARE AlwaysReexecuteStrategy : public ModuleReexecutionStrategy
  {
  public:
    bool needToExecute() const override { return true; }
  };

  class SCISHARE InputsChangedChecker
  {
  public:
    virtual ~InputsChangedChecker() {}

    virtual bool inputsChanged() const = 0;
  };

  typedef SharedPointer<InputsChangedChecker> InputsChangedCheckerHandle;

  class SCISHARE StateChangedChecker
  {
  public:
    virtual ~StateChangedChecker() {}

    virtual bool newStatePresent() const = 0;
  };

  typedef SharedPointer<StateChangedChecker> StateChangedCheckerHandle;

  class SCISHARE OutputPortsCachedChecker
  {
  public:
    virtual ~OutputPortsCachedChecker() {}

    virtual bool outputPortsCached() const = 0;
  };

  typedef SharedPointer<OutputPortsCachedChecker> OutputPortsCachedCheckerHandle;

  class SCISHARE DynamicReexecutionStrategy : public ModuleReexecutionStrategy
  {
  public:
    DynamicReexecutionStrategy(
      InputsChangedCheckerHandle inputsChanged,
      StateChangedCheckerHandle stateChanged,
      OutputPortsCachedCheckerHandle outputsCached);
    bool needToExecute() const override;
  private:
    InputsChangedCheckerHandle inputsChanged_;
    StateChangedCheckerHandle stateChanged_;
    OutputPortsCachedCheckerHandle outputsCached_;
  };

  class SCISHARE InputsChangedCheckerImpl : public InputsChangedChecker
  {
  public:
    explicit InputsChangedCheckerImpl(const Module& module);
    bool inputsChanged() const override;
  private:
    const Module& module_;
  };

  class SCISHARE StateChangedCheckerImpl : public StateChangedChecker
  {
  public:
    explicit StateChangedCheckerImpl(const Module& module);
    bool newStatePresent() const override;
  private:
    const Module& module_;
  };

  class SCISHARE OutputPortsCachedCheckerImpl : public OutputPortsCachedChecker
  {
  public:
    explicit OutputPortsCachedCheckerImpl(const Module& module);
    bool outputPortsCached() const override;
  private:
    const Module& module_;
  };

  class SCISHARE DynamicReexecutionStrategyFactory : public ReexecuteStrategyFactory
  {
  public:
    explicit DynamicReexecutionStrategyFactory(const boost::optional<std::string>& reexMode);
    ModuleReexecutionStrategyHandle create(const Module& module) const override;
  private:
    boost::optional<std::string> reexecuteMode_;
  };

}}}

#endif
