/* 
 *  call-seq: 
 *     get_at(x,y)
 *     get_at([x,y]) # deprecated
 *
 *  Return the color [r,g,b,a] of the pixel at the given coordinate. 
 *
 *  Raises IndexError if the coordinates are out of bounds.
 */
VALUE rbgm_surface_getat( int argc, VALUE *argv, VALUE self )
{
        SDL_Surface *surf;
        int x, y, locked;
        Uint32 color;
        Uint8 *pixels, *pix;
        Uint8 r,g,b,a;
        VALUE vx, vy;

        Data_Get_Struct(self, SDL_Surface, surf);

        rb_scan_args(argc, argv, "11", &vx, &vy);

        /* Still support passing position as an Array... for now. */
        switch( TYPE(vx) )
        {
                case T_ARRAY: {
                        x = NUM2INT( rb_ary_entry(vx,0) );
                        y = NUM2INT( rb_ary_entry(vx,1) );
                        break;
                }
                default: {
                        x = NUM2INT(vx);
                        y = NUM2INT(vy);
                        break;
                }
        }

        if( x < 0 || x > surf->w )
                rb_raise(rb_eIndexError,"x index out of bounds (%d, min 0, max %d)",\
                        x,surf->w);
        if( y < 0 || y > surf->h )
                rb_raise(rb_eIndexError,"y index out of bounds (%d, min 0, max %d)",\
                        y,surf->h);

        locked = 0;
        /* lock surface */
        if(SDL_MUSTLOCK(surf))
        {
                if(SDL_LockSurface(surf)==0)
                        locked += 1;
                else
                        rb_raise(eSDLError,"could not lock surface: %s",SDL_GetError());
        }

/* borrowed from pygame */
        pixels = (Uint8 *) surf->pixels;

        switch(surf->format->BytesPerPixel)
        {
                case 1:
                        color = (Uint32)*((Uint8 *)(pixels + y * surf->pitch) + x);
                        break;
                case 2:
                        color = (Uint32)*((Uint16 *)(pixels + y * surf->pitch) + x);
                        break;
                case 3:
                        pix = ((Uint8 *)(pixels + y * surf->pitch) + x * 3);
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
                        color = (pix[0]) + (pix[1]<<8) + (pix[2]<<16);
#else
                        color = (pix[2]) + (pix[1]<<8) + (pix[0]<<16);
#endif
                        break;
                default: /*case 4:*/
                        color = *((Uint32*)(pixels + y * surf->pitch) + x);
                        break;
        }

/* end borrowed from pygame */

        /* recursively unlock surface*/
        while(locked>1)
        {
                SDL_UnlockSurface(surf);
                locked -= 1;
        }

        SDL_GetRGBA(color, surf->format, &r, &g, &b, &a);
        return rb_ary_new3(4,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b),UINT2NUM(a));
}