/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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_system.h"
#include "SDL_uikitmodes.h"

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

#import <sys/utsname.h>

@implementation SDL_DisplayData

- (instancetype)initWithScreen:(UIScreen*)screen
{
    if (self = [super init]) {
        self.uiscreen = screen;

        /*
         * A well up to date list of device info can be found here:
         * https://github.com/lmirosevic/GBDeviceInfo/blob/master/GBDeviceInfo/GBDeviceInfo_iOS.m
         */
        NSDictionary* devices = @{
            @"iPhone1,1": @163,
            @"iPhone1,2": @163,
            @"iPhone2,1": @163,
            @"iPhone3,1": @326,
            @"iPhone3,2": @326,
            @"iPhone3,3": @326,
            @"iPhone4,1": @326,
            @"iPhone5,1": @326,
            @"iPhone5,2": @326,
            @"iPhone5,3": @326,
            @"iPhone5,4": @326,
            @"iPhone6,1": @326,
            @"iPhone6,2": @326,
            @"iPhone7,1": @401,
            @"iPhone7,2": @326,
            @"iPhone8,1": @326,
            @"iPhone8,2": @401,
            @"iPhone8,4": @326,
            @"iPhone9,1": @326,
            @"iPhone9,2": @401,
            @"iPhone9,3": @326,
            @"iPhone9,4": @401,
            @"iPhone10,1": @326,
            @"iPhone10,2": @401,
            @"iPhone10,3": @458,
            @"iPhone10,4": @326,
            @"iPhone10,5": @401,
            @"iPhone10,6": @458,
            @"iPhone11,2": @458,
            @"iPhone11,4": @458,
            @"iPhone11,6": @458,
            @"iPhone11,8": @326,
            @"iPhone12,1": @326,
            @"iPhone12,3": @458,
            @"iPhone12,5": @458,
            @"iPad1,1": @132,
            @"iPad2,1": @132,
            @"iPad2,2": @132,
            @"iPad2,3": @132,
            @"iPad2,4": @132,
            @"iPad2,5": @163,
            @"iPad2,6": @163,
            @"iPad2,7": @163,
            @"iPad3,1": @264,
            @"iPad3,2": @264,
            @"iPad3,3": @264,
            @"iPad3,4": @264,
            @"iPad3,5": @264,
            @"iPad3,6": @264,
            @"iPad4,1": @264,
            @"iPad4,2": @264,
            @"iPad4,3": @264,
            @"iPad4,4": @326,
            @"iPad4,5": @326,
            @"iPad4,6": @326,
            @"iPad4,7": @326,
            @"iPad4,8": @326,
            @"iPad4,9": @326,
            @"iPad5,1": @326,
            @"iPad5,2": @326,
            @"iPad5,3": @264,
            @"iPad5,4": @264,
            @"iPad6,3": @264,
            @"iPad6,4": @264,
            @"iPad6,7": @264,
            @"iPad6,8": @264,
            @"iPad6,11": @264,
            @"iPad6,12": @264,
            @"iPad7,1": @264,
            @"iPad7,2": @264,
            @"iPad7,3": @264,
            @"iPad7,4": @264,
            @"iPad7,5": @264,
            @"iPad7,6": @264,
            @"iPad7,11": @264,
            @"iPad7,12": @264,
            @"iPad8,1": @264,
            @"iPad8,2": @264,
            @"iPad8,3": @264,
            @"iPad8,4": @264,
            @"iPad8,5": @264,
            @"iPad8,6": @264,
            @"iPad8,7": @264,
            @"iPad8,8": @264,
            @"iPad11,1": @326,
            @"iPad11,2": @326,
            @"iPad11,3": @326,
            @"iPad11,4": @326,
            @"iPod1,1": @163,
            @"iPod2,1": @163,
            @"iPod3,1": @163,
            @"iPod4,1": @326,
            @"iPod5,1": @326,
            @"iPod7,1": @326,
            @"iPod9,1": @326,
        };

        struct utsname systemInfo;
        uname(&systemInfo);
        NSString* deviceName =
            [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
        id foundDPI = devices[deviceName];
        if (foundDPI) {
            self.screenDPI = (float)[foundDPI integerValue];
        } else {
            /*
             * Estimate the DPI based on the screen scale multiplied by the base DPI for the device
             * type (e.g. based on iPhone 1 and iPad 1)
             */
    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
            float scale = (float)screen.nativeScale;
    #else
            float scale = (float)screen.scale;
    #endif
            float defaultDPI;
            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                defaultDPI = 132.0f;
            } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
                defaultDPI = 163.0f;
            } else {
                defaultDPI = 160.0f;
            }
            self.screenDPI = scale * defaultDPI;
        }
    }
    return self;
}

@synthesize uiscreen;
@synthesize screenDPI;

@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] initWithScreen:uiscreen];
    if (!data) {
        UIKit_FreeDisplayModeData(&display.desktop_mode);
        return SDL_OutOfMemory();
    }

    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_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
{
    @autoreleasepool {
        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
        float dpi = data.screenDPI;

        if (ddpi) {
            *ddpi = dpi * (float)SDL_sqrt(2.0);
        }
        if (hdpi) {
            *hdpi = dpi;
        }
        if (vdpi) {
            *vdpi = dpi;
        }
    }

    return 0;
}

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: */
