#include "..\include\iANRCR.h"
#include <opencv2/core/core.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>
#include "Windows.h"

using namespace cv;

int main(int argc, char* argv[])
{
	// вывод помощи
	if (argc == 1)
	{
		printf("%s format\n", argv[0]);
		printf("%s -cam  file.avi\n", argv[0]); // Проигрывание видео с начала с заданным в программе размером цифр
		printf("%s -camf  file.avi frame\n", argv[0]); // Проигрывание видео с кадра frame с заданным в программе размером цифр
		printf("%s -camf  file.avi frame size\n", argv[0]); // Проигрывание видео с кадра frame с  размером цифр size
		printf("%s -img  img.png\n", argv[0]); // Распознавание изображения
		printf("%s -img  img.png size\n", argv[0]); // Распознавание изображения с размером цифр size
		return 0;
	}
	int baseline = 0;
	int fontFace = cv::FONT_HERSHEY_SIMPLEX;
	double fontScale = 1;
	int thickness = 1;

	IN_ANRCR in_param = { 18, iANRCR_NO_LOW_REL };//высоту цифр в пикселях нужно определять заранее
	OUT_ANRCR out_param;

	// Работа с видео
	if (argc > 1 && (strcmp(argv[1], "-cam") == 0 || strcmp(argv[1], "-camf") == 0) )
	{
		cv::VideoCapture *inputVideo = 0;
		if (argc > 2 ) inputVideo = new cv::VideoCapture(argv[2]);
		else inputVideo = new cv::VideoCapture(0);
		if (inputVideo->isOpened())
		{
			cv::Size S = cv::Size((int)inputVideo->get(CV_CAP_PROP_FRAME_WIDTH)/2,    // Acquire input size
				(int)inputVideo->get(CV_CAP_PROP_FRAME_HEIGHT)/2); // Сделано, если входные цифры большие ( больще 36 пикселей в высоту)

			cv::VideoWriter outputVideo;
			outputVideo.open("out.avi", CV_FOURCC('D', 'I', 'V', '3'), 30, S, true);

			if (argc > 3)
				if (strcmp(argv[1], "-camf") == 0) 
					inputVideo->set(CV_CAP_PROP_POS_FRAMES, atoi(argv[3]));
			if (argc > 4)
				in_param.mean_height_characters = atoi(argv[4]);
			Mat frame;
			int count = 0;
			int num = 0;
			char mem_num[256] = { 0 };
			char buf[256];

			void* sum = CreateSumBuf(30, 5);
			char out[20];			
			for (;;)
			{
				*inputVideo >> frame;
				if (frame.empty())
					break;

				Mat dist(frame.size(), frame.type());;
				//DIST_DATA dist_data = { 153,151,35,68,124,129,131,128 };
				DIST_DATA dist_data = { 128,128,128,128,128,128,128,128 };
				CorrectDistorsionANRCR(frame, dist, dist_data); // Если дисторсии нет (все параметры 128), то не надо вызывать, но тогда нужно исправить ниже

				Mat dist2;
				cv::resize(dist, dist2, cv::Size(frame.size().width / 2, frame.size().height / 2));

				out_param = iANRCR(dist2, in_param);
				int size_ = 20;
				int res;
				if (out_param.all_objects > 0)
				{
			
					cv::rectangle(dist2, cvPoint(out_param.objects[0].rect_number.x, out_param.objects[0].rect_number.y),
						cvPoint(out_param.objects[0].rect_number.x + out_param.objects[0].rect_number.width,
							out_param.objects[0].rect_number.y + out_param.objects[0].rect_number.height), CV_RGB(255, 255, 0), 2);
	

					CvPoint pp2, pp1;
					pp2.x = out_param.objects[0].rect_number.x;
					pp2.y = out_param.objects[0].rect_number.y;
					pp1.x = out_param.objects[0].rect_number.x + 1;
					pp1.y = out_param.objects[0].rect_number.y + 1;

					// Тест
					sprintf(buf, "%s:%.3f", out_param.objects[0].number, out_param.objects[0].reliability);
					cv::putText(dist2, buf, cv::Point( 41,41), fontFace, fontScale,
						CV_RGB(128, 000, 128), thickness, 8);
					cv::putText(dist2, buf, cv::Point(40, 40), fontFace, fontScale,
						CV_RGB(255, 000, 255), thickness, 8);

					// сравнение с памятью
					if (strcmp(out_param.objects[0].number, mem_num) == 0)
					{
						cv::putText(dist2, out_param.objects[0].number, pp1, fontFace, fontScale,
							CV_RGB(128, 000, 0), thickness, 8);
						cv::putText(dist2, out_param.objects[0].number, pp2, fontFace, fontScale,
							CV_RGB(255, 000, 0), thickness, 8);
					}

					// Суммирование					
					 res = ProcessSumBuf(sum, out_param.objects[0].number, strlen(out_param.objects[0].number), out, &size_);					
				}//if (out_param.all_objects > 0)
				else
					res = ProcessSumBuf(sum, "", 0, out, &size_);
				if (res == 0)
				{
					std::string str = out;
					int baseline = 0;
					cv::Size textSize = cv::getTextSize(str, fontFace,
						fontScale, thickness, &baseline);
					baseline += thickness;
					cv::rectangle(dist2, cv::Point(40, dist2.rows - 40),
						cv::Point(40 + textSize.width, dist2.rows - 40 - textSize.height), CV_RGB(255, 255, 255), CV_FILLED);
					cv::putText(dist2, str, cv::Point(40, dist2.rows - 40), fontFace, fontScale,
						CV_RGB(255, 0, 0), thickness, 8);
				}
				mem_num[0] = 0;
				if (out_param.all_objects > 0)
					strcpy_s(mem_num, 256, out_param.objects[0].number);
				
				sprintf(buf, "frame: %d", num);
				cv::putText(dist2, buf, cvPoint(41, dist2.rows-1), fontFace, fontScale,
					CV_RGB(100, 100, 0), thickness, 8);
				cv::putText(dist2, buf, cvPoint(40, dist2.rows - 2), fontFace, fontScale,
					CV_RGB(200, 200, 0), thickness, 8);

				imshow("result", dist2);

				outputVideo << dist2;

				DeleteOutANRCR(&out_param);

				int c = cv::waitKey(10);
				if (c == 27)
					break;
				printf("%d\n", num);
				num++;
			}

			DeleteSumBuf(&sum);
			delete inputVideo;
		}
		return 0;
	}
	// Работа с единственным изображением
	if (argc > 2 && strcmp(argv[1], "-img") == 0)
	{
		Mat frame = imread(argv[2]);
		if (!frame.empty())
		{
			if (argc > 3)
				in_param.mean_height_characters = atoi(argv[3]);
			Mat dist(frame.size(), frame.type());

			out_param = iANRCR(frame, in_param);
			if (out_param.all_objects > 0)
			{
				printf("Result: %s.\n", out_param.objects[0]);
			}
		}
		return 0;
	}

	
	return 0;
}