#include "ofSeeSawVideoGrabber.h"


OSErr
ofSeeSawVideoGrabber::videoInitOffscreen (int width, int height)
{
	OSErr err;
	
	// create the offscreen target
	dstPortBounds.left = 0;
	dstPortBounds.right = width;
	dstPortBounds.top = 0;
	dstPortBounds.bottom = height;
	
	gworldBuf				= (unsigned char*)malloc(4 * width * height + 32);
	rgbPixels				= new unsigned char[width*height*3];
	if (err = QTNewGWorldFromPtr(&dstPort, k32ARGBPixelFormat, &dstPortBounds, NULL, NULL, 0, gworldBuf, width*4))
	{
		printf("createOffscreenGWorld err=%d\n", err);
		goto endFunc;	
	}
	
	// Get buffer from GWorld
	pDstData			= GetPixBaseAddr(GetGWorldPixMap(dstPort));
	dstDataSize			= GetPixRowBytes(GetGWorldPixMap(dstPort)) * (dstPortBounds.bottom - dstPortBounds.top); 
	dstDisplayBounds	= dstPortBounds;
	
endFunc:
	return err;
}





//--------------------------------------------------------------
void ofSeeSawVideoGrabber::initGrabber(int w, int h){	 
	
	camWidth 		= w;	// try to grab at this size. 
	camHeight 		= h;
	width = w;
	height = h;
	
	videoTexture.allocate(camWidth,camHeight, GL_RGB);
	
	
	OSErr err;
	
	if(!(pVdg = vdgNew()))
	{
		printf("vdgNew: failed to allocate\n");	
		goto endFunc;
	}
	
	if(err = vdgInit(pVdg))
	{
		printf("vdgInit err=%d\n", err);
		goto endFunc;
	}
	
	if(err = vdgLoadSettings(pVdg))  // request is diff 
	{
		printf("vdgRequestSettings err=%d\n", err);
		goto endFunc;
	}
	
	if(err = vdgPreflightGrabbing(pVdg))
	{
		printf("vdgPreflightGrabbing err=%d\n", err);
		goto endFunc;
	}
	
	// Set the timer frequency from the Vdig's Data Rate
	//videoSetTimerPeriodFromVdig(pWnd);
	
    vdImageDesc = (ImageDescriptionHandle)NewHandle(0);
	if (err = vdgGetImageDescription( pVdg, 
									 vdImageDesc))
	{
		printf("vdgGetImageDescription err=%d\n", err);
		goto endFunc;
	}
	
	// Now create the offscreen GWorld to match the texture
	if (err = videoInitOffscreen(camWidth, camWidth))
	{
		printf("videoInitOffscreen err=%d\n", err);
		goto endFunc;
	}
	
	// Set the decompression destination to the offscreen GWorld
	if (err = vdgSetDestination(	pVdg,
								dstPort ))
	{
		printf("vdgGetImageDescription err=%d\n", err);
		goto endFunc;	
	}
	
	// Set the display bounds to match only the part of the texture
	// that corresponds to the video image
	//videoSetDisplayBoundsToCaptureBounds(pWnd);
	
	if (err = vdgStartGrabbing(pVdg))
	{
		printf("vdgStartGrabbing err=%d\n", err);
		goto endFunc;
	}


	endFunc:
		return;
	
}


//--------------------------------------------------------------
void ofSeeSawVideoGrabber::grabFrame(){
	
	bIsFrameNew = false;
	OSErr	err;
	int		isUpdated = 0;
	
	// Stop the timer is we're not grabbing
	if (!vdgIsGrabbing( pVdg))
		return;
	
	if (err = vdgIdle( pVdg, &isUpdated))
	{
		printf("vdgIdle err=%d\n", err);
		return;
	}
	
	if (isUpdated){
		convertPixels((unsigned char *)pDstData, rgbPixels, camWidth,camHeight);
		videoTexture.loadData( rgbPixels, camWidth, camHeight, GL_RGB);
		bIsFrameNew = true;
	}
	

}

void ofSeeSawVideoGrabber::videoSettings(){
	
	OSErr err;
	if(err = vdgRequestSettings(pVdg))  // request is diff 
	{
		printf("vdgRequestSettings err=%d\n", err);
		return;
	}
	
	
}

//--------------------------------------------------------------
void ofSeeSawVideoGrabber::draw(int x, int y){
	draw(x,y,camWidth, camHeight);
}

void ofSeeSawVideoGrabber::draw(int x, int y, int w, int h){
	videoTexture.draw(x,y,w,h);
}
