#include <vector>

#include "caffe/layer.hpp"
#include "caffe/util/math_functions.hpp"
#include "caffe/vision_layers.hpp"

namespace caffe {

template <typename Dtype>
void ConcatCombLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
}

template <typename Dtype>
void ConcatCombLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  // Initialize with the first blob.
	//0: probe; 1:gallery
  //count_ = bottom[0]->count();
  num_ = bottom[1]->num();
  channels_ = bottom[0]->channels()+bottom[1]->channels();
  height_ = bottom[0]->height();
  width_ = bottom[0]->width();

  (*top)[0]->Reshape(num_, channels_, height_, width_);
  //CHECK_EQ(count_, (*top)[0]->count());
}

template <typename Dtype>
void ConcatCombLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  Dtype* top_data = (*top)[0]->mutable_cpu_data();

    const Dtype* probe_data = bottom[0]->cpu_data();
          const Dtype* gallery_data = bottom[1]->cpu_data();
      int num_elem0 = bottom[0]->channels()*bottom[0]->height()*bottom[0]->width();
      int num_elem1 = bottom[1]->channels()*bottom[1]->height()*bottom[1]->width();
      for (int n = 0; n < num_; ++n) {
    	  int offset_channel = 0;
        caffe_copy(num_elem0, probe_data+bottom[0]->offset(0),
          top_data+(*top)[0]->offset(n, offset_channel));
        offset_channel += bottom[0]->channels();
        caffe_copy(num_elem1, gallery_data+bottom[1]->offset(n),
                  top_data+(*top)[0]->offset(n, offset_channel));
      }

}

template <typename Dtype>
void ConcatCombLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {
	;
}

#ifdef CPU_ONLY
STUB_GPU(ConcatCombLayer);
#endif

INSTANTIATE_CLASS(ConcatCombLayer);

}  // namespace caffe
