/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2014 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) {
                result->kind = QuadShape;
                /* These will stay the same. */
                next.w = dimensions.w / 2;
                next.h = dimensions.h / 2;
                /* These will change from recursion to recursion. */
                next.x = dimensions.x;
                next.y = dimensions.y;
                result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
                next.x += next.w;
                /* Unneeded: next.y = dimensions.y; */
                result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
                next.x = dimensions.x;
                next.y += next.h;
                result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
                next.x += next.w;
                /* Unneeded: next.y = dimensions.y + dimensions.h /2; */
                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;
}
