//
//  ECCompositionLayer.m
//  Etokicho
//
//  Created by 二鏡 on 11/11/29.
//  Copyright 2011年 二鏡庵. All rights reserved.
//

#import "ECCompositionLayer.h"
#import "ECScene.h"

NSString *ECPasteboardTypeCompositionLayer = @"com.mac.nikyo-an.pasteboard.compositionLayer";
static NSString *plistCompositionKey = @"item";

@implementation ECCompositionLayer
+ (NSString*)type
{
    return @"Composition";
}

- (id)initWithPropertyList:(NSDictionary*)plist
                packageURL:(NSURL*)aURL
{
    self = [super initWithPropertyList: plist packageURL: aURL];
    if(self)
    {
        // compositionをロード
        id item_ = [plist objectForKey: plistCompositionKey];
        item = [[NSUnarchiver unarchiveObjectWithData: item_] retain];
    }
    return self;
}

#pragma mark NSCopying
- (id)copyWithZone:(NSZone *)zone
{
    ECCompositionLayer *ret = [super copyWithZone: zone];
    ret->item = [item copy];
    return ret;
}

#pragma mark NSCoding
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder: aDecoder];
    if(self)
    {
        item = [[aDecoder decodeObjectForKey: plistCompositionKey] copy];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [super encodeWithCoder: encoder];
    [encoder encodeObject: item forKey: plistCompositionKey];
}

#pragma mark NSPasteboardItem
-(NSArray*)writableTypesForPasteboard:(NSPasteboard*)pboard
{
    return [NSArray arrayWithObject: ECPasteboardTypeCompositionLayer];
}

-(id)pasteboardPropertyListForType:(NSString*)type
{
    if([type isEqualToString: ECPasteboardTypeCompositionLayer])
        return [NSKeyedArchiver archivedDataWithRootObject: self];
    return nil;
}

+ (NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard
{
    static NSArray *types = nil;
    if(!types)
        types = [[NSArray alloc] initWithObjects: ECPasteboardTypeCompositionLayer,nil];
    return types;
}

+ (NSPasteboardReadingOptions)readingOptionsForType:(NSString *)type 
                                         pasteboard:(NSPasteboard *)pboard
{
    if([type isEqualToString: ECPasteboardTypeCompositionLayer])
        return NSPasteboardReadingAsKeyedArchive;
    return 0;
}

- (void)dealloc
{
    [renderer release];
    [item release];
    [super dealloc];
}

- (NSURL*)auxResourceURL
{
    return nil;
}

- (id)propertyListWithAuxResourceName:(NSString*)filename
{
    id plist = [super propertyListWithAuxResourceName: filename];
    
    id item_ = [NSArchiver archivedDataWithRootObject: item];
    [plist setObject: item_ forKey: plistCompositionKey];
    
    return [[plist copy] autorelease];
}

- (ECQCCompositionItem*)compositionItem
{
    return [[item copy] autorelease];
}

- (void)setCompositionItem:(ECQCCompositionItem*)aItem
{
    if(item == aItem)
        return ;
    [item release];
    item = [aItem copy];
    [renderer release]; renderer = nil;
}

- (BOOL)isStatic
{
    return NO;
}

- (CGSize)size
{
    return size;
}

- (void)setSize:(CGSize)aSize
{
    if(NSEqualSizes(size, aSize))
        return ;
    
    size = aSize;
    // rendererを破棄
    [renderer release];
    renderer = nil;
}

+ (id)undoObservationKeys
{
    id ret = [super undoObservationKeys];
    [ret addObject: @"compositionItem"];
    return [[ret copy] autorelease];
}

- (void)renderAtTime:(NSUInteger)msec
           inContext:(CGContextRef)context
{
    if(item)
    {
        if(!renderer)
        {
            id composition = [item loadComposition];
            renderer = [[QCRenderer alloc] initOffScreenWithSize: scene.size
                                                      colorSpace: nil
                                                     composition: composition];
            [item apply: renderer];
        }
    }

    if([renderer renderAtTime: (CGFloat)msec/1000 arguments: nil])
    {
        CGContextSaveGState(context);
        CGImageRef image = (CGImageRef)[renderer createSnapshotImageOfType: @"CGImage"];
        CGContextSetAlpha(context, alpha);
        CGRect rect;
        rect.origin = origin; rect.size = size;
        CGContextDrawImage(context, rect, image);
        CFRelease(image);
        CGContextRestoreGState(context);
    }
}

- (void)renderInContext:(CGContextRef)context
{
    [self renderAtTime: 0
             inContext: context];
}

- (void)renderThumbnailInContext:(CGContextRef)context
{
    [self renderAtTime: 0
             inContext: context];
}

- (void)cleanupRendering
{
    [renderer release];
    renderer = nil;
}

- (QCRenderer*)attachRenderer:(QCComposition*)composition
{
    if(renderer)
        [renderer release];
    if(composition == nil)
    {
        renderer = nil;
        return nil;
    }
    renderer = [[QCRenderer alloc] initOffScreenWithSize: scene.size
                                              colorSpace: nil
                                             composition: composition];
    return renderer;    
}

- (void)forceEffectParameters
{
    
}

- (ECQCCompositionItem*)currentRendererParameters
{
    return [ECQCCompositionItem itemWithRenderer: renderer];
}

- (BOOL)isUseEmbeddedComposition
{
    return NO;
}

- (BOOL)pointInRect:(CGPoint)aPoint
{
    return NO; //マウス的には不可視とする
}
@end
