#include <stdio.h>
#include "heat_wraper.h"
#include <opencv\cxcore.h>
#include <opencv\highgui.h>
#include <cuda_runtime.h>
#include <cuda_texture_types.h>



void init(cv::Mat* a){
	//float* img =	a->>ptr();
	//for (
}

int main(){
	// open video and write matrix
	//cv::VideoWriter vOut("heat.avi",CV_FOURCC_PROMPT,30.0,		cv::Size(DIM,DIM),false);
	CHeatTrasfer project(DIM,DIM);
	// Reserve Device memory
	float* deviceDataFront = project.reserveDeviceFloatMatrix();
	float* deviceDataBack = project.reserveDeviceFloatMatrix();
	float* deviceDataConst = project.reserveDeviceFloatMatrix();
	// Define texture identifiers


	// host memory
	float* hostData = project.reserveMatrix(false);
	// init const temp
	float* temp = project.initConstTemp();
	// open cv matrix to show results
	cv::Mat mat(DIM,DIM,cv::DataType<float>().type,hostData);
	cv::namedWindow("a");
	float a = 0.0f;
	float x = 0.0f;
	float dx = 0.1f;

	// define as texture memmory
	project.setUpTextureMemmory(deviceDataConst,deviceDataFront,deviceDataBack);
	bool swaped=false;	
	// initialize device const memory
	project.cudaCopy(temp,deviceDataConst,cudaMemcpyHostToDevice);
	project.cudaCopy(deviceDataConst,deviceDataBack,cudaMemcpyDeviceToDevice);
	while(cv::waitKey(3)<0){
		a = sin(x)/2.0f + 0.5f;
		printf("%f\n",a);
		if(swaped){
			deviceDataFront = project.backTex;
			deviceDataBack = project.frontTex;
		}else {
			deviceDataBack = project.backTex;
			deviceDataFront = project.frontTex;
		}
		project.cpy_const(deviceDataBack);
		project.blend(deviceDataFront,swaped);
		//project.setTo(a,deviceData);
		project.cudaCopy(deviceDataBack,hostData,cudaMemcpyDeviceToHost);
		cv::imshow("a",mat);
		// swap buffers
		swaped = !swaped; 
		x+=dx;
	}
	// cv::VideoCapture cap(
}

/*
// globals needed by the update routine
struct DataBlock {
    unsigned char   *output_bitmap;
    float           *dev_inSrc;
    float           *dev_outSrc;
    float           *dev_constSrc;
    CPUAnimBitmap   *bitmap;

    cudaEvent_t     start, stop;
    float           totalTime;
    float           frames;
};

void anim_gpu( DataBlock *d, int ticks ) {
    HANDLE_ERROR( cudaEventRecord( d->start, 0 ) );
    dim3    blocks(DIM/16,DIM/16);
    dim3    threads(16,16);
    CPUAnimBitmap  *bitmap = d->bitmap;

    for (int i=0; i<90; i++) {
        copy_const_kernel<<<blocks,threads>>>( d->dev_inSrc,
                                               d->dev_constSrc );
        blend_kernel<<<blocks,threads>>>( d->dev_outSrc,
                                          d->dev_inSrc );
        swap( d->dev_inSrc, d->dev_outSrc );
    }
    float_to_color<<<blocks,threads>>>( d->output_bitmap,
                                        d->dev_inSrc );

    HANDLE_ERROR( cudaMemcpy( bitmap->get_ptr(),
                              d->output_bitmap,
                              bitmap->image_size(),
                              cudaMemcpyDeviceToHost ) );

    HANDLE_ERROR( cudaEventRecord( d->stop, 0 ) );
    HANDLE_ERROR( cudaEventSynchronize( d->stop ) );
    float   elapsedTime;
    HANDLE_ERROR( cudaEventElapsedTime( &elapsedTime,
                                        d->start, d->stop ) );
    d->totalTime += elapsedTime;
    ++d->frames;
    printf( "Average Time per frame: %3.1f ms\n",
            d->totalTime/d->frames );
}
void anim_exit( DataBlock *d ) {
    cudaFree( d->dev_inSrc );
    cudaFree( d->dev_outSrc );
    cudaFree( d->dev_constSrc );

    HANDLE_ERROR( cudaEventDestroy( d->start ) );
    HANDLE_ERROR( cudaEventDestroy( d->stop ) );
}
*/