


#import "SDAnimatedImageRep.h"

#if SD_MAC

#import "SDImageIOAnimatedCoderInternal.h"
#import "SDImageGIFCoder.h"
#import "SDImageAPNGCoder.h"
#import "SDImageHEICCoder.h"
#import "SDImageAWebPCoder.h"

@interface SDAnimatedImageRep ()

@property (nonatomic, readwrite, weak) NSArray<SDImageFrame *> *frames;
@property (nonatomic, assign, readwrite) SDImageFormat animatedImageFormat;
@end

@implementation SDAnimatedImageRep {
    CGImageSourceRef _imageSource;
}

- (void)dealloc {
    if (_imageSource) {
        CFRelease(_imageSource);
        _imageSource = NULL;
    }
}

- (instancetype)copyWithZone:(NSZone *)zone {
    SDAnimatedImageRep *imageRep = [super copyWithZone:zone];
    
    if (imageRep->_imageSource) {
        CFRetain(imageRep->_imageSource);
    }
    return imageRep;
}


+ (instancetype)imageRepWithData:(NSData *)data {
    SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
    return imageRep;
}


#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
- (instancetype)initWithData:(NSData *)data {
    self = [super initWithData:data];
    if (self) {
        CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL);
        if (!imageSource) {
            return self;
        }
        _imageSource = imageSource;
        NSUInteger frameCount = CGImageSourceGetCount(imageSource);
        if (frameCount <= 1) {
            return self;
        }
        CFStringRef type = CGImageSourceGetType(imageSource);
        if (!type) {
            return self;
        }
        _animatedImageData = data; 
        SDImageFormat format = SDImageFormatUndefined;
        if (CFStringCompare(type, kSDUTTypeGIF, 0) == kCFCompareEqualTo) {
            
            
            
            format = SDImageFormatGIF;
            NSUInteger loopCount = [SDImageGIFCoder imageLoopCountWithSource:imageSource];
            [self setProperty:NSImageLoopCount withValue:@(loopCount)];
        } else if (CFStringCompare(type, kSDUTTypePNG, 0) == kCFCompareEqualTo) {
            
            
            format = SDImageFormatPNG;
            [self setProperty:NSImageFrameCount withValue:@(frameCount)];
            [self setProperty:NSImageCurrentFrame withValue:@(0)];
            NSUInteger loopCount = [SDImageAPNGCoder imageLoopCountWithSource:imageSource];
            [self setProperty:NSImageLoopCount withValue:@(loopCount)];
        } else if (CFStringCompare(type, kSDUTTypeHEICS, 0) == kCFCompareEqualTo) {
            
            
            format = SDImageFormatHEIC;
            [self setProperty:NSImageFrameCount withValue:@(frameCount)];
            [self setProperty:NSImageCurrentFrame withValue:@(0)];
            NSUInteger loopCount = [SDImageHEICCoder imageLoopCountWithSource:imageSource];
            [self setProperty:NSImageLoopCount withValue:@(loopCount)];
        } else if (CFStringCompare(type, kSDUTTypeWebP, 0) == kCFCompareEqualTo) {
            
            
            format = SDImageFormatWebP;
            [self setProperty:NSImageFrameCount withValue:@(frameCount)];
            [self setProperty:NSImageCurrentFrame withValue:@(0)];
            NSUInteger loopCount = [SDImageAWebPCoder imageLoopCountWithSource:imageSource];
            [self setProperty:NSImageLoopCount withValue:@(loopCount)];
        } else {
            format = [NSData sd_imageFormatForImageData:data];
        }
        _animatedImageFormat = format;
    }
    return self;
}


- (void)setProperty:(NSBitmapImageRepPropertyKey)property withValue:(id)value {
    [super setProperty:property withValue:value];
    if ([property isEqualToString:NSImageCurrentFrame]) {
        
        CGImageSourceRef imageSource = _imageSource;
        if (!imageSource) {
            return;
        }
        
        CFStringRef type = CGImageSourceGetType(imageSource);
        if (!type) {
            return;
        }
        NSUInteger index = [value unsignedIntegerValue];
        NSTimeInterval frameDuration = 0;
        if (CFStringCompare(type, kSDUTTypeGIF, 0) == kCFCompareEqualTo) {
            
            frameDuration = [SDImageGIFCoder frameDurationAtIndex:index source:imageSource];
        } else if (CFStringCompare(type, kSDUTTypePNG, 0) == kCFCompareEqualTo) {
            
            frameDuration = [SDImageAPNGCoder frameDurationAtIndex:index source:imageSource];
        } else if (CFStringCompare(type, kSDUTTypeHEICS, 0) == kCFCompareEqualTo) {
            
            frameDuration = [SDImageHEICCoder frameDurationAtIndex:index source:imageSource];
        } else if (CFStringCompare(type, kSDUTTypeWebP, 0) == kCFCompareEqualTo) {
            
            frameDuration = [SDImageAWebPCoder frameDurationAtIndex:index source:imageSource];
        }
        if (!frameDuration) {
            return;
        }
        
        [super setProperty:NSImageCurrentFrameDuration withValue:@(frameDuration)];
    }
}
#pragma clang diagnostic pop

@end

#endif
