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

#include "tools/sk_app/MetalWindowContext.h"
#include "tools/sk_app/ios/WindowContextFactory_ios.h"

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

using sk_app::DisplayParams;
using sk_app::window_context_factory::IOSWindowInfo;
using sk_app::MetalWindowContext;

@interface MetalView : MainView
@end

@implementation MetalView
+ (Class) layerClass {
    return [CAMetalLayer class];
}
@end

namespace {

class MetalWindowContext_ios : public MetalWindowContext {
public:
    MetalWindowContext_ios(const IOSWindowInfo&, const DisplayParams&);

    ~MetalWindowContext_ios() override;

    bool onInitializeContext() override;
    void onDestroyContext() override;

    void resize(int w, int h) override;

private:
    sk_app::Window_ios*  fWindow;
    UIViewController*    fViewController;
    MetalView*           fMetalView;

    using INHERITED = MetalWindowContext;
};

MetalWindowContext_ios::MetalWindowContext_ios(const IOSWindowInfo& info,
                                               const DisplayParams& params)
    : INHERITED(params)
    , fWindow(info.fWindow)
    , fViewController(info.fViewController) {

    // any config code here (particularly for msaa)?

    this->initializeContext();
}

MetalWindowContext_ios::~MetalWindowContext_ios() {
    this->destroyContext();
    [fMetalView removeFromSuperview];
    [fMetalView release];
}

bool MetalWindowContext_ios::onInitializeContext() {
    SkASSERT(nil != fWindow);
    SkASSERT(nil != fViewController);

    CGRect frameRect = [fViewController.view frame];
    fMetalView = [[[MetalView alloc] initWithFrame:frameRect] initWithWindow:fWindow];
    [fViewController.view addSubview:fMetalView];

    fMetalLayer = (CAMetalLayer*)fMetalView.layer;
    fMetalLayer.device = fDevice.get();
    fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
    fMetalLayer.drawableSize = frameRect.size;
    fMetalLayer.frame = frameRect;

    // TODO: need solution for iOS
    // BOOL useVsync = fDisplayParams.fDisableVsync ? NO : YES;
    // fMetalLayer.displaySyncEnabled = useVsync;
    fMetalLayer.contentsGravity = kCAGravityTopLeft;

    fWidth = frameRect.size.width;
    fHeight = frameRect.size.height;

    return true;
}

void MetalWindowContext_ios::onDestroyContext() {}

void MetalWindowContext_ios::resize(int w, int h) {
    // TODO: handle rotation
    fMetalLayer.drawableSize = fMetalView.frame.size;
    fMetalLayer.frame = fMetalView.frame;
    fWidth = w;
    fHeight = h;
}

}  // anonymous namespace

namespace sk_app {
namespace window_context_factory {

std::unique_ptr<WindowContext> MakeMetalForIOS(const IOSWindowInfo& info,
                                               const DisplayParams& params) {
    std::unique_ptr<WindowContext> ctx(new MetalWindowContext_ios(info, params));
    if (!ctx->isValid()) {
        return nullptr;
    }
    return ctx;
}

}  // namespace window_context_factory
}  // namespace sk_app
