#include "ofQtUtils.h"


static bool bQuicktimeInitialized = true;

//----------------------------------------
void initializeQuicktime(){	
	if (bQuicktimeInitialized == true){	
		
		//----------------------------------
		// do we have quicktime installed at all?
		// http://www.apple.com/quicktime/download/win.html
		// can gestalt help with versions, or is that only after init?
		
		long			myAttrs;
		OSErr myErr 	= noErr;
		#ifdef TARGET_WIN32
			myErr = InitializeQTML(0);
			if (myErr != noErr){
				printf("----------------------------------------------------- \n");
				printf("sorry, there is a problem with quicktime starting up \nplease check!");
                OF_EXIT_APP(0);
			}
		#endif
		myErr = EnterMovies ();
		if (myErr != noErr){
			printf("----------------------------------------------------- \n");
			printf("sorry, there is a problem with quicktime starting up  \nplease check!");
			OF_EXIT_APP(0);
		}

		bQuicktimeInitialized = false;
	}
}



//----------------------------------------
void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){
	
	// ok for macs?
	// ok for intel macs?
	
	int * rgbaPtr 			= (int *) gWorldPixels;
	pix24 * rgbPtr 			= (pix24 *) rgbPixels;
	int totalPixelCount 	= w * h;
	unsigned char * rgbaStart;
	
	//	putting in the boolean, so we can work on 
	//	0,0 in top right...
	//	bool bFlipVertically 	= true;
	
	bool bFlipVertically 	= ofbOriginBottomLeft();
	
	// -------------------------------------------
	// we flip vertically because the 0,0 position in OF 
	// is the bottom left (not top left, like processing)
	// since the 0,0 of a picture is top left
	// if we upload and drawf the data as is
	// it will be upside-down....
	// -------------------------------------------
	
	if (!bFlipVertically){
		//----- argb->rgb
		for (int i = 0; i < h; i++){
			pix24 * rgbPtr 			= (pix24 *) rgbPixels + ((i) * w);
			for (int j = 0; j < w; j++){
				rgbaStart = (unsigned char *)rgbaPtr;	
				memcpy (rgbPtr, rgbaStart+1, sizeof(pix24));
				rgbPtr++;
				rgbaPtr++;
			}
		}
	} else {
		//----- flip while argb->rgb
		for (int i = 0; i < h; i++){
			pix24 * rgbPtr 			= (pix24 *) rgbPixels + ((h-i-1) * w);
			for (int j = 0; j < w; j++){
				rgbaStart = (unsigned char *)rgbaPtr;	
				memcpy (rgbPtr, rgbaStart+1, sizeof(pix24));
				rgbPtr++;
				rgbaPtr++;
			}
		}
	}
}


//----------------------------------------
// osx needs this for modal dialogs.  
Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){
	#pragma unused(theDialog, itemHit)  
  	Boolean  handled = false;
  	if ((theEvent->what == updateEvt) && 
    ((WindowPtr) theEvent->message == (WindowPtr) refCon))
  	{
    	BeginUpdate ((WindowPtr) refCon);
    	EndUpdate ((WindowPtr) refCon);
    	handled = true;
  	}
  	return (handled);
}


//----------------------------------------
void initGrabbingComponent(videoGrabberData * vgd, bool bVerbose) {
	
	if (vgd->bSgInited == true) return;		// don't do this twice
	
	OSErr err = noErr;
	
	vgd->gSeqGrabber = OpenDefaultComponent(SeqGrabComponentType, 0);
	
	err = GetMoviesError ();
	if (vgd->gSeqGrabber == NULL || err) {
		printf("error: can't get default sequence grabber component");
		return;
	}
	err = SGInitialize(vgd->gSeqGrabber);
	if (err != noErr) {
		printf("error: can't initialize sequence grabber component");
		return;
	}
	err = SGSetDataRef(vgd->gSeqGrabber, 0, 0, seqGrabDontMakeMovie);
	if (err != noErr) {
		printf("error: can't set the destination data reference");
		return;
	}
	
	// windows crashes w/ out gworld, make a dummy for now...
	// this took a long time to figure out. 
	err = SGSetGWorld(vgd->gSeqGrabber, 0, 0);
	if (err != noErr) {
		printf("error: setting up the gworld");
		return;
	}
	
	err = SGNewChannel(vgd->gSeqGrabber, VideoMediaType, &(vgd->gVideoChannel));
	if (err != noErr) {
		printf("error: creating a channel.  Check if you have any qt capable cameras attached\n");
		return;
	}
	
	vgd->bSgInited = true;
}
