#import "tlController.h"

@implementation tlController

int theHeight;

- (void)awakeFromNib
{
    //NSLog(@"awakeFromNib");
    NSConnection *theConnection = [NSConnection defaultConnection];

    [theConnection setRootObject:self];
    if ([theConnection registerName:@"mhImageHelper"] == NO) {
      NSLog(@"Failed to register name");
    }

    [theConnection retain];
    [theConnection setDelegate:self];
    
    [self clear];
    [NSApp hide:self];
    [window makeKeyAndOrderFront:nil];
    [window orderOut:nil];
    
    theHeight = 32;
}

- (BOOL)openMovie:(NSURL *)url
{
    //NSLog(@"openMovie");
    if ([url isEqual:currentURL]) return YES;
    [self clear];
    if (nil == url) return NO;
    currentMovie = [[NSMovie alloc] initWithURL:url byReference:NO];
    currentURL = [[url copy] retain];
    [self initMovie];
    return YES;
}

- (void)setHeight:(int)height
{
    //NSLog(@"setHeight");
    theHeight = height;
}

- (void)debug
{
    NSLog(@"debug");
}

- (NSData *)getImage:(TimeValue)time
{
    //NSLog(@"getImage");
    return [self getImage:time sender:nil];
}

- (NSData *)getImage:(TimeValue)time sender:(NSString *)senderID
{
    //NSLog(@"getImage:sender");
    return [self getImage:time sender:senderID transparency:nil];
}

- (NSData *)getImage:(TimeValue)time sender:(NSString *)senderID transparency:(NSColor *)keyColor
{
    //NSLog(@"getImage:sender:transparency");
    NSImage *image = nil;
    //id metahoot = [NSConnection rootProxyForConnectionWithRegisteredName:senderID host:nil];
    //if (nil == metahoot)
    //    [NSApp terminate:nil];
    if (nil == currentMovie)
        return nil;
    SetMovieTimeValue([currentMovie QTMovie], time);
    MoviesTask(gMovie, 0);
    image = [self gworldToNSImage:gSrcGWorld transparency:keyColor];
    
    NSData *data = [NSArchiver archivedDataWithRootObject:image];
    //[metahoot image:data forTimeValue:time];
    NSLog(@"Data size: %d", [data length]);
    return data;
}

- (void)quit
{
    //NSLog(@"quit");
    [NSApp terminate:nil];
}

- (void)initMovie
{
    //NSLog(@"initMovie");
    OSErr err = noErr;
    if (nil == currentMovie)
        return;
    gMovie = [currentMovie QTMovie];
    Rect box;
    GetMovieBox(gMovie, &box);
    Rect srcRect, portRect;
    srcRect.top = srcRect.left = 0;
    srcRect.bottom = theHeight;
    srcRect.right = movieWidth = (box.right - box.left) * theHeight / (box.bottom - box.top);
    [fakeMovieView setMovie:currentMovie];
    SetMovieBox(gMovie, &srcRect);
    // http://developer.apple.com/qa/qtmtb/qtmtb57.html
    err = NewGWorld(&gSrcGWorld,
                k32ARGBPixelFormat,
                &srcRect,
                NULL,
                NULL,
                0);
        /* make sure to lock the PixMap */
    LockPixels(GetGWorldPixMap(gSrcGWorld));
        /* erase */
    SetGWorld(gSrcGWorld,NULL);
    GetPortBounds(gSrcGWorld, &portRect);
    EraseRect(&portRect);
        /* tell the movie to draw into the GWorld */
    SetMovieGWorld(gMovie, gSrcGWorld,  GetGWorldDevice(gSrcGWorld));
    [fakeMovieView setMovie:nil];
}

- (void)clear
{
    //NSLog(@"clear");
    //theScale = 0;
    //theDuration = 0;
    currentMovie = nil;
    currentURL = nil;
    gMovie = nil;
    gSrcGWorld = nil;
}


//////////
//
// gworldToNSImage
//
// convert contents of a gworld to an NSImage 
// CocoaVideoFrameToNSImage sample code from the mothership
// http://developer.apple.com/samplecode/Sample_Code/QuickTime/Basics/CocoaVideoFrameToNSImage.htm
//
//////////

-(NSImage *)gworldToNSImage:(GWorldPtr) gWorldPtr
{
    return [self gworldToNSImage:gWorldPtr transparency:nil];
}

-(NSImage *)gworldToNSImage:(GWorldPtr) gWorldPtr transparency:(NSColor *)keyColor
{
    //NSLog(@"gworldToNSImage");
    PixMapHandle 		pixMapHandle = NULL;
    Ptr 				pixBaseAddr = nil;
    NSBitmapImageRep 	*imageRep = nil;
    NSImage 			*image = nil;
    
    float keyR = 0, keyB = 0, keyG = 0, keyA = 0;
    unsigned char KeyR = 0, KeyG = 0, KeyB = 0, KeyA = 0;
    if (keyColor) {
        keyColor = [keyColor colorUsingColorSpaceName:@"NSCalibratedRGBColorSpace"];
        [keyColor getRed:&keyR green:&keyG blue:&keyB alpha:&keyA];
        KeyR = 256.0 * keyR;
        KeyG = 256.0 * keyG;
        KeyB = 256.0 * keyB;
        KeyA = 256.0 * keyA;
    }
    
    //NSAssert(gWorldPtr != nil, @"nil gWorldPtr");
    if (nil == gWorldPtr) return nil;

    // Lock the pixels
    pixMapHandle = GetGWorldPixMap(gWorldPtr);
    if (pixMapHandle)
    {
        Rect 		portRect;
        unsigned 	portWidth, portHeight;
        int 		bitsPerSample, samplesPerPixel;
        BOOL 		hasAlpha, isPlanar;
        int 		destRowBytes;

        NSAssert(LockPixels(pixMapHandle) != false, @"LockPixels returns false");
    
        GetPortBounds(gWorldPtr, &portRect);
        portWidth = (portRect.right - portRect.left);
        portHeight = (portRect.bottom - portRect.top);
    
        bitsPerSample 	= 8;
        samplesPerPixel = 4;
        hasAlpha		= YES;
        isPlanar 		= NO;
        destRowBytes 	= portWidth * samplesPerPixel;
        imageRep 		= [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:portWidth pixelsHigh:portHeight bitsPerSample:bitsPerSample samplesPerPixel:samplesPerPixel hasAlpha:hasAlpha isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:destRowBytes bitsPerPixel:0];
        if (imageRep)
        {
            char 	*theData;
            int 	pixmapRowBytes;
            int 	rowByte,rowIndex;

            theData = [imageRep bitmapData];
        
            pixBaseAddr = GetPixBaseAddr(pixMapHandle);
            if (pixBaseAddr)
            {
                pixmapRowBytes = GetPixRowBytes(pixMapHandle);
            
                for (rowIndex=0; rowIndex< portHeight; rowIndex++)
                {
                    unsigned char *dst = theData + rowIndex * destRowBytes;
                    unsigned char *src = pixBaseAddr + rowIndex * pixmapRowBytes;
                    unsigned char a,r,g,b;
                    
                    for (rowByte = 0; rowByte < portWidth; rowByte++)
                    {
                        a = *src++;		// get source Alpha component
                        r = *src++;		// get source Red component
                        g = *src++;		// get source Green component
                        b = *src++;		// get source Blue component  
                        
                        if (keyColor) {
                            if (r == KeyR && g == KeyG && b == KeyB)
                                a = 0;
                        }
            
                        *dst++ = r;		// set dest. Alpha component
                        *dst++ = g;		// set dest. Red component
                        *dst++ = b;		// set dest. Green component
                        *dst++ = a;		// set dest. Blue component  
                    }
                }
            
                image = [[[NSImage alloc]initWithSize:NSMakeSize(portWidth, portHeight)] autorelease];
                if (image)
                {
                    [image addRepresentation:imageRep];
                    [imageRep release];
                }
            }
        }
    }

    NSAssert(pixMapHandle != NULL, @"null pixMapHandle");
    NSAssert(imageRep != nil, @"nil imageRep");
    NSAssert(pixBaseAddr != nil, @"nil pixBaseAddr");
    NSAssert(image != nil, @"nil image");

    if (pixMapHandle)
    {
        UnlockPixels(pixMapHandle);
    }

    return image;
}

@end
