/*
 *  Copyright (c) 2008 Cyrille Berger <cberger@cberger.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version of the License.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef _OPENSHIVA_KERNEL_H_
#define _OPENSHIVA_KERNEL_H_

#include <list>

namespace GTLCore {
  class AbstractImage;
  class ModuleData;
  class ProgressReport;
  class RegionI;
}

#include <OpenShiva/Library.h>

#include <GTLCore/ChannelsFlags.h>
#include <GTLCore/Macros.h>
#include <GTLCore/Transform.h>

namespace OpenShiva {
  struct KernelPrivate;
  /**
   * @ingroup OpenShiva
   * This is the main class in OpenShiva, it is used to compile the kernel, and to apply it on
   * a set of images.
   */
  class OPENSHIVA_EXPORT Kernel : public Library {
    friend class CodeGenerator;
      GTL_NO_COPY(Kernel);
    public:
      /**
       * @param indicates the number of channel for the 'pixel' and 'image' type
       */
      Kernel(int _channelsNb = 4 );
      ~Kernel();
    public: // Function call
      void evaluatePixels( const GTLCore::RegionI& _region, const std::list< const GTLCore::AbstractImage* >& _inputImages, GTLCore::AbstractImage* _outputImage, GTLCore::ProgressReport* report = 0, const GTLCore::Transform& transfo = GTLCore::Transform(), const GTLCore::ChannelsFlags& flags = GTLCore::ChannelsFlags()) const;
      /**
       * Run the function called "int runTest()" in the Kernel.
       */
      int runTest() const;
      /**
       * @return true if the test function is available
       */
      bool hasTestFunction() const;
      
      GTLCore::RegionF needed( GTLCore::RegionI output_region, int input_index, const std::list< GTLCore::RegionI>& input_DOD, const GTLCore::Transform& transfo = GTLCore::Transform());
      bool hasNeededFunction() const;
      GTLCore::RegionF changed( GTLCore::RegionI changed_input_region, int input_index, const std::list< GTLCore::RegionI>& input_DOD, const GTLCore::Transform& transfo = GTLCore::Transform());
      bool hasChangedFunction() const;
      GTLCore::RegionF generated(const GTLCore::Transform& transfo = GTLCore::Transform());
      bool hasGeneratedFunction() const;
    public:
      enum StandardParameter {
        IMAGE_WIDTH,
        IMAGE_HEIGHT
      };
      /**
       * Set one of the hint.
       */
      void setParameter( StandardParameter _parameter, const GTLCore::Value& _value);
      /**
       * Set a given parameter to a given value
       */
      void setParameter( const GTLCore::String& _name, const GTLCore::Value& );
      /**
       * Set a given parameter to a given value
       */
      void setParameter( size_t _id, const GTLCore::Value& _value );
      /**
       * @return the id of a parameter
       */
      std::size_t parameterId( const GTLCore::String& _name );
      /**
       * Set a list of parameters
       */
      void setParameters( const std::map< GTLCore::String, GTLCore::Value>&  );
    private:
      KernelPrivate * const d;
  };
}

#endif
