/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/skin/window.h"
#include "android/skin/image.h"
#include "android/skin/scaler.h"
#include "android/charmap.h"
#include "android/utils/debug.h"
#include "android/hw-sensors.h"
#include <SDL_syswm.h>
#include "qemu-common.h"
#include <math.h>

#include "framebuffer.h"

/* when shrinking, we reduce the pixel ratio by this fixed amount */
#define  SHRINK_SCALE  0.6

/* maximum value of LCD brighness */
#define  LCD_BRIGHTNESS_MIN      0
#define  LCD_BRIGHTNESS_DEFAULT  128
#define  LCD_BRIGHTNESS_MAX      255

typedef struct Background {
    SkinImage*   image;
    SkinRect     rect;
    SkinPos      origin;
} Background;

static void
background_done( Background*  back )
{
    skin_image_unref( &back->image );
}

static void
background_init( Background*  back, SkinBackground*  sback, SkinLocation*  loc, SkinRect*  frame )
{
    SkinRect  r;

    back->image = skin_image_rotate( sback->image, loc->rotation );
    skin_rect_rotate( &r, &sback->rect, loc->rotation );
    r.pos.x += loc->anchor.x;
    r.pos.y += loc->anchor.y;

    back->origin = r.pos;
    skin_rect_intersect( &back->rect, &r, frame );
}

static void
background_redraw( Background*  back, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &back->rect ) )
    {
        SDL_Rect  rd, rs;

        rd.x = r.pos.x;
        rd.y = r.pos.y;
        rd.w = r.size.w;
        rd.h = r.size.h;

        rs.x = r.pos.x - back->origin.x;
        rs.y = r.pos.y - back->origin.y;
        rs.w = r.size.w;
        rs.h = r.size.h;

        SDL_BlitSurface( skin_image_surface(back->image), &rs, surface, &rd );
        //SDL_UpdateRects( surface, 1, &rd );
    }
}


typedef struct ADisplay {
    SkinRect       rect;
    SkinPos        origin;
    SkinRotation   rotation;
    SkinSize       datasize;  /* framebuffer size */
    void*          data;      /* framebuffer pixels */
    QFrameBuffer*  qfbuff;
    SkinImage*     onion;       /* onion image */
    SkinRect       onion_rect;  /* onion rect, if any */
    int            brightness;
} ADisplay;

static void
display_done( ADisplay*  disp )
{
    disp->data   = NULL;
    disp->qfbuff = NULL;
    skin_image_unref( &disp->onion );
}

static int
display_init( ADisplay*  disp, SkinDisplay*  sdisp, SkinLocation*  loc, SkinRect*  frame )
{
    skin_rect_rotate( &disp->rect, &sdisp->rect, loc->rotation );
    disp->rect.pos.x += loc->anchor.x;
    disp->rect.pos.y += loc->anchor.y;

    disp->rotation = (loc->rotation + sdisp->rotation) & 3;
    switch (disp->rotation) {
        case SKIN_ROTATION_0:
            disp->origin = disp->rect.pos;
            break;

        case SKIN_ROTATION_90:
            disp->origin.x = disp->rect.pos.x + disp->rect.size.w;
            disp->origin.y = disp->rect.pos.y;
            break;

        case SKIN_ROTATION_180:
            disp->origin.x = disp->rect.pos.x + disp->rect.size.w;
            disp->origin.y = disp->rect.pos.y + disp->rect.size.h;
            break;

        default:
            disp->origin.x = disp->rect.pos.x;
            disp->origin.y = disp->rect.pos.y + disp->rect.size.h;
            break;
    }
    skin_size_rotate( &disp->datasize, &sdisp->rect.size, sdisp->rotation );
    skin_rect_intersect( &disp->rect, &disp->rect, frame );
#if 0
    fprintf(stderr, "... display_init  rect.pos(%d,%d) rect.size(%d,%d) datasize(%d,%d)\n",
                    disp->rect.pos.x, disp->rect.pos.y,
                    disp->rect.size.w, disp->rect.size.h,
                    disp->datasize.w, disp->datasize.h);
#endif
    disp->qfbuff = sdisp->qfbuff;
    disp->data   = sdisp->qfbuff->pixels;
    disp->onion  = NULL;

    disp->brightness = LCD_BRIGHTNESS_DEFAULT;

    return (disp->data == NULL) ? -1 : 0;
}

static __inline__ uint32_t  rgb565_to_argb32( uint32_t  pix )
{
    uint32_t  r = ((pix & 0xf800) << 8) | ((pix & 0xe000) << 3);
    uint32_t  g = ((pix & 0x07e0) << 5) | ((pix & 0x0600) >> 1);
    uint32_t  b = ((pix & 0x001f) << 3) | ((pix & 0x001c) >> 2);

    return 0xff000000 | r | g | b;
}


static void
display_set_onion( ADisplay*  disp, SkinImage*  onion, SkinRotation  rotation, int  blend )
{
    int        onion_w, onion_h;
    SkinRect*  rect  = &disp->rect;
    SkinRect*  orect = &disp->onion_rect;

    rotation = (rotation + disp->rotation) & 3;

    skin_image_unref( &disp->onion );
    disp->onion = skin_image_clone_full( onion, rotation, blend );

    onion_w = skin_image_w(disp->onion);
    onion_h = skin_image_h(disp->onion);

    switch (rotation) {
        case SKIN_ROTATION_0:
            orect->pos = rect->pos;
            break;

        case SKIN_ROTATION_90:
            orect->pos.x = rect->pos.x + rect->size.w - onion_w;
            orect->pos.y = rect->pos.y;
            break;

        case SKIN_ROTATION_180:
            orect->pos.x = rect->pos.x + rect->size.w - onion_w;
            orect->pos.y = rect->pos.y + rect->size.h - onion_h;
            break;

        default:
            orect->pos.x = rect->pos.x;
            orect->pos.y = rect->pos.y + rect->size.h - onion_h;
    }
    orect->size.w = onion_w;
    orect->size.h = onion_h;
}

#define  DOT_MATRIX  0

#if DOT_MATRIX

static void
dotmatrix_dither_argb32( unsigned char*  pixels, int  x, int  y, int  w, int  h, int  pitch )
{
    static const unsigned dotmatrix_argb32[16] = {
        0x003f00, 0x00003f, 0x3f0000, 0x000000,
        0x3f3f3f, 0x000000, 0x3f3f3f, 0x000000,
        0x3f0000, 0x000000, 0x003f00, 0x00003f,
        0x3f3f3f, 0x000000, 0x3f3f3f, 0x000000
    };

    int   yy = y & 3;

    pixels += 4*x + y*pitch;

    for ( ; h > 0; h-- ) {
        unsigned*  line = (unsigned*) pixels;
        int        nn, xx = x & 3;

        for (nn = 0; nn < w; nn++) {
            unsigned  c = line[nn];

            c = c - ((c >> 2) & dotmatrix_argb32[(yy << 2)|xx]);

            xx = (xx + 1) & 3;
            line[nn] = c;
        }

        yy      = (yy + 1) & 3;
        pixels += pitch;
    }
}

#endif /* DOT_MATRIX */

/* technical note about the lightness emulation
 *
 * we try to emulate something that looks like the Dream's
 * non-linear LCD lightness, without going too dark or bright.
 *
 * the default lightness is around 105 (about 40%) and we prefer
 * to keep full RGB colors at that setting, to not alleviate
 * developers who will not understand why the emulator's colors
 * look slightly too dark.
 *
 * we also want to implement a 'bright' mode by de-saturating
 * colors towards bright white.
 *
 * All of this leads to the implementation below that looks like
 * the following:
 *
 * if (level == MIN)
 *     screen is off
 *
 * if (level > MIN && level < LOW)
 *     interpolate towards black, with
 *     MINALPHA = 0.2
 *     alpha = MINALPHA + (1-MINALPHA)*(level-MIN)/(LOW-MIN)
 *
 * if (level >= LOW && level <= HIGH)
 *     keep full RGB colors
 *
 * if (level > HIGH)
 *     interpolate towards bright white, with
 *     MAXALPHA = 0.6
 *     alpha = MAXALPHA*(level-HIGH)/(MAX-HIGH)
 *
 * we probably want some sort of power law instead of interpolating
 * linearly, but frankly, this is sufficient for most uses.
 */

#define  LCD_BRIGHTNESS_LOW   80
#define  LCD_BRIGHTNESS_HIGH  180

#define  LCD_ALPHA_LOW_MIN      0.2
#define  LCD_ALPHA_HIGH_MAX     0.6

/* treat as special value to turn screen off */
#define  LCD_BRIGHTNESS_OFF   LCD_BRIGHTNESS_MIN

static void
lcd_brightness_argb32( unsigned char*  pixels, SkinRect*  r, int  pitch, int  brightness )
{
    const unsigned  b_min  = LCD_BRIGHTNESS_MIN;
    const unsigned  b_max  = LCD_BRIGHTNESS_MAX;
    const unsigned  b_low  = LCD_BRIGHTNESS_LOW;
    const unsigned  b_high = LCD_BRIGHTNESS_HIGH;

    unsigned        alpha = brightness;
    int             w     = r->size.w;
    int             h     = r->size.h;

    if (alpha <= b_min)
        alpha = b_min;
    else if (alpha > b_max)
        alpha = b_max;

    pixels += 4*r->pos.x + r->pos.y*pitch;

    if (alpha < b_low)
    {
        const unsigned  alpha_min   = (255*LCD_ALPHA_LOW_MIN);
        const unsigned  alpha_range = (255 - alpha_min);

        alpha = alpha_min + ((alpha - b_min)*alpha_range) / (b_low - b_min);

        for ( ; h > 0; h-- ) {
            unsigned*  line = (unsigned*) pixels;
            int        nn;

            for (nn = 0; nn < w; nn++) {
                unsigned  c  = line[nn];
                unsigned  ag = (c >> 8) & 0x00ff00ff;
                unsigned  rb = (c)      & 0x00ff00ff;

                ag = (ag*alpha)        & 0xff00ff00;
                rb = ((rb*alpha) >> 8) & 0x00ff00ff;

                line[nn] = (unsigned)(ag | rb);
            }
            pixels += pitch;
        }
    }
    else if (alpha > LCD_BRIGHTNESS_HIGH) /* 'superluminous' mode */
    {
        const unsigned  alpha_max   = (255*LCD_ALPHA_HIGH_MAX);
        const unsigned  alpha_range = (255-alpha_max);
        unsigned        ialpha;

        alpha  = ((alpha - b_high)*alpha_range) / (b_max - b_high);
        ialpha = 255-alpha;

        for ( ; h > 0; h-- ) {
            unsigned*  line = (unsigned*) pixels;
            int        nn;

            for (nn = 0; nn < w; nn++) {
                unsigned  c  = line[nn];
                unsigned  ag = (c >> 8) & 0x00ff00ff;
                unsigned  rb = (c)      & 0x00ff00ff;

                /* interpolate towards bright white, i.e. 0x00ffffff */
                ag = ((ag*ialpha + 0x00ff00ff*alpha)) & 0xff00ff00;
                rb = ((rb*ialpha + 0x00ff00ff*alpha) >> 8) & 0x00ff00ff;

                line[nn] = (unsigned)(ag | rb);
            }
            pixels += pitch;
        }
    }
}


/* this is called when the LCD framebuffer is off */
static void
lcd_off_argb32( unsigned char*  pixels, SkinRect*  r, int  pitch )
{
    int  x = r->pos.x;
    int  y = r->pos.y;
    int  w = r->size.w;
    int  h = r->size.h;

    pixels += 4*x + y*pitch;
    for ( ; h > 0; h-- ) {
        memset( pixels, 0, w*4 );
        pixels += pitch;
    }
}


static void
display_redraw( ADisplay*  disp, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &disp->rect ))
    {
        int           x  = r.pos.x - disp->rect.pos.x;
        int           y  = r.pos.y - disp->rect.pos.y;
        int           w  = r.size.w;
        int           h  = r.size.h;
        int           disp_w    = disp->rect.size.w;
        int           disp_h    = disp->rect.size.h;
        int           dst_pitch = surface->pitch;
        uint8_t*      dst_line  = (uint8_t*)surface->pixels + r.pos.x*4 + r.pos.y*dst_pitch;
        int           src_pitch = disp->datasize.w*2;
        uint8_t*      src_line  = (uint8_t*)disp->data;
        int           yy, xx;
#if 0
        fprintf(stderr, "--- display redraw r.pos(%d,%d) r.size(%d,%d) "
                        "disp.pos(%d,%d) disp.size(%d,%d) datasize(%d,%d) rect.pos(%d,%d) rect.size(%d,%d)\n",
                        r.pos.x - disp->rect.pos.x, r.pos.y - disp->rect.pos.y, w, h, disp->rect.pos.x, disp->rect.pos.y,
                        disp->rect.size.w, disp->rect.size.h, disp->datasize.w, disp->datasize.h,
                        rect->pos.x, rect->pos.y, rect->size.w, rect->size.h );
#endif
        SDL_LockSurface( surface );

        if (disp->brightness == LCD_BRIGHTNESS_OFF)
        {
            lcd_off_argb32( surface->pixels, &r, dst_pitch );
        }
        else
        {
            switch ( disp->rotation & 3 )
            {
            case ANDROID_ROTATION_0:
                src_line += x*2 + y*src_pitch;

                for (yy = h; yy > 0; yy--)
                {
                    uint32_t*  dst = (uint32_t*)dst_line;
                    uint16_t*  src = (uint16_t*)src_line;

                    for (xx = 0; xx < w; xx++) {
                        dst[xx] = rgb565_to_argb32(src[xx]);
                    }
                    src_line += src_pitch;
                    dst_line += dst_pitch;
                }
                break;

            case ANDROID_ROTATION_90:
                src_line += y*2 + (disp_w - x - 1)*src_pitch;

                for (yy = h; yy > 0; yy--)
                {
                    uint32_t*  dst = (uint32_t*)dst_line;
                    uint8_t*   src = src_line;

                    for (xx = w; xx > 0; xx--)
                    {
                        dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
                        src -= src_pitch;
                        dst += 1;
                    }
                    src_line += 2;
                    dst_line += dst_pitch;
                }
                break;

            case ANDROID_ROTATION_180:
                src_line += (disp_w -1 - x)*2 + (disp_h-1-y)*src_pitch;

                for (yy = h; yy > 0; yy--)
                {
                    uint16_t*  src = (uint16_t*)src_line;
                    uint32_t*  dst = (uint32_t*)dst_line;

                    for (xx = w; xx > 0; xx--) {
                        dst[0] = rgb565_to_argb32(src[0]);
                        src -= 1;
                        dst += 1;
                    }

                    src_line -= src_pitch;
                    dst_line += dst_pitch;
            }
            break;

            default:  /* ANDROID_ROTATION_270 */
                src_line += (disp_h-1-y)*2 + x*src_pitch;

                for (yy = h; yy > 0; yy--)
                {
                    uint32_t*  dst = (uint32_t*)dst_line;
                    uint8_t*   src = src_line;

                    for (xx = w; xx > 0; xx--) {
                        dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
                        dst   += 1;
                        src   += src_pitch;
                    }
                    src_line -= 2;
                    dst_line += dst_pitch;
                }
            }
#if DOT_MATRIX
            dotmatrix_dither_argb32( surface->pixels, r.pos.x, r.pos.y, r.size.w, r.size.h, surface->pitch );
#endif
            /* apply lightness */
            lcd_brightness_argb32( surface->pixels, &r, surface->pitch, disp->brightness );
        }
        SDL_UnlockSurface( surface );

        /* Apply onion skin */
        if (disp->onion != NULL) {
            SkinRect  r2;

            if ( skin_rect_intersect( &r2, &r, &disp->onion_rect ) ) {
                SDL_Rect  rs, rd;

                rd.x = r2.pos.x;
                rd.y = r2.pos.y;
                rd.w = r2.size.w;
                rd.h = r2.size.h;

                rs.x = rd.x - disp->onion_rect.pos.x;
                rs.y = rd.y - disp->onion_rect.pos.y;
                rs.w = rd.w;
                rs.h = rd.h;

                SDL_BlitSurface( skin_image_surface(disp->onion), &rs, surface, &rd );
            }
        }

        SDL_UpdateRect( surface, r.pos.x, r.pos.y, w, h );
    }
}


typedef struct Button {
    SkinImage*       image;
    SkinRect         rect;
    SkinPos          origin;
    Background*      background;
    unsigned         keycode;
    int              down;
} Button;

static void
button_done( Button*  button )
{
    skin_image_unref( &button->image );
    button->background = NULL;
}

static void
button_init( Button*  button, SkinButton*  sbutton, SkinLocation*  loc, Background*  back, SkinRect*  frame )
{
    SkinRect  r;

    button->image      = skin_image_rotate( sbutton->image, loc->rotation );
    button->background = back;
    button->keycode    = sbutton->keycode;
    button->down       = 0;

    skin_rect_rotate( &r, &sbutton->rect, loc->rotation );
    r.pos.x += loc->anchor.x;
    r.pos.y += loc->anchor.y;
    button->origin = r.pos;
    skin_rect_intersect( &button->rect, &r, frame );
}

static void
button_redraw( Button*  button, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &button->rect ))
    {
        if ( button->down && button->image != SKIN_IMAGE_NONE )
        {
            SDL_Rect  rs, rd;

            rs.x = r.pos.x - button->origin.x;
            rs.y = r.pos.y - button->origin.y;
            rs.w = r.size.w;
            rs.h = r.size.h;

            rd.x = r.pos.x;
            rd.y = r.pos.y;
            rd.w = r.size.w;
            rd.h = r.size.h;

            if (button->image != SKIN_IMAGE_NONE) {
                SDL_BlitSurface( skin_image_surface(button->image), &rs, surface, &rd );
                if (button->down > 1)
                    SDL_BlitSurface( skin_image_surface(button->image), &rs, surface, &rd );
            }
        }
    }
}


typedef struct {
    char      tracking;
    char      inside;
    SkinPos   pos;
    ADisplay*  display;
} FingerState;

static void
finger_state_reset( FingerState*  finger )
{
    finger->tracking = 0;
    finger->inside   = 0;
}

typedef struct {
    Button*   pressed;
    Button*   hover;
} ButtonState;

static void
button_state_reset( ButtonState*  button )
{
    button->pressed = NULL;
    button->hover   = NULL;
}

typedef struct {
    char            tracking;
    SkinTrackBall*  ball;
    SkinRect        rect;
    SkinWindow*     window;
} BallState;

static void
ball_state_reset( BallState*  state, SkinWindow*  window )
{
    state->tracking = 0;
    state->ball     = NULL;

    state->rect.pos.x  = 0;
    state->rect.pos.y  = 0;
    state->rect.size.w = 0;
    state->rect.size.h = 0;
    state->window      = window;
}

static void
ball_state_redraw( BallState*  state, SkinRect*  rect, SDL_Surface*  surface )
{
    SkinRect  r;

    if (skin_rect_intersect( &r, rect, &state->rect ))
        skin_trackball_draw( state->ball, 0, 0, surface );
}

static void
ball_state_show( BallState*  state, int  enable )
{
    if (enable) {
        if ( !state->tracking ) {
            state->tracking = 1;
            SDL_ShowCursor(0);
            SDL_WM_GrabInput( SDL_GRAB_ON );
            skin_trackball_refresh( state->ball );
            skin_window_redraw( state->window, &state->rect );
        }
    } else {
        if ( state->tracking ) {
            state->tracking = 0;
            SDL_WM_GrabInput( SDL_GRAB_OFF );
            SDL_ShowCursor(1);
            skin_window_redraw( state->window, &state->rect );
        }
    }
}


static void
ball_state_set( BallState*  state, SkinTrackBall*  ball )
{
    ball_state_show( state, 0 );

    state->ball = ball;
    if (ball != NULL) {
        SDL_Rect  sr;

        skin_trackball_rect( ball, &sr );
        state->rect.pos.x  = sr.x;
        state->rect.pos.y  = sr.y;
        state->rect.size.w = sr.w;
        state->rect.size.h = sr.h;
    }
}

typedef struct Layout {
    int          num_buttons;
    int          num_backgrounds;
    int          num_displays;
    unsigned     color;
    Button*      buttons;
    Background*  backgrounds;
    ADisplay*    displays;
    SkinRect     rect;
    SkinLayout*  slayout;
} Layout;

#define  LAYOUT_LOOP_BUTTONS(layout,button)                          \
    do {                                                             \
        Button*  __button = (layout)->buttons;                       \
        Button*  __button_end = __button + (layout)->num_buttons;    \
        for ( ; __button < __button_end; __button ++ ) {             \
            Button*  button = __button;

#define  LAYOUT_LOOP_END_BUTTONS \
        }                        \
    } while (0);

#define  LAYOUT_LOOP_DISPLAYS(layout,display)                          \
    do {                                                               \
        ADisplay*  __display = (layout)->displays;                     \
        ADisplay*  __display_end = __display + (layout)->num_displays; \
        for ( ; __display < __display_end; __display ++ ) {            \
            ADisplay*  display = __display;

#define  LAYOUT_LOOP_END_DISPLAYS \
        }                         \
    } while (0);


static void
layout_done( Layout*  layout )
{
    int  nn;

    for (nn = 0; nn < layout->num_buttons; nn++)
        button_done( &layout->buttons[nn] );

    for (nn = 0; nn < layout->num_backgrounds; nn++)
        background_done( &layout->backgrounds[nn] );

    for (nn = 0; nn < layout->num_displays; nn++)
        display_done( &layout->displays[nn] );

    qemu_free( layout->buttons );
    layout->buttons = NULL;

    qemu_free( layout->backgrounds );
    layout->backgrounds = NULL;

    qemu_free( layout->displays );
    layout->displays = NULL;

    layout->num_buttons     = 0;
    layout->num_backgrounds = 0;
    layout->num_displays    = 0;
}

static int
layout_init( Layout*  layout, SkinLayout*  slayout )
{
    int       n_buttons, n_backgrounds, n_displays;

    /* first, count the number of elements of each kind */
    n_buttons     = 0;
    n_backgrounds = 0;
    n_displays    = 0;

    layout->color   = slayout->color;
    layout->slayout = slayout;

    SKIN_LAYOUT_LOOP_LOCS(slayout,loc)
        SkinPart*    part = loc->part;

        if ( part->background->valid )
            n_backgrounds += 1;
        if ( part->display->valid )
            n_displays += 1;

        SKIN_PART_LOOP_BUTTONS(part, sbutton)
            n_buttons += 1;
            sbutton=sbutton;
        SKIN_PART_LOOP_END
    SKIN_LAYOUT_LOOP_END

    layout->num_buttons     = n_buttons;
    layout->num_backgrounds = n_backgrounds;
    layout->num_displays    = n_displays;

    /* now allocate arrays, then populate them */
    layout->buttons     = qemu_mallocz( sizeof(Button) *     n_buttons );
    layout->backgrounds = qemu_mallocz( sizeof(Background) * n_backgrounds );
    layout->displays    = qemu_mallocz( sizeof(ADisplay) *    n_displays );

    if (layout->buttons == NULL && n_buttons > 0) goto Fail;
    if (layout->backgrounds == NULL && n_backgrounds > 0) goto Fail;
    if (layout->displays == NULL && n_displays > 0) goto Fail;

    n_buttons     = 0;
    n_backgrounds = 0;
    n_displays    = 0;

    layout->rect.pos.x = 0;
    layout->rect.pos.y = 0;
    layout->rect.size  = slayout->size;

    SKIN_LAYOUT_LOOP_LOCS(slayout,loc)
        SkinPart*    part = loc->part;
        Background*  back = NULL;

        if ( part->background->valid ) {
            back = layout->backgrounds + n_backgrounds;
            background_init( back, part->background, loc, &layout->rect );
            n_backgrounds += 1;
        }
        if ( part->display->valid ) {
            ADisplay*  disp = layout->displays + n_displays;
            display_init( disp, part->display, loc, &layout->rect );
            n_displays += 1;
        }

        SKIN_PART_LOOP_BUTTONS(part, sbutton)
            Button*  button = layout->buttons + n_buttons;
            button_init( button, sbutton, loc, back, &layout->rect );
            n_buttons += 1;
        SKIN_PART_LOOP_END
    SKIN_LAYOUT_LOOP_END

    return 0;

Fail:
    layout_done(layout);
    return -1;
}

struct SkinWindow {
    SDL_Surface*  surface;
    Layout        layout;
    SkinPos       pos;
    FingerState   finger;
    ButtonState   button;
    BallState     ball;
    char          enabled;
    char          fullscreen;
    char          no_display;

    char          enable_touch;
    char          enable_trackball;
    char          enable_dpad;
    char          enable_qwerty;

    SkinImage*    onion;
    SkinRotation  onion_rotation;
    int           onion_alpha;

    int           x_pos;
    int           y_pos;

    SkinScaler*   scaler;
    int           shrink;
    double        shrink_scale;
    unsigned*     shrink_pixels;
    SDL_Surface*  shrink_surface;

    double        effective_scale;
    double        effective_x;
    double        effective_y;
};

static void
add_finger_event(unsigned x, unsigned y, unsigned state)
{
    //fprintf(stderr, "::: finger %d,%d %d\n", x, y, state);

    /* NOTE: the 0 is used in hw/goldfish_events.c to differentiate
     * between a touch-screen and a trackball event
     */
    kbd_mouse_event(x, y, 0, state);
}

static void
skin_window_find_finger( SkinWindow*  window,
                         int          x,
                         int          y )
{
    FingerState*  finger = &window->finger;

    /* find the display that contains this movement */
    finger->display = NULL;
    finger->inside  = 0;

    if (!window->enable_touch)
        return;

    LAYOUT_LOOP_DISPLAYS(&window->layout,disp)
        if ( skin_rect_contains( &disp->rect, x, y ) ) {
            finger->inside   = 1;
            finger->display  = disp;
            finger->pos.x    = x - disp->origin.x;
            finger->pos.y    = y - disp->origin.y;

            skin_pos_rotate( &finger->pos, &finger->pos, -disp->rotation );
            break;
        }
    LAYOUT_LOOP_END_DISPLAYS
}

static void
skin_window_move_mouse( SkinWindow*  window,
                        int          x,
                        int          y )
{
    FingerState*  finger = &window->finger;
    ButtonState*  button = &window->button;

    if (finger->tracking) {
        ADisplay*  disp   = finger->display;
        char       inside = 1;
        int        dx     = x - disp->rect.pos.x;
        int        dy     = y - disp->rect.pos.y;

        if (dx < 0) {
            dx = 0;
            inside = 0;
        }
        else if (dx >= disp->rect.size.w) {
            dx = disp->rect.size.w - 1;
            inside = 0;
        }
        if (dy < 0) {
            dy = 0;
            inside = 0;
        } else if (dy >= disp->rect.size.h) {
            dy = disp->rect.size.h-1;
            inside = 0;
        }
        finger->inside = inside;
        finger->pos.x  = dx + (disp->rect.pos.x - disp->origin.x);
        finger->pos.y  = dy + (disp->rect.pos.y - disp->origin.y);

        skin_pos_rotate( &finger->pos, &finger->pos, -disp->rotation );
    }

    {
        Button*  hover = button->hover;

        if (hover) {
            if ( skin_rect_contains( &hover->rect, x, y ) )
                return;

            hover->down = 0;
            skin_window_redraw( window, &hover->rect );
            button->hover = NULL;
        }

        hover = NULL;
        LAYOUT_LOOP_BUTTONS( &window->layout, butt )
            if ( skin_rect_contains( &butt->rect, x, y ) ) {
                hover = butt;
                break;
            }
        LAYOUT_LOOP_END_BUTTONS

        /* filter DPAD and QWERTY buttons right here */
        if (hover != NULL) {
            switch (hover->keycode) {
                /* these correspond to the DPad */
                case kKeyCodeDpadUp:
                case kKeyCodeDpadDown:
                case kKeyCodeDpadLeft:
                case kKeyCodeDpadRight:
                case kKeyCodeDpadCenter:
                    if (!window->enable_dpad)
                        hover = NULL;
                    break;

                /* these correspond to non-qwerty buttons */
                case kKeyCodeSoftLeft:
                case kKeyCodeSoftRight:
                case kKeyCodeVolumeUp:
                case kKeyCodeVolumeDown:
                case kKeyCodePower:
                case kKeyCodeHome:
                case kKeyCodeBack:
                case kKeyCodeCall:
                case kKeyCodeEndCall:
                    break;

                /* all the rest is assumed to be qwerty */
                default:
                    if (!window->enable_qwerty)
                        hover = NULL;
            }
        }

        if (hover != NULL) {
            hover->down = 1;
            skin_window_redraw( window, &hover->rect );
            button->hover = hover;
        }
    }
}

static void
skin_window_trackball_press( SkinWindow*  window, int  down )
{
    send_key_event(  BTN_MOUSE, down );
}

static void
skin_window_trackball_move( SkinWindow*  window, int  xrel, int  yrel )
{
    BallState*  state = &window->ball;

    if ( skin_trackball_move( state->ball, xrel, yrel ) ) {
        skin_trackball_refresh( state->ball );
        skin_window_redraw( window, &state->rect );
    }
}

void
skin_window_set_trackball( SkinWindow*  window, SkinTrackBall*  ball )
{
    BallState*  state = &window->ball;

    ball_state_set( state, ball );
}

void
skin_window_show_trackball( SkinWindow*  window, int  enable )
{
    BallState*  state = &window->ball;

    if (state->ball != NULL && window->enable_trackball) {
        ball_state_show(state, enable);
    }
}


static int  skin_window_reset_internal (SkinWindow*, SkinLayout*);

SkinWindow*
skin_window_create( SkinLayout*  slayout, int  x, int  y, double  scale, int  no_display )
{
    SkinWindow*  window = qemu_mallocz(sizeof(*window));

    window->shrink_scale = scale;
    window->shrink       = (scale != 1.0);
    window->scaler       = skin_scaler_create();
    window->no_display   = no_display;

    /* enable everything by default */
    window->enable_touch     = 1;
    window->enable_trackball = 1;
    window->enable_dpad      = 1;
    window->enable_qwerty    = 1;

    window->x_pos = x;
    window->y_pos = y;

    if (skin_window_reset_internal(window, slayout) < 0) {
        skin_window_free( window );
        return NULL;
    }
    //SDL_WM_SetCaption( "Android Emulator", "Android Emulator" );

    SDL_WM_SetPos( x, y );
    if ( !SDL_WM_IsFullyVisible( 1 ) ) {
        dprint( "emulator window was out of view and was recentred\n" );
    }

    return window;
}

void
skin_window_enable_touch( SkinWindow*  window, int  enabled )
{
    window->enable_touch = !!enabled;
}

void
skin_window_enable_trackball( SkinWindow*  window, int  enabled )
{
    window->enable_trackball = !!enabled;
}

void
skin_window_enable_dpad( SkinWindow*  window, int  enabled )
{
    window->enable_dpad = !!enabled;
}

void
skin_window_enable_qwerty( SkinWindow*  window, int  enabled )
{
    window->enable_qwerty = !!enabled;
}

void
skin_window_set_title( SkinWindow*  window, const char*  title )
{
    if (window && title)
        SDL_WM_SetCaption( title, title );
}

static void
skin_window_resize( SkinWindow*  window )
{
    /* now resize window */
    if (window->surface) {
        SDL_FreeSurface(window->surface);
        window->surface = NULL;
    }

    if (window->shrink_surface) {
        SDL_FreeSurface(window->shrink_surface);
        window->shrink_surface = NULL;
    }

    if (window->shrink_pixels) {
        qemu_free(window->shrink_pixels);
        window->shrink_pixels = NULL;
    }

    if ( !window->no_display ) {
        int           layout_w = window->layout.rect.size.w;
        int           layout_h = window->layout.rect.size.h;
        int           window_w = layout_w;
        int           window_h = layout_h;
        int           window_x = window->x_pos;
        int           window_y = window->y_pos;
        int           flags;
        SDL_Surface*  surface;
        double        scale = 1.0;
        int           fullscreen = window->fullscreen;

        if (fullscreen) {
            SDL_Rect  r;
            if (SDL_WM_GetMonitorRect(&r) < 0) {
                fullscreen = 0;
            } else {
                double  x_scale, y_scale;

                window_x = r.x;
                window_y = r.y;
                window_w = r.w;
                window_h = r.h;

                x_scale = window_w * 1.0 / layout_w;
                y_scale = window_h * 1.0 / layout_h;

                scale = (x_scale <= y_scale) ? x_scale : y_scale;
            }
        }
        else if (window->shrink) {
            scale = window->shrink_scale;
            window_w = (int) ceil(layout_w*scale);
            window_h = (int) ceil(layout_h*scale);
        }

        {
            char  temp[32];
            sprintf(temp,"SDL_VIDEO_WINDOW_POS=%d,%d",window_x,window_y);
            putenv(temp);
            putenv("SDL_VIDEO_WINDOW_FORCE_VISIBLE=1");
        }

        flags = SDL_SWSURFACE;
        if (fullscreen) {
            flags |= SDL_FULLSCREEN;
        }
        surface = SDL_SetVideoMode( window_w, window_h, 32, flags );
        if (surface == NULL) {
            fprintf(stderr, "### Error: could not create or resize SDL window: %s\n", SDL_GetError() );
            exit(1);
        }

        SDL_WM_SetPos( window_x, window_y );

        window->effective_scale = scale;
        window->effective_x     = 0;
        window->effective_y     = 0;

        if (fullscreen) {
            window->effective_x = (window_w - layout_w*scale)*0.5;
            window->effective_y = (window_h - layout_h*scale)*0.5;
        }

        if (scale == 1.0)
            window->surface = surface;
        else
        {
            window_w = (int) ceil(window_w / scale );
            window_h = (int) ceil(window_h / scale );

            window->shrink_surface = surface;
            window->shrink_pixels  = qemu_mallocz( window_w * window_h * 4 );
            if (window->shrink_pixels == NULL) {
                fprintf(stderr, "### Error: could not allocate memory for rescaling surface\n");
                exit(1);
            }
            window->surface = sdl_surface_from_argb32( window->shrink_pixels, window_w, window_h );
            if (window->surface == NULL) {
                fprintf(stderr, "### Error: could not create or resize SDL window: %s\n", SDL_GetError() );
                exit(1);
            }
            skin_scaler_set( window->scaler, scale, window->effective_x, window->effective_y );
        }
    }
}

static int
skin_window_reset_internal ( SkinWindow*  window, SkinLayout*  slayout )
{
    Layout         layout;
    ADisplay*      disp;

    if ( layout_init( &layout, slayout ) < 0 )
        return -1;

    disp = window->layout.displays;

    layout_done( &window->layout );
    window->layout = layout;

    disp = window->layout.displays;
    if (disp != NULL && window->onion)
        display_set_onion( disp,
                           window->onion,
                           window->onion_rotation,
                           window->onion_alpha );

    skin_window_resize(window);

    finger_state_reset( &window->finger );
    button_state_reset( &window->button );
    ball_state_reset( &window->ball, window );

    skin_window_redraw( window, NULL );

    if (slayout->event_type != 0) {
        kbd_generic_event( slayout->event_type, slayout->event_code, slayout->event_value );
        /* XXX: hack, replace by better code here */
        if (slayout->event_value != 0)
            android_sensors_set_coarse_orientation( ANDROID_COARSE_PORTRAIT );
        else
            android_sensors_set_coarse_orientation( ANDROID_COARSE_LANDSCAPE );
    }

    return 0;
}

int
skin_window_reset ( SkinWindow*  window, SkinLayout*  slayout )
{
    if (!window->fullscreen) {
        SDL_WM_GetPos(&window->x_pos, &window->y_pos);
    }
    return skin_window_reset_internal( window, slayout );
}

void
skin_window_set_lcd_brightness( SkinWindow*  window, int  brightness )
{
    ADisplay*  disp = window->layout.displays;

    if (disp != NULL) {
        disp->brightness = brightness;
        skin_window_redraw( window, NULL );
    }
}

void
skin_window_free  ( SkinWindow*  window )
{
    if (window) {
        if (window->surface) {
            SDL_FreeSurface(window->surface);
            window->surface = NULL;
        }
        if (window->shrink_surface) {
            SDL_FreeSurface(window->shrink_surface);
            window->shrink_surface = NULL;
        }
        if (window->shrink_pixels) {
            qemu_free(window->shrink_pixels);
            window->shrink_pixels = NULL;
        }
        if (window->onion) {
            skin_image_unref( &window->onion );
            window->onion_rotation = SKIN_ROTATION_0;
        }
        if (window->scaler) {
            skin_scaler_free(window->scaler);
            window->scaler = NULL;
        }
        layout_done( &window->layout );
        qemu_free(window);
    }
}

void
skin_window_set_onion( SkinWindow*   window,
                       SkinImage*    onion,
                       SkinRotation  onion_rotation,
                       int           onion_alpha )
{
    ADisplay*  disp;
    SkinImage*  old = window->onion;

    window->onion          = skin_image_ref(onion);
    window->onion_rotation = onion_rotation;
    window->onion_alpha    = onion_alpha;

    skin_image_unref( &old );

    disp = window->layout.displays;

    if (disp != NULL)
        display_set_onion( disp, window->onion, onion_rotation, onion_alpha );
}

static void
skin_window_update_shrink( SkinWindow*  window, SkinRect*  rect )
{
    skin_scaler_scale( window->scaler, window->shrink_surface, window->surface,
                       rect->pos.x, rect->pos.y, rect->size.w, rect->size.h );
}

void
skin_window_set_scale( SkinWindow*  window, double  scale )
{
    window->shrink       = (scale != 1.0);
    window->shrink_scale = scale;

    skin_window_resize( window );
    skin_window_redraw( window, NULL );
}

void
skin_window_redraw( SkinWindow*  window, SkinRect*  rect )
{
    if (window != NULL && window->surface != NULL) {
        Layout*  layout = &window->layout;

        if (rect == NULL)
            rect = &layout->rect;

        {
            SkinRect  r;

            if ( skin_rect_intersect( &r, rect, &layout->rect ) ) {
                SDL_Rect  rd;
                rd.x = r.pos.x;
                rd.y = r.pos.y;
                rd.w = r.size.w;
                rd.h = r.size.h;

                SDL_FillRect( window->surface, &rd, layout->color );
            }
        }

        {
            Background*  back = layout->backgrounds;
            Background*  end  = back + layout->num_backgrounds;
            for ( ; back < end; back++ )
                background_redraw( back, rect, window->surface );
        }

        {
            ADisplay*  disp = layout->displays;
            ADisplay*  end  = disp + layout->num_displays;
            for ( ; disp < end; disp++ )
                display_redraw( disp, rect, window->surface );
        }

        {
            Button*  button = layout->buttons;
            Button*  end    = button + layout->num_buttons;
            for ( ; button < end; button++ )
                button_redraw( button, rect, window->surface );
        }

        if ( window->ball.tracking )
            ball_state_redraw( &window->ball, rect, window->surface );

        if (window->effective_scale != 1.0)
            skin_window_update_shrink( window, rect );
        else
        {
            SDL_Rect  rd;
            rd.x = rect->pos.x;
            rd.y = rect->pos.y;
            rd.w = rect->size.w;
            rd.h = rect->size.h;

            SDL_UpdateRects( window->surface, 1, &rd );
        }
    }
}

void
skin_window_toggle_fullscreen( SkinWindow*  window )
{
    if (window && window->surface) {
        if (!window->fullscreen)
            SDL_WM_GetPos( &window->x_pos, &window->y_pos );

        window->fullscreen = !window->fullscreen;
        skin_window_resize( window );
        skin_window_redraw( window, NULL );
    }
}

void
skin_window_get_display( SkinWindow*  window, ADisplayInfo  *info )
{
    ADisplay*  disp = window->layout.displays;

    if (disp != NULL) {
        info->width    = disp->datasize.w;
        info->height   = disp->datasize.h;
        info->rotation = disp->rotation;
        info->data     = disp->data;
    } else {
        info->width    = 0;
        info->height   = 0;
        info->rotation = SKIN_ROTATION_0;
        info->data     = NULL;
    }
}


static void
skin_window_map_to_scale( SkinWindow*  window, int  *x, int  *y )
{
    *x = (*x - window->effective_x) / window->effective_scale;
    *y = (*y - window->effective_y) / window->effective_scale;
}

void
skin_window_process_event( SkinWindow*  window, SDL_Event*  ev )
{
    Button*  button;
    int      mx, my;

    if (!window->surface)
        return;

    switch (ev->type) {
    case SDL_MOUSEBUTTONDOWN:
        if ( window->ball.tracking ) {
            skin_window_trackball_press( window, 1 );
            break;
        }

        mx = ev->button.x;
        my = ev->button.y;
        skin_window_map_to_scale( window, &mx, &my );
        skin_window_move_mouse( window, mx, my );
        skin_window_find_finger( window, mx, my );
#if 0
        printf("down: x=%d y=%d fx=%d fy=%d fis=%d\n",
               ev->button.x, ev->button.y, window->finger.pos.x,
               window->finger.pos.y, window->finger.inside);
#endif
        if (window->finger.inside) {
            window->finger.tracking = 1;
            add_finger_event(window->finger.pos.x, window->finger.pos.y, 1);
        } else {
            window->button.pressed = NULL;
            button = window->button.hover;
            if(button) {
                button->down += 1;
                skin_window_redraw( window, &button->rect );
                window->button.pressed = button;
                if(button->keycode) {
                    send_key_event(button->keycode, 1);
                }
            }
        }
        break;

    case SDL_MOUSEBUTTONUP:
        if ( window->ball.tracking ) {
            skin_window_trackball_press( window, 0 );
            break;
        }
        button = window->button.pressed;
        mx = ev->button.x;
        my = ev->button.y;
        skin_window_map_to_scale( window, &mx, &my );
        if (button)
        {
            button->down = 0;
            skin_window_redraw( window, &button->rect );
            if(button->keycode) {
                send_key_event(button->keycode, 0);
            }
            window->button.pressed = NULL;
            window->button.hover   = NULL;
            skin_window_move_mouse( window, mx, my );
        }
        else if (window->finger.tracking)
        {
            skin_window_move_mouse( window, mx, my );
            window->finger.tracking = 0;
            add_finger_event( window->finger.pos.x, window->finger.pos.y, 0);
        }
        break;

    case SDL_MOUSEMOTION:
        if ( window->ball.tracking ) {
            skin_window_trackball_move( window, ev->motion.xrel, ev->motion.yrel );
            break;
        }
        mx = ev->button.x;
        my = ev->button.y;
        skin_window_map_to_scale( window, &mx, &my );
        if ( !window->button.pressed )
        {
            skin_window_move_mouse( window, mx, my );
            if ( window->finger.tracking ) {
                add_finger_event( window->finger.pos.x, window->finger.pos.y, 1 );
            }
        }
        break;
    }
}

static ADisplay*
skin_window_display( SkinWindow*  window )
{
    return window->layout.displays;
}

void
skin_window_update_display( SkinWindow*  window, int  x, int  y, int  w, int  h )
{
    ADisplay*  disp = skin_window_display(window);

    if ( !window->surface )
        return;

    if (disp != NULL) {
        SkinRect  r;
        r.pos.x  = x;
        r.pos.y  = y;
        r.size.w = w;
        r.size.h = h;

        skin_rect_rotate( &r, &r, disp->rotation );
        r.pos.x += disp->origin.x;
        r.pos.y += disp->origin.y;

        if (window->effective_scale != 1.0)
            skin_window_redraw( window, &r );
        else
            display_redraw( disp, &r, window->surface );
    }
}
