#pragma once
#include <opencv2/opencv.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/vector.hpp>
 
BOOST_SERIALIZATION_SPLIT_FREE(::cv::Mat)
namespace boost {
  namespace serialization {
 
    /** Serialization support for cv::Mat */
    template <class Archive>
    void save(Archive & ar, const ::cv::Mat& mat, const unsigned int version)
    {
      int cols, rows, type;
      bool continuous;
      cols = mat.cols; rows = mat.rows; type = mat.type();
      continuous = mat.isContinuous();
      //      std::cerr << cols << ", "<< rows << ", " << type << ", " << continuous << std::endl;

      ar & cols & rows & type & continuous;

      if (continuous) {
        const unsigned int data_size = rows * cols * mat.elemSize();
        ar & boost::serialization::make_array(mat.ptr(), data_size);
      } else {
        const unsigned int row_size = cols*mat.elemSize();
        for (int i = 0; i < rows; i++) {
	  ar & boost::serialization::make_array(mat.ptr(i), row_size);
        }
      }
    }

    /** Serialization support for cv::Mat */
    template  <class Archive>
    void load(Archive & ar, ::cv::Mat& mat, const unsigned int version)
    {
      int cols, rows, type;
      bool continuous;
      
      ar & cols & rows & type & continuous;
      
      //      std::cerr << cols << ", "<< rows << ", " << type << ", " << continuous << std::endl;
      mat.create(rows, cols, type);
      if (continuous) {
        const unsigned int data_size = rows * cols * mat.elemSize();
        ar & boost::serialization::make_array(mat.ptr(), data_size);
      } else {
        const unsigned int row_size = cols*mat.elemSize();
        for (int i = 0; i < rows; i++) {
	  ar & boost::serialization::make_array(mat.ptr(i), row_size);
        }
      }
    }
  }
}
