// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

#include "experimental/skottie_ios/SkMetalViewBridge.h"
#include "experimental/skottie_ios/SkottieMtkView.h"

#include "include/gpu/GrContext.h"
#include "include/gpu/GrContextOptions.h"

#import <Metal/Metal.h>
#import <MetalKit/MetalKit.h>
#import <UIKit/UIKit.h>

static UIStackView* make_skottie_stack(CGFloat width,
                                       id<MTLDevice> metalDevice,
                                       id<MTLCommandQueue> metalQueue,
                                       GrContext* grContext) {
    UIStackView* stack = [[UIStackView alloc] init];
    [stack setAxis:UILayoutConstraintAxisVertical];
    [stack setDistribution:UIStackViewDistributionEqualSpacing];

    NSBundle* mainBundle = [NSBundle mainBundle];
    NSArray<NSString*>* paths = [mainBundle pathsForResourcesOfType:@"json"
                                            inDirectory:@"data"];
    constexpr CGFloat kSpacing = 2;
    CGFloat totalHeight = kSpacing;
    for (NSUInteger i = 0; i < [paths count]; ++i) {
        NSString* path = [paths objectAtIndex:i];
        NSData* content = [NSData dataWithContentsOfFile:path];
        if (!content) {
            NSLog(@"'%@' not found", path);
            continue;
        }
        SkottieMtkView* skottieView = [[SkottieMtkView alloc] init];
        if (![skottieView loadAnimation:content]) {
            continue;
        }
        [skottieView setDevice:metalDevice];
        [skottieView setQueue:metalQueue];
        [skottieView setGrContext:grContext];
        SkMtkViewConfigForSkia(skottieView);
        CGSize animSize = [skottieView size];
        CGFloat height = animSize.width ? (width * animSize.height / animSize.width) : 0;
        [skottieView setFrame:{{0, 0}, {width, height}}];
        [skottieView setPreferredFramesPerSecond:30];
        [[[skottieView heightAnchor] constraintEqualToConstant:height] setActive:true];
        [[[skottieView widthAnchor] constraintEqualToConstant:width] setActive:true];
        [stack addArrangedSubview:skottieView];
        totalHeight += height + kSpacing;
    }
    [stack setFrame:{{0, 0}, {width, totalHeight}}];
    return stack;
}

@interface AppViewController : UIViewController
    @property (strong) id<MTLDevice> metalDevice;
    @property (strong) id<MTLCommandQueue> metalQueue;
    @property (strong) UIStackView* stackView;
@end

@implementation AppViewController {
    sk_sp<GrContext> fGrContext;
}

- (void)loadView {
    [self setView:[[UIView alloc] init]];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    if (!fGrContext) {
        [self setMetalDevice:MTLCreateSystemDefaultDevice()];
        if(![self metalDevice]) {
            NSLog(@"Metal is not supported on this device");
            return;
        }
        [self setMetalQueue:[[self metalDevice] newCommandQueue]];
        GrContextOptions grContextOptions;  // set different options here.
        fGrContext = SkMetalDeviceToGrContext([self metalDevice], [self metalQueue],
                                              grContextOptions);
    }

    [self setStackView:make_skottie_stack([[UIScreen mainScreen] bounds].size.width,
                                          [self metalDevice], [self metalQueue], fGrContext.get())];

    CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
    CGSize mainScreenSize = [[UIScreen mainScreen] bounds].size;
    CGRect scrollViewBounds = {{0, statusBarHeight},
                               {mainScreenSize.width, mainScreenSize.height - statusBarHeight}};
    UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:scrollViewBounds];
    [scrollView setContentSize:[[self stackView] frame].size];
    [scrollView addSubview:[self stackView]];
    [scrollView setBackgroundColor:[UIColor blackColor]];

    UIView* mainView = [self view];
    [mainView setBounds:{{0, 0}, mainScreenSize}];
    [mainView setBackgroundColor:[UIColor whiteColor]];
    [mainView addSubview:scrollView];

    UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc] init];
    [tapGestureRecognizer addTarget:self action:@selector(handleTap:)];
    [mainView addGestureRecognizer:tapGestureRecognizer];
}

- (void)handleTap:(UIGestureRecognizer*)sender {
    if (![sender state] == UIGestureRecognizerStateEnded) {
        return;
    }
    NSArray<UIView*>* subviews = [[self stackView] subviews];
    for (NSUInteger i = 0; i < [subviews count]; ++i) {
        UIView* subview = [subviews objectAtIndex:i];
        if (![subview isKindOfClass:[SkottieMtkView class]]) {
            continue;
        }
        SkottieMtkView* skottieView = (SkottieMtkView*)subview;
        BOOL paused = [skottieView togglePaused];
        [skottieView setEnableSetNeedsDisplay:paused];
        [skottieView setPaused:paused];
    }
}
@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow* window;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication*)app didFinishLaunchingWithOptions:(NSDictionary*)ops {
    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
    [[self window] setRootViewController:[[AppViewController alloc] init]];
    [[self window] makeKeyAndVisible];
    return YES;
}
@end

int main(int argc, char* argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
