/* 
 *  call-seq: 
 *     get_at(pos)
 *     get_at(x,y)
 *
 *  Return the color [r,g,b,a] of the pixel at the given coordinate. 
 *
 *  This method takes these argument:
 *  - pos:: the coordinate of the pixel to get the color of.
 *
 *  The coordinate can also be given as two arguments, separate +x+ and +y+
 *  positions.
 */
VALUE rbgm_surface_getat( int argc, VALUE *argv, VALUE self )
{
        SDL_Surface *surf;
        int x,y;
        int locked=0;
        Uint32 color;
        Uint8 *pixels, *pix;
        Uint8 r,g,b,a;

        Data_Get_Struct(self, SDL_Surface, surf);

        if(argc>2)
                rb_raise(rb_eArgError,"wrong number of arguments (%d for 1)",argc);

        if(argc==1)
        {
                x = NUM2INT(rb_ary_entry(argv[0],0));
                y = NUM2INT(rb_ary_entry(argv[0],1));
        }
        else
        {
                x = NUM2INT(argv[0]);
                y = NUM2INT(argv[1]);
        }

        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);

        /* 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;
        }

        if((int *)color == NULL)
        {
                VALUE zero = INT2NUM(0);
                return rb_ary_new3(4,zero,zero,zero,zero);
        }

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