/*
 * Copyright 2017 Jan Dorazil <deu439@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef SLIDINGHISTOGRAM_HPP
#define SLIDINGHISTOGRAM_HPP

#include <opencv2/opencv.hpp>

using namespace cv;
class SlidingHistogram
{
public:
  typedef uint16_t binType;
  typedef float simType;
  typedef int imType;
  
private:
  Size mDim;
  int mNChannels;
  int mNBins;
  imType mMaxVal;

public:
  SlidingHistogram(Size dim, int nchannels, int nbins,
                   imType maxval = std::numeric_limits<imType>::max());
  void compute(InputArray image, Size size, std::vector<int> &desc);
  void integralHistogram(InputArray image, std::vector<binType> &hist);
  void integralHistogramVM(InputArray val, InputArray mag,
                           std::vector<binType>& hist);
  void integralHistogramJoint( InputArray val, InputArray mag,
                               std::vector<binType>& hist, int nmag);
  
  void compare(std::vector<binType> &h1, std::vector<binType> &h2,
               Size size, OutputArray out);
  void regionHistogram(const std::vector<binType> &integral, 
                              const Rect &region,
                              std::vector<binType> &out);

  
private:
  void calcHist(Mat_<uchar> image, Size size, int *desc);
  void wavefrontScan(Mat_<imType> image, binType *hist);
  void wavefrontScanVM(Mat_<imType> val, Mat_<imType> mag,
                       binType* hist);
  void wavefrontScanJoint(Mat_<imType> val, Mat_<imType> mag,
                          binType* hist, int nmag);
  void compSingle(const binType *h1, const binType *h2,
                  Size size, Mat_<simType> out);
  inline void sumHist(binType *hist1, binType *hist2,
                      binType *hist3, binType *out);
  inline void regionHist(const binType *hist00, const binType *hist01, 
                         const binType *hist10, const binType *hist11,
                         binType *out);
  inline simType compHist(binType *hist1, binType *hist2,
                          const Size &size);
  inline void histMatch(const binType *temp, const binType *hist, binType *out);
  inline int histMean(const binType *hist, const Size &size);
};

#endif // SLIDINGHISTOGRAM_HPP
