/* 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/surface.h"
#include "android/skin/argb.h"
#include <SDL.h>

#define  DEBUG  1

#if DEBUG
#include "android/utils/debug.h"
#define  D(...)   VERBOSE_PRINT(surface,__VA_ARGS__)
#else
#define  D(...)   ((void)0)
#endif

struct SkinSurface {
    int                  refcount;
    uint32_t*            pixels;
    SDL_Surface*         surface;
    SkinSurfaceDoneFunc  done_func;
    void*                done_user;
};

static void
skin_surface_free( SkinSurface*  s )
{
    if (s->done_func) {
        s->done_func( s->done_user );
        s->done_func = NULL;
    }
    if (s->surface) {
        SDL_FreeSurface(s->surface);
        s->surface = NULL;
    }
    free(s);
}

extern SkinSurface*
skin_surface_ref( SkinSurface*  surface )
{
    if (surface)
        surface->refcount += 1;
    return surface;
}

extern void
skin_surface_unrefp( SkinSurface*  *psurface )
{
    SkinSurface*  surf = *psurface;
    if (surf) {
        if (--surf->refcount <= 0)
            skin_surface_free(surf);
        *psurface = NULL;
    }
}


void
skin_surface_set_done( SkinSurface*  s, SkinSurfaceDoneFunc  done_func, void*  done_user )
{
    s->done_func = done_func;
    s->done_user = done_user;
}

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#  define  ARGB32_R_MASK  0xff000000
#  define  ARGB32_G_MASK  0x00ff0000
#  define  ARGB32_B_MASK  0x0000ff00
#  define  ARGB32_A_MASK  0x000000ff
#else
#  define  ARGB32_R_MASK  0x000000ff
#  define  ARGB32_G_MASK  0x0000ff00
#  define  ARGB32_B_MASK  0x00ff0000
#  define  ARGB32_A_MASK  0xff000000
#endif

static SDL_Surface*
_sdl_surface_create_rgb( int  width,
                         int  height,
                         int  depth,
                         int  flags )
{
   Uint32   rmask, gmask, bmask, amask;

    if (depth == 8) {
        rmask = gmask = bmask = 0;
        amask = 0xff;
    } else if (depth == 32) {
        rmask = ARGB32_R_MASK;
        gmask = ARGB32_G_MASK;
        bmask = ARGB32_B_MASK;
        amask = ARGB32_A_MASK;
    } else
        return NULL;

    return SDL_CreateRGBSurface( flags, width, height, depth,
                                 rmask, gmask, bmask, amask );
}


static SDL_Surface*
_sdl_surface_create_rgb_from( int   width,
                              int   height,
                              int   pitch,
                              void* pixels,
                              int   depth )
{
   Uint32   rmask, gmask, bmask, amask;

    if (depth == 8) {
        rmask = gmask = bmask = 0;
        amask = 0xff;
    } else if (depth == 32) {
        rmask = ARGB32_R_MASK;
        gmask = ARGB32_G_MASK;
        bmask = ARGB32_B_MASK;
        amask = ARGB32_A_MASK;
    } else
        return NULL;

    return SDL_CreateRGBSurfaceFrom( pixels, width, height, pitch, depth,
                                     rmask, gmask, bmask, amask );
}


static SkinSurface*
_skin_surface_create( SDL_Surface*  surface,
                      void*         pixels )
{
    SkinSurface*  s = malloc(sizeof(*s));
    if (s != NULL) {
        s->refcount = 1;
        s->pixels   = pixels;
        s->surface  = surface;
        s->done_func = NULL;
        s->done_user = NULL;
    }
    else {
        SDL_FreeSurface(surface);
        free(pixels);
        D( "not enough memory to allocate new skin surface !" );
    }
    return  s;
}


SkinSurface*
skin_surface_create_fast( int  w, int  h )
{
    SDL_Surface*  surface;

    surface = _sdl_surface_create_rgb( w, h, 32, SDL_HWSURFACE );
    if (surface == NULL) {
        surface = _sdl_surface_create_rgb( w, h, 32, SDL_SWSURFACE );
        if (surface == NULL) {
            D( "could not create fast %dx%d ARGB32 surface: %s",
               w, h, SDL_GetError() );
            return NULL;
        }
    }
    return _skin_surface_create( surface, NULL );
}


SkinSurface*
skin_surface_create_slow( int  w, int  h )
{
    SDL_Surface*  surface;

    surface = _sdl_surface_create_rgb( w, h, 32, SDL_SWSURFACE );
    if (surface == NULL) {
        D( "could not create slow %dx%d ARGB32 surface: %s",
            w, h, SDL_GetError() );
        return NULL;
    }
    return _skin_surface_create( surface, NULL );
}


SkinSurface*
skin_surface_create_argb32_from(
                        int                  w,
                        int                  h,
                        int                  pitch,
                        uint32_t*            pixels,
                        int                  do_copy )
{
    SDL_Surface*  surface;
    uint32_t*     pixcopy = NULL;

    if (do_copy) {
        size_t  size = h*pitch;
        pixcopy = malloc( size );
        if (pixcopy == NULL && size > 0) {
            D( "not enough memory to create %dx%d ARGB32 surface",
               w, h );
            return NULL;
        }
        memcpy( pixcopy, pixels, size );
    }

    surface = _sdl_surface_create_rgb_from( w, h, pitch,
                                            pixcopy ? pixcopy : pixels,
                                            32 );
    if (surface == NULL) {
        D( "could not create %dx%d slow ARGB32 surface: %s",
            w, h, SDL_GetError() );
        return NULL;
    }
    return _skin_surface_create( surface, pixcopy );
}




extern int
skin_surface_lock( SkinSurface*  s, SkinSurfacePixels  *pix )
{
    if (!s || !s->surface) {
        D( "error: trying to lock stale surface %p", s );
        return -1;
    }
    if ( SDL_LockSurface( s->surface ) != 0 ) {
        D( "could not lock surface %p: %s", s, SDL_GetError() );
        return -1;
    }
    pix->w      = s->surface->w;
    pix->h      = s->surface->h;
    pix->pitch  = s->surface->pitch;
    pix->pixels = s->surface->pixels;
    return 0;
}

/* unlock a slow surface that was previously locked */
extern void
skin_surface_unlock( SkinSurface*  s )
{
    if (s && s->surface)
        SDL_UnlockSurface( s->surface );
}


#if 0
static uint32_t
skin_surface_map_argb( SkinSurface*  s, uint32_t  c )
{
    if (s && s->surface) {
        return SDL_MapRGBA( s->surface->format,
                            ((c) >> 16) & 255,
                            ((c) >> 8) & 255,
                            ((c) & 255),
                            ((c) >> 24) & 255 );
    }
    return 0x00000000;
}
#endif

typedef struct {
    int   x;
    int   y;
    int   w;
    int   h;
    int   sx;
    int   sy;

    uint8_t*      dst_line;
    int           dst_pitch;
    SDL_Surface*  dst_lock;

    uint8_t*      src_line;
    int           src_pitch;
    SDL_Surface*  src_lock;
    uint32_t      src_color;

} SkinBlit;


static int
skin_blit_init_fill( SkinBlit*     blit,
                     SkinSurface*  dst,
                     SkinRect*     dst_rect,
                     uint32_t      color )
{
    int  x = dst_rect->pos.x;
    int  y = dst_rect->pos.y;
    int  w = dst_rect->size.w;
    int  h = dst_rect->size.h;
    int  delta;

    if (x < 0) {
        w += x;
        x  = 0;
    }
    delta = (x + w) - dst->surface->w;
    if (delta > 0)
        w -= delta;

    if (y < 0) {
        h += y;
        y  = 0;
    }
    delta = (y + h) - dst->surface->h;
    if (delta > 0)
        h -= delta;

    if (w <= 0 || h <= 0)
        return 0;

    blit->x = x;
    blit->y = y;
    blit->w = w;
    blit->h = h;

    if ( !SDL_LockSurface(dst->surface) )
        return 0;

    blit->dst_lock  = dst->surface;
    blit->dst_pitch = dst->surface->pitch;
    blit->dst_line  = dst->surface->pixels + y*blit->dst_pitch;

    blit->src_lock  = NULL;
    blit->src_color = color;

    return 1;
}

static int
skin_blit_init_blit( SkinBlit*     blit,
                     SkinSurface*  dst,
                     SkinPos*      dst_pos,
                     SkinSurface*  src,
                     SkinRect*     src_rect )
{
    int  x  = dst_pos->x;
    int  y  = dst_pos->y;
    int  sx = src_rect->pos.x;
    int  sy = src_rect->pos.y;
    int  w  = src_rect->size.w;
    int  h  = src_rect->size.h;
    int  delta;

    if (x < 0) {
        w  += x;
        sx -= x;
        x   = 0;
    }
    if (sx < 0) {
        w  += sx;
        x  -= sx;
        sx  = 0;
    }

    delta = (x + w) - dst->surface->w;
    if (delta > 0)
        w -= delta;

    delta = (sx + w) - src->surface->w;
    if (delta > 0)
        w -= delta;

    if (y < 0) {
        h  += y;
        sy += y;
        y   = 0;
    }
    if (sy < 0) {
        h  += sy;
        y  -= sy;
        sy  = 0;
    }
    delta = (y + h) - dst->surface->h;
    if (delta > 0)
        h -= delta;

    delta = (sy + h) - src->surface->h;

    if (w <= 0 || h <= 0)
        return 0;

    blit->x = x;
    blit->y = y;
    blit->w = w;
    blit->h = h;

    blit->sx = sx;
    blit->sy = sy;

    if ( !SDL_LockSurface(dst->surface) )
        return 0;

    blit->dst_lock  = dst->surface;
    blit->dst_pitch = dst->surface->pitch;
    blit->dst_line  = (uint8_t*) dst->surface->pixels + y*blit->dst_pitch;

    if ( !SDL_LockSurface(src->surface) ) {
        SDL_UnlockSurface(dst->surface);
        return 0;
    }

    blit->src_lock  = src->surface;
    blit->src_pitch = src->surface->pitch;
    blit->src_line  = (uint8_t*) src->surface->pixels + sy*blit->src_pitch;

    return 1;
}

static void
skin_blit_done( SkinBlit*  blit )
{
    if (blit->src_lock)
        SDL_UnlockSurface( blit->src_lock );
    if (blit->dst_lock)
        SDL_UnlockSurface( blit->dst_lock );
    ARGB_DONE;
}

typedef void (*SkinLineFillFunc)( uint32_t*  dst, uint32_t  color, int  len );
typedef void (*SkinLineBlitFunc)( uint32_t*  dst, const uint32_t*  src,  int  len );

static void
skin_line_fill_copy( uint32_t*  dst, uint32_t  color, int  len )
{
    uint32_t*  end = dst + len;

    while (dst + 4 <= end) {
        dst[0] = dst[1] = dst[2] = dst[3] = color;
        dst   += 4;
    }
    while (dst < end) {
        dst[0] = color;
        dst   += 1;
    }
}

static void
skin_line_fill_srcover( uint32_t*  dst, uint32_t  color, int  len )
{
    uint32_t*  end = dst + len;
    uint32_t   alpha = (color >> 24);

    if (alpha == 255)
    {
        skin_line_fill_copy(dst, color, len);
    }
    else
    {
        ARGB_DECL(src_c);
        ARGB_DECL_ZERO();

        alpha  = 255 - alpha;
        alpha += (alpha >> 7);

        ARGB_UNPACK(src_c,color);

        for ( ; dst < end; dst++ )
        {
            ARGB_DECL(dst_c);

            ARGB_READ(dst_c,dst);
            ARGB_MULSHIFT(dst_c,dst_c,alpha,8);
            ARGB_ADD(dst_c,src_c);
            ARGB_WRITE(dst_c,dst);
        }
    }
}

static void
skin_line_fill_dstover( uint32_t*  dst, uint32_t  color, int  len )
{
    uint32_t*  end = dst + len;
    ARGB_DECL(src_c);
    ARGB_DECL_ZERO();

    ARGB_UNPACK(src_c,color);

    for ( ; dst < end; dst++ )
    {
        ARGB_DECL(dst_c);
        ARGB_DECL(val);

        uint32_t   alpha;

        ARGB_READ(dst_c,dst);
        alpha = 256 - (dst[0] >> 24);
        ARGB_MULSHIFT(val,src_c,alpha,8);
        ARGB_ADD(val,dst_c);
        ARGB_WRITE(val,dst);
    }
}

extern void
skin_surface_fill( SkinSurface*  dst,
                   SkinRect*     rect,
                   uint32_t      argb_premul,
                   SkinBlitOp    blitop )
{
    SkinLineFillFunc  fill;
    SkinBlit          blit[1];

    switch (blitop) {
        case SKIN_BLIT_COPY:    fill = skin_line_fill_copy; break;
        case SKIN_BLIT_SRCOVER: fill = skin_line_fill_srcover; break;
        case SKIN_BLIT_DSTOVER: fill = skin_line_fill_dstover; break;
        default: return;
    }

    if ( skin_blit_init_fill( blit, dst, rect, argb_premul ) ) {
        uint8_t*   line  = blit->dst_line;
        int        pitch = blit->dst_pitch;
        uint8_t*   end   = line + pitch*blit->h;

        for ( ; line != end; line += pitch )
            fill( (uint32_t*)line + blit->x, argb_premul, blit->w );
    }
}


static void
skin_line_blit_copy( uint32_t*  dst, const uint32_t*  src, int  len )
{
    memcpy( (char*)dst, (const char*)src, len*4 );
}



static void
skin_line_blit_srcover( uint32_t*  dst, const uint32_t*  src, int  len )
{
    uint32_t*  end = dst + len;
    ARGB_DECL_ZERO();

    for ( ; dst < end; dst++ ) {
        ARGB_DECL(d);
        ARGB_DECL(v);
        uint32_t  alpha;

        alpha = (src[0] >> 24);
        if (alpha > 0) {
            ARGB_READ(d,dst);
            alpha = 256 - alpha;
            ARGB_MULSHIFT(v,d,alpha,8);
            ARGB_ADD(v,d);
            ARGB_WRITE(v,dst);
        }
    }
}

static void
skin_line_blit_dstover( uint32_t*  dst, const uint32_t*  src, int  len )
{
    uint32_t*  end = dst + len;
    ARGB_DECL_ZERO();

    for ( ; dst < end; dst++ ) {
        ARGB_DECL(s);
        ARGB_DECL(v);
        uint32_t  alpha;

        alpha = (dst[0] >> 24);
        if (alpha < 255) {
            ARGB_READ(s,src);
            alpha = 256 - alpha;
            ARGB_MULSHIFT(v,s,alpha,8);
            ARGB_ADD(v,s);
            ARGB_WRITE(v,dst);
        }
    }
}


extern void
skin_surface_blit( SkinSurface*  dst,
                   SkinPos*      dst_pos,
                   SkinSurface*  src,
                   SkinRect*     src_rect,
                   SkinBlitOp    blitop )
{
    SkinLineBlitFunc  func;
    SkinBlit          blit[1];

    switch (blitop) {
        case SKIN_BLIT_COPY:    func = skin_line_blit_copy; break;
        case SKIN_BLIT_SRCOVER: func = skin_line_blit_srcover; break;
        case SKIN_BLIT_DSTOVER: func = skin_line_blit_dstover; break;
        default: return;
    }

    if ( skin_blit_init_blit( blit, dst, dst_pos, src, src_rect ) ) {
        uint8_t*   line   = blit->dst_line;
        uint8_t*   sline  = blit->src_line;
        int        pitch  = blit->dst_pitch;
        int        spitch = blit->src_pitch;
        uint8_t*   end    = line + pitch*blit->h;

        for ( ; line != end; line += pitch, sline += spitch )
            func( (uint32_t*)line + blit->x, (uint32_t*)sline + blit->sx, blit->w );

        skin_blit_done(blit);
    }
}
