/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 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"

#include "SDL.h"
#include "SDL_video.h"
#include "SDL_sysvideo.h"
#include "SDL_pixels.h"
#include "SDL_surface.h"
#include "SDL_shape.h"
#include "SDL_shape_internals.h"

SDL_Window*
SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags)
{
    SDL_Window *result = NULL;
    result = SDL_CreateWindow(title,-1000,-1000,w,h,(flags | SDL_WINDOW_BORDERLESS) & (~SDL_WINDOW_FULLSCREEN) & (~SDL_WINDOW_RESIZABLE) /* & (~SDL_WINDOW_SHOWN) */);
    if(result != NULL) {
        if (SDL_GetVideoDevice()->shape_driver.CreateShaper == NULL) {
            SDL_DestroyWindow(result);
            return NULL;
        }
        result->shaper = SDL_GetVideoDevice()->shape_driver.CreateShaper(result);
        if(result->shaper != NULL) {
            result->shaper->userx = x;
            result->shaper->usery = y;
            result->shaper->mode.mode = ShapeModeDefault;
            result->shaper->mode.parameters.binarizationCutoff = 1;
            result->shaper->hasshape = SDL_FALSE;
            return result;
        }
        else {
            SDL_DestroyWindow(result);
            return NULL;
        }
    }
    else
        return NULL;
}

SDL_bool
SDL_IsShapedWindow(const SDL_Window *window)
{
    if(window == NULL)
        return SDL_FALSE;
    else
        return (SDL_bool)(window->shaper != NULL);
}

/* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */
void
SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb)
{
    int x = 0;
    int y = 0;
    Uint8 r = 0,g = 0,b = 0,alpha = 0;
    Uint8* pixel = NULL;
    Uint32 pixel_value = 0,mask_value = 0;
    int bytes_per_scanline = (shape->w + (ppb - 1)) / ppb;
    Uint8 *bitmap_scanline;
    SDL_Color key;
    if(SDL_MUSTLOCK(shape))
        SDL_LockSurface(shape);
    for(y = 0;y<shape->h;y++) {
        bitmap_scanline = bitmap + y * bytes_per_scanline;
        for(x=0;x<shape->w;x++) {
            alpha = 0;
            pixel_value = 0;
            pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
            switch(shape->format->BytesPerPixel) {
                case(1):
                    pixel_value = *pixel;
                    break;
                case(2):
                    pixel_value = *(Uint16*)pixel;
                    break;
                case(3):
                    pixel_value = *(Uint32*)pixel & (~shape->format->Amask);
                    break;
                case(4):
                    pixel_value = *(Uint32*)pixel;
                    break;
            }
            SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha);
            switch(mode.mode) {
                case(ShapeModeDefault):
                    mask_value = (alpha >= 1 ? 1 : 0);
                    break;
                case(ShapeModeBinarizeAlpha):
                    mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0);
                    break;
                case(ShapeModeReverseBinarizeAlpha):
                    mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0);
                    break;
                case(ShapeModeColorKey):
                    key = mode.parameters.colorKey;
                    mask_value = ((key.r != r || key.g != g || key.b != b) ? 1 : 0);
                    break;
            }
            bitmap_scanline[x / ppb] |= mask_value << (x % ppb);
        }
    }
    if(SDL_MUSTLOCK(shape))
        SDL_UnlockSurface(shape);
}

static SDL_ShapeTree*
RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* mask,SDL_Rect dimensions) {
    int x = 0,y = 0;
    Uint8* pixel = NULL;
    Uint32 pixel_value = 0;
    Uint8 r = 0,g = 0,b = 0,a = 0;
    SDL_bool pixel_opaque = SDL_FALSE;
    int last_opaque = -1;
    SDL_Color key;
    SDL_ShapeTree* result = (SDL_ShapeTree*)SDL_malloc(sizeof(SDL_ShapeTree));
    SDL_Rect next = {0,0,0,0};

    for(y=dimensions.y;y<dimensions.y + dimensions.h;y++) {
        for(x=dimensions.x;x<dimensions.x + dimensions.w;x++) {
            pixel_value = 0;
            pixel = (Uint8 *)(mask->pixels) + (y*mask->pitch) + (x*mask->format->BytesPerPixel);
            switch(mask->format->BytesPerPixel) {
                case(1):
                    pixel_value = *pixel;
                    break;
                case(2):
                    pixel_value = *(Uint16*)pixel;
                    break;
                case(3):
                    pixel_value = *(Uint32*)pixel & (~mask->format->Amask);
                    break;
                case(4):
                    pixel_value = *(Uint32*)pixel;
                    break;
            }
            SDL_GetRGBA(pixel_value,mask->format,&r,&g,&b,&a);
            switch(mode.mode) {
                case(ShapeModeDefault):
                    pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE);
                    break;
                case(ShapeModeBinarizeAlpha):
                    pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
                    break;
                case(ShapeModeReverseBinarizeAlpha):
                    pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
                    break;
                case(ShapeModeColorKey):
                    key = mode.parameters.colorKey;
                    pixel_opaque = ((key.r != r || key.g != g || key.b != b) ? SDL_TRUE : SDL_FALSE);
                    break;
            }
            if(last_opaque == -1)
                last_opaque = pixel_opaque;
            if(last_opaque != pixel_opaque) {
                const int halfwidth = dimensions.w / 2;
                const int halfheight = dimensions.h / 2;

                result->kind = QuadShape;

                next.x = dimensions.x;
                next.y = dimensions.y;
                next.w = halfwidth;
                next.h = halfheight;
                result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);

                next.x = dimensions.x + halfwidth;
                next.w = dimensions.w - halfwidth;
                result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);

                next.x = dimensions.x;
                next.w = halfwidth;
                next.y = dimensions.y + halfheight;
                next.h = dimensions.h - halfheight;
                result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);

                next.x = dimensions.x + halfwidth;
                next.w = dimensions.w - halfwidth;
                result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);

                return result;
            }
        }
    }


    /* If we never recursed, all the pixels in this quadrant have the same "value". */
    result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape);
    result->data.shape = dimensions;
    return result;
}

SDL_ShapeTree*
SDL_CalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* shape)
{
    SDL_Rect dimensions;
    SDL_ShapeTree* result = NULL;

    dimensions.x = 0;
    dimensions.y = 0;
    dimensions.w = shape->w;
    dimensions.h = shape->h;

    if(SDL_MUSTLOCK(shape))
        SDL_LockSurface(shape);
    result = RecursivelyCalculateShapeTree(mode,shape,dimensions);
    if(SDL_MUSTLOCK(shape))
        SDL_UnlockSurface(shape);
    return result;
}

void
SDL_TraverseShapeTree(SDL_ShapeTree *tree,SDL_TraversalFunction function,void* closure)
{
    SDL_assert(tree != NULL);
    if(tree->kind == QuadShape) {
        SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft,function,closure);
        SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright,function,closure);
        SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft,function,closure);
        SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright,function,closure);
    }
    else
        function(tree,closure);
}

void
SDL_FreeShapeTree(SDL_ShapeTree** shape_tree)
{
    if((*shape_tree)->kind == QuadShape) {
        SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.upleft);
        SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.upright);
        SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.downleft);
        SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.downright);
    }
    SDL_free(*shape_tree);
    *shape_tree = NULL;
}

int
SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode)
{
    int result;
    if(window == NULL || !SDL_IsShapedWindow(window))
        /* The window given was not a shapeable window. */
        return SDL_NONSHAPEABLE_WINDOW;
    if(shape == NULL)
        /* Invalid shape argument. */
        return SDL_INVALID_SHAPE_ARGUMENT;

    if(shape_mode != NULL)
        window->shaper->mode = *shape_mode;
    result = SDL_GetVideoDevice()->shape_driver.SetWindowShape(window->shaper,shape,shape_mode);
    window->shaper->hasshape = SDL_TRUE;
    if(window->shaper->userx != 0 && window->shaper->usery != 0) {
        SDL_SetWindowPosition(window,window->shaper->userx,window->shaper->usery);
        window->shaper->userx = 0;
        window->shaper->usery = 0;
    }
    return result;
}

static SDL_bool
SDL_WindowHasAShape(SDL_Window *window)
{
    if (window == NULL || !SDL_IsShapedWindow(window))
        return SDL_FALSE;
    return window->shaper->hasshape;
}

int
SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode)
{
    if(window != NULL && SDL_IsShapedWindow(window)) {
        if(shape_mode == NULL) {
            if(SDL_WindowHasAShape(window))
                /* The window given has a shape. */
                return 0;
            else
                /* The window given is shapeable but lacks a shape. */
                return SDL_WINDOW_LACKS_SHAPE;
        }
        else {
            *shape_mode = window->shaper->mode;
            return 0;
        }
    }
    else
        /* The window given is not a valid shapeable window. */
        return SDL_NONSHAPEABLE_WINDOW;
}
