//
//  ECDSceneSegment.m
//  Etokicho
//
//  Created by 二鏡 on 11/12/06.
//  Copyright (c) 2011年 二鏡庵. All rights reserved.
//

#import "ECDSceneSegment.h"
#import "ServiceFunctions.h"

@interface ECDSceneSegment (CoreDataGeneratedAccessor)
- (void)setPrimitiveScene:(ECScene*)aScene;
@end

extern NSString *udSegmentGeneratorBaseWait;
extern NSString *udSegmentGeneratorTextWait;
extern NSString *udSegmentGeneratorUseTextWait;

@implementation ECDSceneSegment

@dynamic scene;
+ (NSString*)segmentType
{
    return @"SceneSegment";
}

- (NSString*)type
{
    return NSLocalizedString(@"Scene", @"");
}

- (void)setScene:(ECScene*)aScene
{
    [self willChangeValueForKey: @"scene"];
    id scene = [aScene copy];
    [self setPrimitiveScene: scene];
    [scene release];
    [self didChangeValueForKey: @"scene"];
}

- (void)setLightPreview:(BOOL)val
{
    [super setLightPreview: val];
    ECScene* scene = [self scene];
    scene.lightPreview = val;
}

+ (id)attachNewSegmentWithScene:(ECScene*)aScene
                      inContext:(NSManagedObjectContext*)context
{
    id ud = [NSUserDefaults standardUserDefaults];
    id entity = [NSEntityDescription entityForName: @"SceneSegment"
                            inManagedObjectContext: context];
    ECDSceneSegment *ret = [[self alloc] initWithEntity: entity 
                         insertIntoManagedObjectContext: context];
    ret.scene = aScene;
 
    // msec calculation
    NSInteger msec = [[ud objectForKey: udSegmentGeneratorBaseWait] integerValue];
    if([ud boolForKey: udSegmentGeneratorUseTextWait])
    {
        NSUInteger count = [aScene longestTextLength];
        msec += count*[[ud objectForKey: udSegmentGeneratorTextWait] integerValue];
    }
    ret.msec = msec;
    
    return [ret autorelease];
}

- (id)loadContentsOfURL:(NSURL*)URL
           propertyList:(NSDictionary*)plist
              inContext:(NSManagedObjectContext*)context
{
    self.msec = [[plist objectForKey: plistSegmentMsecKey] integerValue];
    id sceneName = [ECScene pathComponent: @"scene"];
    id sceneURL = [URL URLByAppendingPathComponent: sceneName];
    id scene = [[ECScene alloc] initWithContentsOfURL: sceneURL];
    if(scene == nil)
    {
        [self autorelease];
        [context deleteObject: self];
        return nil;
    }
    [self setPrimitiveScene: scene];
    [scene release];
    
    return self;
}

- (BOOL)writeToURL:(NSURL*)URL
{
    id plist = [NSMutableDictionary dictionary];
    [plist setObject: [NSNumber numberWithInteger: self.msec]
              forKey: plistSegmentMsecKey];
    [plist setObject: [[self class] segmentType]
              forKey: plistSegmentTypeKey];
    
    id sceneFile = [ECScene pathComponent: @"scene"];
    id plistURL = [ECDSegment propertyListForLocation: URL];
    id sceneURL = [URL URLByAppendingPathComponent: sceneFile];
    
    [self.scene writeToURL: sceneURL];
    
    return [plist writeToURL: plistURL atomically: YES];
}

- (void)insertSegment:(QTMovie*)aMovie
            frameRate:(NSUInteger)fps
                 size:(NSSize)size
{
    ECScene *scene = self.scene;
    NSInteger msec = self.msec;
    id attr = [[self class] standardRenderAttributes];
    
    if(self.lightPreview || scene.isStatic)
    {
        CGImageRef img = [scene allocImageAtTime: 0.0]; // 静的な時は時間に関係なく同じである
        id image = [[NSImage alloc] initWithCGImage:img size: NSZeroSize];
        [aMovie addImage: image
             forDuration: QTMakeTime(msec,1000)
          withAttributes: attr];
        [image release];
        CGImageRelease(img);
    }
    else
    {
        NSUInteger f_sec, frames, adjust_cycle;
        _calculateFrameInfo(fps, msec, &f_sec, &frames, &adjust_cycle);
        
        NSUInteger is_adjust = 0;
        NSUInteger duration = 0;
        for(NSUInteger i=0;i<frames;i++)
        {
            id pool = [[NSAutoreleasePool alloc] init];
            CGImageRef img = [scene allocImageAtTime: duration];
            id image = [[NSImage alloc] initWithCGImage: img size: NSZeroSize];
            CGImageRelease(img);
            
            NSUInteger moment = f_sec;
            is_adjust = (is_adjust+1) % adjust_cycle;
            if(is_adjust == 0)
                moment += 1;
            [aMovie addImage: image
                 forDuration: QTMakeTime(moment,1000)
              withAttributes: attr];
            duration += moment;
            [image release];
            [pool release];
        }
    }
}

- (void)cleanup
{
    ECScene *scene = self.scene;
    [scene cleanupRendering];
}

- (id)cloneInContext:(NSManagedObjectContext*)context
{
    ECDSceneSegment *ret = [super cloneInContext: context];
    ret.scene = self.scene;
    return ret;
}

- (CGImageRef)allocInFrameImage
{
    return [self.scene allocImageAtTime: 0];
}

- (CGImageRef)allocOutFrameImage
{
    return [self.scene allocImageAtTime: self.msec];
}

@end
