/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_UIKIT

#include "SDL_assert.h"
#include "SDL_uikitmodes.h"

#include "../../events/SDL_events_c.h"

@implementation SDL_DisplayData

@synthesize uiscreen;

@end

@implementation SDL_DisplayModeData

@synthesize uiscreenmode;

@end


static int
UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
    UIScreenMode * uiscreenmode)
{
    SDL_DisplayModeData *data = nil;

    if (uiscreenmode != nil) {
        /* Allocate the display mode data */
        data = [[SDL_DisplayModeData alloc] init];
        if (!data) {
            return SDL_OutOfMemory();
        }

        data.uiscreenmode = uiscreenmode;
    }

    mode->driverdata = (void *) CFBridgingRetain(data);

    return 0;
}

static void
UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
{
    if (mode->driverdata != NULL) {
        CFRelease(mode->driverdata);
        mode->driverdata = NULL;
    }
}

static NSUInteger
UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen)
{
#ifdef __IPHONE_10_3
    if ([uiscreen respondsToSelector:@selector(maximumFramesPerSecond)]) {
        return uiscreen.maximumFramesPerSecond;
    }
#endif
    return 0;
}

static int
UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
    UIScreen * uiscreen, UIScreenMode * uiscreenmode)
{
    SDL_DisplayMode mode;
    SDL_zero(mode);

    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
        return -1;
    }

    mode.format = SDL_PIXELFORMAT_ABGR8888;
    mode.refresh_rate = (int) UIKit_GetDisplayModeRefreshRate(uiscreen);
    mode.w = w;
    mode.h = h;

    if (SDL_AddDisplayMode(display, &mode)) {
        return 0;
    } else {
        UIKit_FreeDisplayModeData(&mode);
        return -1;
    }
}

static int
UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscreen,
                     UIScreenMode * uiscreenmode, SDL_bool addRotation)
{
    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreen, uiscreenmode) < 0) {
        return -1;
    }

    if (addRotation) {
        /* Add the rotated version */
        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreen, uiscreenmode) < 0) {
            return -1;
        }
    }

    return 0;
}

static int
UIKit_AddDisplay(UIScreen *uiscreen)
{
    UIScreenMode *uiscreenmode = uiscreen.currentMode;
    CGSize size = uiscreen.bounds.size;
    SDL_VideoDisplay display;
    SDL_DisplayMode mode;
    SDL_zero(mode);

    /* Make sure the width/height are oriented correctly */
    if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
        CGFloat height = size.width;
        size.width = size.height;
        size.height = height;
    }

    mode.format = SDL_PIXELFORMAT_ABGR8888;
    mode.refresh_rate = (int) UIKit_GetDisplayModeRefreshRate(uiscreen);
    mode.w = (int) size.width;
    mode.h = (int) size.height;

    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
        return -1;
    }

    SDL_zero(display);
    display.desktop_mode = mode;
    display.current_mode = mode;

    /* Allocate the display data */
    SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
    if (!data) {
        UIKit_FreeDisplayModeData(&display.desktop_mode);
        return SDL_OutOfMemory();
    }

    data.uiscreen = uiscreen;

    display.driverdata = (void *) CFBridgingRetain(data);
    SDL_AddVideoDisplay(&display);

    return 0;
}

SDL_bool
UIKit_IsDisplayLandscape(UIScreen *uiscreen)
{
#if !TARGET_OS_TV
    if (uiscreen == [UIScreen mainScreen]) {
        return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
    } else
#endif /* !TARGET_OS_TV */
    {
        CGSize size = uiscreen.bounds.size;
        return (size.width > size.height);
    }
}

int
UIKit_InitModes(_THIS)
{
    @autoreleasepool {
        for (UIScreen *uiscreen in [UIScreen screens]) {
            if (UIKit_AddDisplay(uiscreen) < 0) {
                return -1;
            }
        }
#if !TARGET_OS_TV
        SDL_OnApplicationDidChangeStatusBarOrientation();
#endif
    }

    return 0;
}

void
UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
    @autoreleasepool {
        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;

        SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
        SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
        CGFloat scale = data.uiscreen.scale;
        NSArray *availableModes = nil;

#if TARGET_OS_TV
        addRotation = SDL_FALSE;
        availableModes = @[data.uiscreen.currentMode];
#else
        availableModes = data.uiscreen.availableModes;
#endif

        for (UIScreenMode *uimode in availableModes) {
            /* The size of a UIScreenMode is in pixels, but we deal exclusively
             * in points (except in SDL_GL_GetDrawableSize.)
             *
             * For devices such as iPhone 6/7/8 Plus, the UIScreenMode reported
             * by iOS is not in physical pixels of the display, but rather the
             * point size times the scale.  For example, on iOS 12.2 on iPhone 8
             * Plus the uimode.size is 1242x2208 and the uiscreen.scale is 3
             * thus this will give the size in points which is 414x736. The code
             * used to use the nativeScale, assuming UIScreenMode returned raw
             * physical pixels (as suggested by its documentation, but in
             * practice it is returning the retina pixels). */
            int w = (int)(uimode.size.width / scale);
            int h = (int)(uimode.size.height / scale);

            /* Make sure the width/height are oriented correctly */
            if (isLandscape != (w > h)) {
                int tmp = w;
                w = h;
                h = tmp;
            }

            UIKit_AddDisplayMode(display, w, h, data.uiscreen, uimode, addRotation);
        }
    }
}

int
UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
    @autoreleasepool {
        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;

#if !TARGET_OS_TV
        SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
        [data.uiscreen setCurrentMode:modedata.uiscreenmode];
#endif

        if (data.uiscreen == [UIScreen mainScreen]) {
            /* [UIApplication setStatusBarOrientation:] no longer works reliably
             * in recent iOS versions, so we can't rotate the screen when setting
             * the display mode. */
            if (mode->w > mode->h) {
                if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
                    return SDL_SetError("Screen orientation does not match display mode size");
                }
            } else if (mode->w < mode->h) {
                if (UIKit_IsDisplayLandscape(data.uiscreen)) {
                    return SDL_SetError("Screen orientation does not match display mode size");
                }
            }
        }
    }

    return 0;
}

int
UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
{
    @autoreleasepool {
        int displayIndex = (int) (display - _this->displays);
        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
        CGRect frame = data.uiscreen.bounds;

        /* the default function iterates displays to make a fake offset,
         as if all the displays were side-by-side, which is fine for iOS. */
        if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
            return -1;
        }

#if !TARGET_OS_TV && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
        if (!UIKit_IsSystemVersionAtLeast(7.0)) {
            frame = [data.uiscreen applicationFrame];
        }
#endif

        rect->x += frame.origin.x;
        rect->y += frame.origin.y;
        rect->w = frame.size.width;
        rect->h = frame.size.height;
    }

    return 0;
}

void
UIKit_QuitModes(_THIS)
{
    /* Release Objective-C objects, so higher level doesn't free() them. */
    int i, j;
    @autoreleasepool {
        for (i = 0; i < _this->num_displays; i++) {
            SDL_VideoDisplay *display = &_this->displays[i];

            UIKit_FreeDisplayModeData(&display->desktop_mode);
            for (j = 0; j < display->num_display_modes; j++) {
                SDL_DisplayMode *mode = &display->display_modes[j];
                UIKit_FreeDisplayModeData(mode);
            }

            if (display->driverdata != NULL) {
                CFRelease(display->driverdata);
                display->driverdata = NULL;
            }
        }
    }
}

#if !TARGET_OS_TV
void SDL_OnApplicationDidChangeStatusBarOrientation()
{
    BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
    SDL_VideoDisplay *display = SDL_GetDisplay(0);

    if (display) {
        SDL_DisplayMode *desktopmode = &display->desktop_mode;
        SDL_DisplayMode *currentmode = &display->current_mode;
        SDL_DisplayOrientation orientation = SDL_ORIENTATION_UNKNOWN;

        /* The desktop display mode should be kept in sync with the screen
         * orientation so that updating a window's fullscreen state to
         * SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the
         * correct orientation. */
        if (isLandscape != (desktopmode->w > desktopmode->h)) {
            int height = desktopmode->w;
            desktopmode->w = desktopmode->h;
            desktopmode->h = height;
        }

        /* Same deal with the current mode + SDL_GetCurrentDisplayMode. */
        if (isLandscape != (currentmode->w > currentmode->h)) {
            int height = currentmode->w;
            currentmode->w = currentmode->h;
            currentmode->h = height;
        }

        switch ([UIApplication sharedApplication].statusBarOrientation) {
        case UIInterfaceOrientationPortrait:
            orientation = SDL_ORIENTATION_PORTRAIT;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            orientation = SDL_ORIENTATION_PORTRAIT_FLIPPED;
            break;
        case UIInterfaceOrientationLandscapeLeft:
            /* Bug: UIInterfaceOrientationLandscapeLeft/Right are reversed - http://openradar.appspot.com/7216046 */
            orientation = SDL_ORIENTATION_LANDSCAPE_FLIPPED;
            break;
        case UIInterfaceOrientationLandscapeRight:
            /* Bug: UIInterfaceOrientationLandscapeLeft/Right are reversed - http://openradar.appspot.com/7216046 */
            orientation = SDL_ORIENTATION_LANDSCAPE;
            break;
        default:
            break;
        }
        SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation);
    }
}
#endif /* !TARGET_OS_TV */

#endif /* SDL_VIDEO_DRIVER_UIKIT */

/* vi: set ts=4 sw=4 expandtab: */
