/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 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_assert.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) {
        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 bitmap_pixel,pixel_value = 0,mask_value = 0;
    SDL_Color key;
    if(SDL_MUSTLOCK(shape))
        SDL_LockSurface(shape);
    for(y = 0;y<shape->h;y++) {
        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 = *(Uint8*)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);
            bitmap_pixel = y*shape->w + x;
            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[bitmap_pixel / ppb] |= mask_value << (7 - ((ppb - 1) - (bitmap_pixel % 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 = *(Uint8*)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 = {0,0,shape->w,shape->h};
    SDL_ShapeTree* result = NULL;
    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 **)&(*shape_tree)->data.children.upleft);
        SDL_FreeShapeTree((SDL_ShapeTree **)&(*shape_tree)->data.children.upright);
        SDL_FreeShapeTree((SDL_ShapeTree **)&(*shape_tree)->data.children.downleft);
        SDL_FreeShapeTree((SDL_ShapeTree **)&(*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;
}
