#include <jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <vector>
#include <sstream>

#include "mycv.h"

using namespace std;
using namespace cv;

extern "C" {
JNIEXPORT void JNICALL Java_sliz_elektromery_CamActivity_FindFrame(JNIEnv*,
		jobject, jlong addrRgba, jlong addrRects);

JNIEXPORT void JNICALL Java_sliz_elektromery_CamActivity_AdjFrame(JNIEnv*,
		jobject, jlong addrRgba, jlong addrRect);

JNIEXPORT void JNICALL Java_sliz_elektromery_PicActivity_FindFrame(
		JNIEnv*, jobject, jlong addrRgba, jlong addrRects);

JNIEXPORT void JNICALL Java_sliz_elektromery_PicActivity_SegmentDigits(JNIEnv*,
		jobject, jlong addrRgba, jlong addrFeaturePattern, jlong addrANNTest);

	inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat)
	{
	    mat = Mat(v_rect, true);
	}

	JNIEXPORT void JNICALL Java_sliz_elektromery_CamActivity_FindFrame(JNIEnv*, jobject, jlong addrRgba, jlong addrRects)
	{
		Mat& mRgb = *(Mat*)addrRgba;

		// Locate counter
		mycv cMyCV;
		vector<Rect> RectFaces;
		cMyCV.detectFrame(mRgb, mRgb, RectFaces);
		vector_Rect_to_Mat(RectFaces, *((Mat*)addrRects));
	}

	JNIEXPORT void JNICALL Java_sliz_elektromery_CamActivity_AdjFrame(JNIEnv*, jobject, jlong addrRgba, jlong addrRect)
	{
		Mat& mRgb = *(Mat*)addrRgba;
		Mat& mRect = *(Mat*)addrRect;
		// Adjust frame according to first scan
		vector<Rect> rects;
		for(int i = 0 ; i < mRect.rows ; i++)
		{
			rects.push_back(mRect.at<Rect>(i, 0));
		}

		mycv cMyCV;

		cMyCV.adjustFrame(mRgb, mRgb, rects);

		vector_Rect_to_Mat(rects, mRect);
	}

	JNIEXPORT void JNICALL Java_sliz_elektromery_PicActivity_FindFrame(JNIEnv*, jobject, jlong addrRgba, jlong addrRects)
	{
		Mat& mRgb = *(Mat*)addrRgba;

		double scaleFactor = (double)800/mRgb.cols;
		if(mRgb.cols > 800)
			resize(mRgb, mRgb, Size(), scaleFactor, scaleFactor, INTER_CUBIC);

		// Locate counter
		mycv cMyCV;
		vector<Rect> RectFaces;
		cMyCV.detectFrame(mRgb, mRgb, RectFaces);

		// find largest rect
		int max = 0;
		int maxIndx = 0;
		for(int i = 0 ; i < RectFaces.size() ; i++)
		{
			if(max < RectFaces[i].width*RectFaces[i].height)
			{
				max = RectFaces[i].width*RectFaces[i].height;
				maxIndx = i;
			}
		}

//		mRgb = mRgb(RectFaces[maxIndx]).clone();
		vector<Rect> bestRect;
		bestRect.push_back(RectFaces[maxIndx]);
		cMyCV.adjustFrame(mRgb, mRgb, bestRect);

		vector_Rect_to_Mat(RectFaces, *((Mat*)addrRects));
	}

	JNIEXPORT void JNICALL Java_sliz_elektromery_PicActivity_SegmentDigits
	(JNIEnv*, jobject, jlong addrRgba, jlong addrFeaturePattern, jlong addrANNTest)
	{
		Mat& mRgb = *(Mat*)addrRgba;
		Mat& mPatt = *(Mat*)addrFeaturePattern;
		Mat& mANNTest = *(Mat*)addrANNTest;

		// Segment digits
		mycv cMyCV;
		vector<Mat> digits;

		// Digits segmentation
		cMyCV.segmentDigits(mRgb, mRgb, digits, mPatt);

		/// Create test mat for ANN

		for(int i = 0 ; i < digits.size() ; i ++)
		{
			Mat row = digits[i].reshape(0, 1);
			mANNTest.push_back(row);
		}
		mANNTest.convertTo(mANNTest, CV_32FC1);

	}
}
