/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2013 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_config.h"

#if SDL_VIDEO_DRIVER_COCOA

#include "SDL_cocoavideo.h"

/* We need this for IODisplayCreateInfoDictionary and kIODisplayOnlyPreferredName */
#include <IOKit/graphics/IOGraphicsLib.h>

/* we need this for ShowMenuBar() and HideMenuBar(). */
#include <Carbon/Carbon.h>

/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */
#include <AvailabilityMacros.h>


static void
Cocoa_ToggleMenuBar(const BOOL show)
{
    /* !!! FIXME: keep an eye on this.
     * ShowMenuBar/HideMenuBar is officially unavailable for 64-bit binaries.
     *  It happens to work, as of 10.7, but we're going to see if
     *  we can just simply do without it on newer OSes...
     */
#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__)
    if (show)
        ShowMenuBar();
    else
        HideMenuBar();
#endif
}


/* !!! FIXME: clean out the pre-10.6 code when it makes sense to do so. */
#define FORCE_OLD_API 0

#if FORCE_OLD_API
#undef MAC_OS_X_VERSION_MIN_REQUIRED
#define MAC_OS_X_VERSION_MIN_REQUIRED 1050
#endif

static BOOL
IS_SNOW_LEOPARD_OR_LATER(_THIS)
{
#if FORCE_OLD_API
    return NO;
#else
    return ((((SDL_VideoData *) _this->driverdata))->osversion >= 0x1060);
#endif
}

static int
CG_SetError(const char *prefix, CGDisplayErr result)
{
    const char *error;

    switch (result) {
    case kCGErrorFailure:
        error = "kCGErrorFailure";
        break;
    case kCGErrorIllegalArgument:
        error = "kCGErrorIllegalArgument";
        break;
    case kCGErrorInvalidConnection:
        error = "kCGErrorInvalidConnection";
        break;
    case kCGErrorInvalidContext:
        error = "kCGErrorInvalidContext";
        break;
    case kCGErrorCannotComplete:
        error = "kCGErrorCannotComplete";
        break;
    case kCGErrorNotImplemented:
        error = "kCGErrorNotImplemented";
        break;
    case kCGErrorRangeCheck:
        error = "kCGErrorRangeCheck";
        break;
    case kCGErrorTypeCheck:
        error = "kCGErrorTypeCheck";
        break;
    case kCGErrorInvalidOperation:
        error = "kCGErrorInvalidOperation";
        break;
    case kCGErrorNoneAvailable:
        error = "kCGErrorNoneAvailable";
        break;
    default:
        error = "Unknown Error";
        break;
    }
    return SDL_SetError("%s: %s", prefix, error);
}

static SDL_bool
GetDisplayMode(_THIS, const void *moderef, SDL_DisplayMode *mode)
{
    SDL_DisplayModeData *data;
    long width = 0;
    long height = 0;
    long bpp = 0;
    long refreshRate = 0;

    data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
    if (!data) {
        return SDL_FALSE;
    }
    data->moderef = moderef;

    if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
        CGDisplayModeRef vidmode = (CGDisplayModeRef) moderef;
        CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode);
        width = (long) CGDisplayModeGetWidth(vidmode);
        height = (long) CGDisplayModeGetHeight(vidmode);
        refreshRate = (long) CGDisplayModeGetRefreshRate(vidmode);

        if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
                            kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            bpp = 32;
        } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
                            kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            bpp = 16;
        } else {
            bpp = 0;  /* ignore 8-bit and such for now. */
        }

        CFRelease(fmt);
    }

    #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
        CFNumberRef number;
        CFDictionaryRef vidmode = (CFDictionaryRef) moderef;
        number = CFDictionaryGetValue(vidmode, kCGDisplayWidth);
        CFNumberGetValue(number, kCFNumberLongType, &width);
        number = CFDictionaryGetValue(vidmode, kCGDisplayHeight);
        CFNumberGetValue(number, kCFNumberLongType, &height);
        number = CFDictionaryGetValue(vidmode, kCGDisplayBitsPerPixel);
        CFNumberGetValue(number, kCFNumberLongType, &bpp);
        number = CFDictionaryGetValue(vidmode, kCGDisplayRefreshRate);
        CFNumberGetValue(number, kCFNumberLongType, &refreshRate);
    }
    #endif

    mode->format = SDL_PIXELFORMAT_UNKNOWN;
    switch (bpp) {
    case 16:
        mode->format = SDL_PIXELFORMAT_ARGB1555;
        break;
    case 32:
        mode->format = SDL_PIXELFORMAT_ARGB8888;
        break;
    case 8: /* We don't support palettized modes now */
    default: /* Totally unrecognizable bit depth. */
        return SDL_FALSE;
    }
    mode->w = width;
    mode->h = height;
    mode->refresh_rate = refreshRate;
    mode->driverdata = data;
    return SDL_TRUE;
}

static void
Cocoa_ReleaseDisplayMode(_THIS, const void *moderef)
{
    if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
        CGDisplayModeRelease((CGDisplayModeRef) moderef);  /* NULL is ok */
    }
}

static void
Cocoa_ReleaseDisplayModeList(_THIS, CFArrayRef modelist)
{
    if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
        CFRelease(modelist);  /* NULL is ok */
    }
}

static const char *
Cocoa_GetDisplayName(CGDirectDisplayID displayID)
{
    NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
    NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
    const char* displayName = NULL;

    if ([localizedNames count] > 0) {
        displayName = SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
    }
    [deviceInfo release];
    return displayName;
}

void
Cocoa_InitModes(_THIS)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    CGDisplayErr result;
    CGDirectDisplayID *displays;
    CGDisplayCount numDisplays;
    int pass, i;

    result = CGGetOnlineDisplayList(0, NULL, &numDisplays);
    if (result != kCGErrorSuccess) {
        CG_SetError("CGGetOnlineDisplayList()", result);
        [pool release];
        return;
    }
    displays = SDL_stack_alloc(CGDirectDisplayID, numDisplays);
    result = CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
    if (result != kCGErrorSuccess) {
        CG_SetError("CGGetOnlineDisplayList()", result);
        SDL_stack_free(displays);
        [pool release];
        return;
    }

    /* Pick up the primary display in the first pass, then get the rest */
    for (pass = 0; pass < 2; ++pass) {
        for (i = 0; i < numDisplays; ++i) {
            SDL_VideoDisplay display;
            SDL_DisplayData *displaydata;
            SDL_DisplayMode mode;
            const void *moderef = NULL;

            if (pass == 0) {
                if (!CGDisplayIsMain(displays[i])) {
                    continue;
                }
            } else {
                if (CGDisplayIsMain(displays[i])) {
                    continue;
                }
            }

            if (CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay) {
                continue;
            }

            if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
                moderef = CGDisplayCopyDisplayMode(displays[i]);
            }

            #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
            if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
                moderef = CGDisplayCurrentMode(displays[i]);
            }
            #endif

            if (!moderef) {
                continue;
            }

            displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
            if (!displaydata) {
                Cocoa_ReleaseDisplayMode(_this, moderef);
                continue;
            }
            displaydata->display = displays[i];

            SDL_zero(display);
            /* this returns a stddup'ed string */
            display.name = (char *)Cocoa_GetDisplayName(displays[i]);
            if (!GetDisplayMode (_this, moderef, &mode)) {
                Cocoa_ReleaseDisplayMode(_this, moderef);
                SDL_free(display.name);
                SDL_free(displaydata);
                continue;
            }

            display.desktop_mode = mode;
            display.current_mode = mode;
            display.driverdata = displaydata;
            SDL_AddVideoDisplay(&display);
            SDL_free(display.name);
        }
    }
    SDL_stack_free(displays);
    [pool release];
}

int
Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
{
    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
    CGRect cgrect;

    cgrect = CGDisplayBounds(displaydata->display);
    rect->x = (int)cgrect.origin.x;
    rect->y = (int)cgrect.origin.y;
    rect->w = (int)cgrect.size.width;
    rect->h = (int)cgrect.size.height;
    return 0;
}

void
Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    CFArrayRef modes = NULL;

    if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
        modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
    }

    #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
        modes = CGDisplayAvailableModes(data->display);
    }
    #endif

    if (modes) {
        const CFIndex count = CFArrayGetCount(modes);
        CFIndex i;

        for (i = 0; i < count; i++) {
            const void *moderef = CFArrayGetValueAtIndex(modes, i);
            SDL_DisplayMode mode;
            if (GetDisplayMode(_this, moderef, &mode)) {
                if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
                    CGDisplayModeRetain((CGDisplayModeRef) moderef);
                }
                SDL_AddDisplayMode(display, &mode);
            }
        }

        Cocoa_ReleaseDisplayModeList(_this, modes);
    }
}

static CGError
Cocoa_SwitchMode(_THIS, CGDirectDisplayID display, const void *mode)
{
    if (IS_SNOW_LEOPARD_OR_LATER(_this)) {
        return CGDisplaySetDisplayMode(display, (CGDisplayModeRef) mode, NULL);
    }
 
    #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    if (!IS_SNOW_LEOPARD_OR_LATER(_this)) {
        return CGDisplaySwitchToMode(display, (CFDictionaryRef) mode);
    }
    #endif

    return kCGErrorFailure;
}

int
Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
    SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
    CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
    CGError result;

    /* Fade to black to hide resolution-switching flicker */
    if (CGAcquireDisplayFadeReservation(5, &fade_token) == kCGErrorSuccess) {
        CGDisplayFade(fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
    }

    if (data == display->desktop_mode.driverdata) {
        /* Restoring desktop mode */
        Cocoa_SwitchMode(_this, displaydata->display, data->moderef);

        if (CGDisplayIsMain(displaydata->display)) {
            CGReleaseAllDisplays();
        } else {
            CGDisplayRelease(displaydata->display);
        }

        if (CGDisplayIsMain(displaydata->display)) {
            Cocoa_ToggleMenuBar(YES);
        }
    } else {
        /* Put up the blanking window (a window above all other windows) */
        if (CGDisplayIsMain(displaydata->display)) {
            /* If we don't capture all displays, Cocoa tries to rearrange windows... *sigh* */
            result = CGCaptureAllDisplays();
        } else {
            result = CGDisplayCapture(displaydata->display);
        }
        if (result != kCGErrorSuccess) {
            CG_SetError("CGDisplayCapture()", result);
            goto ERR_NO_CAPTURE;
        }

        /* Do the physical switch */
        result = Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
        if (result != kCGErrorSuccess) {
            CG_SetError("CGDisplaySwitchToMode()", result);
            goto ERR_NO_SWITCH;
        }

        /* Hide the menu bar so it doesn't intercept events */
        if (CGDisplayIsMain(displaydata->display)) {
            Cocoa_ToggleMenuBar(NO);
        }
    }

    /* Fade in again (asynchronously) */
    if (fade_token != kCGDisplayFadeReservationInvalidToken) {
        CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
        CGReleaseDisplayFadeReservation(fade_token);
    }

    return 0;

    /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
ERR_NO_SWITCH:
    CGDisplayRelease(displaydata->display);
ERR_NO_CAPTURE:
    if (fade_token != kCGDisplayFadeReservationInvalidToken) {
        CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
        CGReleaseDisplayFadeReservation(fade_token);
    }
    return -1;
}

void
Cocoa_QuitModes(_THIS)
{
    int i, j;

    for (i = 0; i < _this->num_displays; ++i) {
        SDL_VideoDisplay *display = &_this->displays[i];
        SDL_DisplayModeData *mode;

        if (display->current_mode.driverdata != display->desktop_mode.driverdata) {
            Cocoa_SetDisplayMode(_this, display, &display->desktop_mode);
        }

        mode = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
        Cocoa_ReleaseDisplayMode(_this, mode->moderef);

        for (j = 0; j < display->num_display_modes; j++) {
            mode = (SDL_DisplayModeData*) display->display_modes[j].driverdata;
            Cocoa_ReleaseDisplayMode(_this, mode->moderef);
        }

    }
    Cocoa_ToggleMenuBar(YES);
}

#endif /* SDL_VIDEO_DRIVER_COCOA */

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