#include "cvision.h"
#include "visiondefs.h"

#include <iostream>
#include <highgui.h>
#include <cv.h>
#include <cxcore.h>
#include <cvaux.h>

using namespace std;

CVision::CVision(void)
{
	m_pCap = cvCaptureFromCAM(-1);
	m_pImg = 0;
}


CVision::CVision(unsigned width, unsigned height, int device, int depth, int channels)
{
	m_pCap = cvCaptureFromCAM(device);
	m_pImg = cvCreateImage(cvSize(width,height), depth, channels);
}

CVision::CVision(CVision& vis)/*A REVER!!!!!*/
{
	if(vis.m_pImg == 0)
		m_pCap = cvCaptureFromCAM(-1);
	else
	{
//		m_pCap = new int;//CvCapture[1];
		m_pCap = vis.m_pCap;
		m_pImg = cvCreateImage(cvSize(vis.m_pImg->width,vis.m_pImg->height), vis.m_pImg->depth, vis.m_pImg->nChannels);
		cvCopy(m_pImg,m_pImg);
	}
}

CVision::~CVision()
{
}

void CVision::Display(void)
{
	cvNamedWindow("Default Window",CV_WINDOW_AUTOSIZE);

	cvShowImage("Default Window", m_pImg);
}

void CVision::Display(char *window_name)
{
	cvNamedWindow(window_name,CV_WINDOW_AUTOSIZE);

	cvShowImage(window_name, m_pImg);
}

void CVision::Refresh(void)
{
// 	IplImage* temp = cvCreateImage(cvSize(m_pImg->width,m_pImg->height), Gdepth, m_pImg->nChannels);
	m_pImg = cvQueryFrame(m_pCap);
// 	if( int n = m_pImg->width/Gwidth > 1)
// 	{
// 		IplImage* pyr = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), Gdepth, m_pImg->nChannels);
// 		cvPyrDown(temp, pyr, CV_GAUSSIAN_5x5);
// 		temp = pyr;
// 		if(n = temp->width/Gwidth > 1)
// 		{
// 			for(int i = 0; i < n; i++)
// 			{
// 				IplImage* pyr = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), Gdepth, m_pImg->nChannels);
// 				cvPyrDown(temp, pyr, CV_GAUSSIAN_5x5);
// 				temp = pyr;
// 			}
// 			cvCopy(temp, m_pImg, NULL);
// 			return;
// 		}
// 		else
// 		{
// 			cvCopy(temp, m_pImg, NULL);
// 			return;
// 		}
// 	}
// 	cout << "mpimg.w=" << m_pImg->width << "\ttemp.w=" << temp->width;// << "\tscale=" << n;
// 	cvCopy(temp, m_pImg, NULL);
// 	double n = (double)m_pImg->width / temp->width;

// 
// 	cvConvertScale(temp, m_pImg, n, 0);
}


void CVision::CapnSave(char *dest)
{
	m_pImg = cvQueryFrame(m_pCap);

	cvSaveImage(dest, m_pImg);
}

int CVision::DetectColor(HSVColour color, CVision* visarr[], char* index[])
{
	//Imagens de manipulação
	visarr[0]->m_pImg = cvCloneImage(m_pImg);
	index[0]="Imagem Filtrada";
	visarr[1]->m_pImg = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 3);
	//visarr[0]->imgpc = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 3);
	index[1]="PyrDown da Imagem Original";
	visarr[2]->m_pImg = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 3);
	index[2]="Imagem no espaço HSV";
	//Componentes da imagem HSV
	visarr[3]->m_pImg = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);
	index[3]="Componente H";
	visarr[4]->m_pImg = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);
	index[4]="Componente S";
	visarr[5]->m_pImg = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);
	index[5]="Componente V";

	IplImage *h_filter = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);
	IplImage *s_filter = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);
	IplImage *v_filter = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);

	visarr[6]->m_pImg = cvCreateImage(cvSize(m_pImg->width/2,m_pImg->height/2), m_pImg->depth, 1);
	index[6]="Filtro de Cor";

	//Aplicação de filtros para detecção de cor

	//Redução do tamanho da imagem através de um Pyramid Down que torna o valor de uma pixel como a media do valor do dois correspondentes na imagem original
	cvPyrDown(visarr[0]->m_pImg, visarr[1]->m_pImg, CV_GAUSSIAN_5x5 );
	//Conversão de imagem para HSV para que se possam aplicar os filtros
	cvCvtColor(visarr[1]->m_pImg, visarr[2]->m_pImg, CV_RGB2HSV);
	//Divisão da imagem nas suas componentes H, S e V
	cvSplit(visarr[2]->m_pImg, visarr[3]->m_pImg, visarr[4]->m_pImg, visarr[5]->m_pImg, NULL);
	//Comparação da imagem H(Hue->Tonalidade) com o escalar correspondente a
	//cvCmpS(h, 50.0, imgpc, CV_CMP_GT);
	//Filtros nas Componentes H, S e V
	cvInRangeS(visarr[3]->m_pImg, cvScalar(color.Hlow), cvScalar(color.Hhigh), h_filter);
	cvInRangeS(visarr[4]->m_pImg, cvScalar(color.Slow), cvScalar(color.Shigh), s_filter);
	cvInRangeS(visarr[5]->m_pImg, cvScalar(color.Vlow), cvScalar(color.Vhigh), v_filter);
	//Adição dos filtros
	cvAnd(h_filter, s_filter, visarr[6]->m_pImg, v_filter);

	cvCopy(visarr[0]->m_pImg, visarr[1]->m_pImg, visarr[6]->m_pImg);

	return 0;
}
// 
// bool DetectShape(char *shape);
// {
// }

void CVision::AddText(char *text)
{
	CvFont font;
	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 2, 8 );
	cvPutText(m_pImg, text, cvPoint(0,25), &font, CV_RGB(100,100,255));
}


void CVision::AddText(char *text, int posx, int posy)
{
	CvFont font;
	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 2, 8 );
	cvPutText(m_pImg, text, cvPoint(posx,posy), &font, CV_RGB(100,100,255));
}

// CVision& CVision::operator=(const CVision& vis)/*A REVER!!!!!*/
// {
// 	if(this != &vis)
// 	{
// 		m_pCap = vis.m_pCap;
// 		if(m_pImg == 0)
// 			m_pImg = cvCreateImage(cvSize(vis.m_pImg->width,vis.m_pImg->height), vis.m_pImg->depth, vis.m_pImg->nChannels);
// 		*(this->m_pImg) = cvCloneImage(vis.m_pImg);
// 		m_uDepth = vis.m_uDepth;
// 		m_uChannels = vis.m_uChannels;
// 	}
// 	return *this;
// }
