/*
* Copyright 2017 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/ios/WindowContextFactory_ios.h"
#include "tools/sk_app/ios/Window_ios.h"

#if __has_feature(objc_arc)
#error "File should not be compiled with ARC."
#endif

@interface WindowViewController : UIViewController

- (WindowViewController*)initWithWindow:(sk_app::Window_ios*)initWindow;

@end

///////////////////////////////////////////////////////////////////////////////

using sk_app::Window;

namespace sk_app {

Window_ios* Window_ios::gWindow = nullptr;

Window* Window::CreateNativeWindow(void*) {
    // already have a window
    if (Window_ios::MainWindow()) {
        return nullptr;
    }

    Window_ios* window = new Window_ios();
    if (!window->initWindow()) {
        delete window;
        return nullptr;
    }

    return window;
}

bool Window_ios::initWindow() {
    // we already have a window
    if (fWindow) {
        return true;
    }

    // Create a view controller to track certain events
    WindowViewController* viewController = [[WindowViewController alloc] initWithWindow:this];
    if (nil == viewController) {
        return false;
    }

    fWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    if (nil == fWindow) {
        [viewController release];
        return false;
    }
    fWindow.backgroundColor = [UIColor whiteColor];

    viewController.view = nil;
    [fWindow setRootViewController:viewController];
    [fWindow makeKeyAndVisible];

    gWindow = this;

    return true;
}

void Window_ios::closeWindow() {
    if (nil != fWindow) {
        gWindow = nullptr;
        [fWindow release];
        fWindow = nil;
    }
}

bool Window_ios::attach(BackendType attachType) {
    this->initWindow();

    window_context_factory::IOSWindowInfo info;
    info.fWindow = this;
    info.fViewController = fWindow.rootViewController;
    switch (attachType) {
#ifdef SK_METAL
        case kMetal_BackendType:
            fWindowContext = MakeMetalForIOS(info, fRequestedDisplayParams);
            break;
#endif
#ifdef SK_GL
        case kNativeGL_BackendType:
            fWindowContext = MakeGLForIOS(info, fRequestedDisplayParams);
            break;
        case kRaster_BackendType:
            fWindowContext = MakeRasterForIOS(info, fRequestedDisplayParams);
            break;
#endif
        default:
            SkASSERT_RELEASE(false);
    }
    this->onBackendCreated();

    return (SkToBool(fWindowContext));
}

void Window_ios::PaintWindow() {
    gWindow->onPaint();
}

void Window_ios::onInval() {
    // TODO: send expose event
}

}   // namespace sk_app

///////////////////////////////////////////////////////////////////////////////

@implementation WindowViewController {
    sk_app::Window_ios* fWindow;
}

- (WindowViewController*)initWithWindow:(sk_app::Window_ios *)initWindow {
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        fWindow = initWindow;
    }
    return self;
}

- (void)viewDidLoad {
    // nothing yet
}

- (void)didReceiveMemoryWarning {
    // nothing yet
}

- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    // handle rotations here
}
@end

///////////////////////////////////////////////////////////////////////////////

@implementation MainView {
    sk_app::Window_ios* fWindow;
}

- (void)panGestureAction:(UIGestureRecognizer*)sender {
    CGPoint location = [sender locationInView:self];
    switch (sender.state) {
        case UIGestureRecognizerStateBegan:
            fWindow->onMouse(location.x, location.y,
                             skui::InputState::kDown, skui::ModifierKey::kNone);
            break;
        case UIGestureRecognizerStateChanged:
            fWindow->onMouse(location.x, location.y,
                             skui::InputState::kMove, skui::ModifierKey::kNone);
            break;
        case UIGestureRecognizerStateEnded:
            fWindow->onMouse(location.x, location.y,
                             skui::InputState::kUp, skui::ModifierKey::kNone);
            break;
        case UIGestureRecognizerStateCancelled:
            fWindow->onMouse(location.x, location.y,
                             skui::InputState::kUp, skui::ModifierKey::kNone);
            break;
        default:
            break;
    }
}

- (void)tapGestureAction:(UIGestureRecognizer*)sender {
    CGPoint location = [sender locationInView:self];
    switch (sender.state) {
        case UIGestureRecognizerStateEnded:
            fWindow->onMouse(location.x, location.y,
                             skui::InputState::kDown, skui::ModifierKey::kNone);
            fWindow->onMouse(location.x, location.y,
                             skui::InputState::kUp, skui::ModifierKey::kNone);
            break;
        default:
            break;
    }
}

- (void)pinchGestureAction:(UIGestureRecognizer*)sender {
    CGPoint location = [sender locationInView:self];
    UIPinchGestureRecognizer* pinchGestureRecognizer = (UIPinchGestureRecognizer*) sender;
    float scale = pinchGestureRecognizer.scale;
    switch (sender.state) {
        case UIGestureRecognizerStateBegan:
            fWindow->onPinch(skui::InputState::kDown, scale, location.x, location.y);
            break;
        case UIGestureRecognizerStateChanged:
            fWindow->onPinch(skui::InputState::kMove, scale, location.x, location.y);
            break;
        case UIGestureRecognizerStateEnded:
            fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y);
            break;
        case UIGestureRecognizerStateCancelled:
            fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y);
            break;
        default:
            break;
    }
}

- (void)swipeRightGestureAction:(UIGestureRecognizer*)sender {
    if (UIGestureRecognizerStateEnded == sender.state) {
        fWindow->onFling(skui::InputState::kRight);
    }
}

- (void)swipeLeftGestureAction:(UIGestureRecognizer*)sender {
    if (UIGestureRecognizerStateEnded == sender.state) {
        fWindow->onFling(skui::InputState::kLeft);
    }
}

- (MainView*)initWithWindow:(sk_app::Window_ios *)initWindow {
    self = [super init];

    UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
    panGestureRecognizer.maximumNumberOfTouches = 1;
    [panGestureRecognizer addTarget:self action:@selector(panGestureAction:)];
    [self addGestureRecognizer:panGestureRecognizer];

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

    UIPinchGestureRecognizer* pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] init];
    [pinchGestureRecognizer addTarget:self action:@selector(pinchGestureAction:)];
    [self addGestureRecognizer:pinchGestureRecognizer];

    UISwipeGestureRecognizer* swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [swipeRightGestureRecognizer addTarget:self action:@selector(swipeRightGestureAction:)];
    [self addGestureRecognizer:swipeRightGestureRecognizer];

    UISwipeGestureRecognizer* swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [swipeLeftGestureRecognizer addTarget:self action:@selector(swipeLeftGestureAction:)];
    [self addGestureRecognizer:swipeLeftGestureRecognizer];

    // disable pan recognition until swipes fail
    [panGestureRecognizer requireGestureRecognizerToFail:swipeLeftGestureRecognizer];
    [panGestureRecognizer requireGestureRecognizerToFail:swipeRightGestureRecognizer];

    fWindow = initWindow;

    return self;
}

@end

