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

#if SDL_VIDEO_DRIVER_DIRECTFB

#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_window.h"

#include "../../events/SDL_windowevents_c.h"

#define COLOR_EXPAND(col) col.r, col.g, col.b, col.a

static DFB_Theme theme_std = {
    4, 4, 8, 8,
    {255, 200, 200, 200},
    24,
    {255, 0, 0, 255},
    16,
    {255, 255, 255, 255},
    "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
    {255, 255, 0, 0},
    {255, 255, 255, 0},
};

static DFB_Theme theme_none = {
    0, 0, 0, 0,
    {0, 0, 0, 0},
    0,
    {0, 0, 0, 0},
    0,
    {0, 0, 0, 0},
    NULL
};

static void
DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w)
{
    int x1, x2, x3;
    int y1, y2, y3;

    if (down) {
        x1 = x + w / 2;
        x2 = x;
        x3 = x + w;
        y1 = y + w;
        y2 = y;
        y3 = y;
    } else {
        x1 = x + w / 2;
        x2 = x;
        x3 = x + w;
        y1 = y;
        y2 = y + w;
        y3 = y + w;
    }
    s->FillTriangle(s, x1, y1, x2, y2, x3, y3);
}

static void
LoadFont(_THIS, SDL_Window * window)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);

    if (windata->font != NULL) {
        SDL_DFB_RELEASE(windata->font);
        windata->font = NULL;
        SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
    }

    if (windata->theme.font != NULL)
    {
        DFBFontDescription fdesc;

        SDL_zero(fdesc);
        fdesc.flags = DFDESC_HEIGHT;
        fdesc.height = windata->theme.font_size;
        SDL_DFB_CHECK(devdata->
                      dfb->CreateFont(devdata->dfb, windata->theme.font,
                                      &fdesc, &windata->font));
        SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
    }
}

static void
DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text)
{
    DFBSurfaceTextFlags flags;

    flags = DSTF_CENTER | DSTF_TOP;

    s->DrawString(s, text, -1, x, y, flags);
}

void
DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    IDirectFBSurface *s = windata->window_surface;
    DFB_Theme *t = &windata->theme;
    int i;
    int d = (t->caption_size - t->font_size) / 2;
    int x, y, w;


    if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN))
        return;

    SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE));
    SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO));
    SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX));
    SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX));

    LoadFont(_this, window);
    /* s->SetDrawingFlags(s, DSDRAW_BLEND); */
    s->SetColor(s, COLOR_EXPAND(t->frame_color));
    /* top */
    for (i = 0; i < t->top_size; i++)
        s->DrawLine(s, 0, i, windata->size.w, i);
    /* bottom */
    for (i = windata->size.h - t->bottom_size; i < windata->size.h; i++)
        s->DrawLine(s, 0, i, windata->size.w, i);
    /* left */
    for (i = 0; i < t->left_size; i++)
        s->DrawLine(s, i, 0, i, windata->size.h);
    /* right */
    for (i = windata->size.w - t->right_size; i < windata->size.w; i++)
        s->DrawLine(s, i, 0, i, windata->size.h);
    /* Caption */
    s->SetColor(s, COLOR_EXPAND(t->caption_color));
    s->FillRectangle(s, t->left_size, t->top_size, windata->client.w,
                     t->caption_size);
    /* Close Button */
    w = t->caption_size;
    x = windata->size.w - t->right_size - w + d;
    y = t->top_size + d;
    s->SetColor(s, COLOR_EXPAND(t->close_color));
    DrawTriangle(s, 1, x, y, w - 2 * d);
    /* Max Button */
    s->SetColor(s, COLOR_EXPAND(t->max_color));
    DrawTriangle(s, window->flags & SDL_WINDOW_MAXIMIZED ? 1 : 0, x - w,
               y, w - 2 * d);

    /* Caption */
    if (window->title) {
        s->SetColor(s, COLOR_EXPAND(t->font_color));
        DrawCraption(_this, s, (x - w) / 2, t->top_size + d, window->title);
    }
    /* Icon */
    if (windata->icon) {
        DFBRectangle dr;

        dr.x = t->left_size + d;
        dr.y = t->top_size + d;
        dr.w = w - 2 * d;
        dr.h = w - 2 * d;
        s->SetBlittingFlags(s, DSBLIT_BLEND_ALPHACHANNEL);

        s->StretchBlit(s, windata->icon, NULL, &dr);
    }
    windata->wm_needs_redraw = 0;
}

DFBResult
DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
{
    SDL_DFB_WINDOWDATA(window);
    IDirectFBWindow *dfbwin = windata->dfbwin;

    SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch));
    dfbwin->GetSize(dfbwin, cw, ch);
    *cw -= windata->theme.left_size + windata->theme.right_size;
    *ch -=
        windata->theme.top_size + windata->theme.caption_size +
        windata->theme.bottom_size;
    return DFB_OK;
}

void
DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h)
{
    SDL_DFB_WINDOWDATA(window);

    if (!windata->is_managed)
        windata->theme = theme_none;
    else if (flags & SDL_WINDOW_BORDERLESS)
        /* desc.caps |= DWCAPS_NODECORATION;) */
        windata->theme = theme_none;
    else if (flags & SDL_WINDOW_FULLSCREEN) {
        windata->theme = theme_none;
    } else if (flags & SDL_WINDOW_MAXIMIZED) {
        windata->theme = theme_std;
        windata->theme.left_size = 0;
        windata->theme.right_size = 0;
        windata->theme.top_size = 0;
        windata->theme.bottom_size = 0;
    } else {
        windata->theme = theme_std;
    }

    windata->client.x = windata->theme.left_size;
    windata->client.y = windata->theme.top_size + windata->theme.caption_size;
    windata->client.w = w;
    windata->client.h = h;
    windata->size.w =
        w + windata->theme.left_size + windata->theme.right_size;
    windata->size.h =
        h + windata->theme.top_size +
        windata->theme.caption_size + windata->theme.bottom_size;
}


enum
{
    WM_POS_NONE = 0x00,
    WM_POS_CAPTION = 0x01,
    WM_POS_CLOSE = 0x02,
    WM_POS_MAX = 0x04,
    WM_POS_LEFT = 0x08,
    WM_POS_RIGHT = 0x10,
    WM_POS_TOP = 0x20,
    WM_POS_BOTTOM = 0x40,
};

static int
WMIsClient(DFB_WindowData * p, int x, int y)
{
    x -= p->client.x;
    y -= p->client.y;
    if (x < 0 || y < 0)
        return 0;
    if (x >= p->client.w || y >= p->client.h)
        return 0;
    return 1;
}

static int
WMPos(DFB_WindowData * p, int x, int y)
{
    int pos = WM_POS_NONE;

    if (!WMIsClient(p, x, y)) {
        if (y < p->theme.top_size) {
            pos |= WM_POS_TOP;
        } else if (y < p->client.y) {
            if (x <
                p->size.w - p->theme.right_size - 2 * p->theme.caption_size) {
                pos |= WM_POS_CAPTION;
            } else if (x <
                       p->size.w - p->theme.right_size -
                       p->theme.caption_size) {
                pos |= WM_POS_MAX;
            } else {
                pos |= WM_POS_CLOSE;
            }
        } else if (y >= p->size.h - p->theme.bottom_size) {
            pos |= WM_POS_BOTTOM;
        }
        if (x < p->theme.left_size) {
            pos |= WM_POS_LEFT;
        } else if (x >= p->size.w - p->theme.right_size) {
            pos |= WM_POS_RIGHT;
        }
    }
    return pos;
}

int
DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
    IDirectFBWindow *dfbwin = windata->dfbwin;
    DFBWindowOptions wopts;

    if (!windata->is_managed)
        return 0;

    SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts));

    switch (evt->type) {
    case DWET_BUTTONDOWN:
        if (evt->buttons & DIBM_LEFT) {
            int pos = WMPos(windata, evt->x, evt->y);
            switch (pos) {
            case WM_POS_NONE:
                return 0;
            case WM_POS_CLOSE:
                windata->wm_grab = WM_POS_NONE;
                SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0,
                                    0);
                return 1;
            case WM_POS_MAX:
                windata->wm_grab = WM_POS_NONE;
                if (window->flags & SDL_WINDOW_MAXIMIZED) {
                    SDL_RestoreWindow(window);
                } else {
                    SDL_MaximizeWindow(window);
                }
                return 1;
            case WM_POS_CAPTION:
                if (!(wopts & DWOP_KEEP_STACKING)) {
                    DirectFB_RaiseWindow(_this, window);
                }
                if (window->flags & SDL_WINDOW_MAXIMIZED)
                    return 1;
                /* fall through */
            default:
                windata->wm_grab = pos;
                if (gwindata != NULL)
                    SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
                SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin));
                windata->wm_lastx = evt->cx;
                windata->wm_lasty = evt->cy;
            }
        }
        return 1;
    case DWET_BUTTONUP:
        if (!windata->wm_grab)
            return 0;
        if (!(evt->buttons & DIBM_LEFT)) {
            if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
                int dx = evt->cx - windata->wm_lastx;
                int dy = evt->cy - windata->wm_lasty;

                if (!(wopts & DWOP_KEEP_SIZE)) {
                    int cw, ch;
                    if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
                        dx = 0;
                    else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
                        dy = 0;
                    SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));

                    /* necessary to trigger an event - ugly */
                    SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
                    SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy));
                    SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));

                    SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
                }
            }
            SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin));
            if (gwindata != NULL)
                SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin));
            windata->wm_grab = WM_POS_NONE;
            return 1;
        }
        break;
    case DWET_MOTION:
        if (!windata->wm_grab)
            return 0;
        if (evt->buttons & DIBM_LEFT) {
            int dx = evt->cx - windata->wm_lastx;
            int dy = evt->cy - windata->wm_lasty;

            if (windata->wm_grab & WM_POS_CAPTION) {
                if (!(wopts & DWOP_KEEP_POSITION))
                    SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy));
            }
            if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
                if (!(wopts & DWOP_KEEP_SIZE)) {
                    int cw, ch;

                    /* Make sure all events are disabled for this operation ! */
                    SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));

                    if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
                        dx = 0;
                    else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
                        dy = 0;

                    SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
                    SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));

                    SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
                }
            }
            windata->wm_lastx = evt->cx;
            windata->wm_lasty = evt->cy;
            return 1;
        }
        break;
    case DWET_KEYDOWN:
        break;
    case DWET_KEYUP:
        break;
    default:
        ;
    }
    return 0;
}

#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
