/*
 *  call-seq:
 *    rotozoom( angle, zoom, smooth=false )  ->  Surface
 *
 *  Return a rotated and/or zoomed version of the given surface. Note that
 *  rotating a Surface anything other than a multiple of 90 degrees will 
 *  cause the new surface to be larger than the original to accomodate the
 *  corners (which would otherwise extend beyond the surface).
 *
 *  If Rubygame was compiled with SDL_gfx-2.0.13 or greater, +zoom+ can be
 *  an Array of 2 Numerics for separate X and Y scaling. Also, it can be
 *  negative to indicate flipping horizontally or vertically.
 *
 *  Will raise SDLError if you attempt to use separate X and Y zoom factors
 *  or negative zoom factors with an unsupported version of SDL_gfx.
 *
 *  This method takes these arguments:
 *  angle::   degrees to rotate counter-clockwise (negative for clockwise).
 *  zoom::    scaling factor(s). A single positive Numeric, unless you have
 *            SDL_gfx-2.0.13 or greater (see above).
 *  smooth::  whether to anti-alias the new surface.
 *            By the way, if true, the new surface will be 32bit RGBA.
 */
VALUE rbgm_transform_rotozoom(int argc, VALUE *argv, VALUE self)
{
  SDL_Surface *src, *dst;
  double angle, zoomx, zoomy;
  int smooth = 0;

  if(argc < 2)             /* smooth is optional, so only 2 required*/
    rb_raise(rb_eArgError,"wrong number of arguments (%d for 2)",argc);

  /* argv[0], the source surface. */
  Data_Get_Struct(self,SDL_Surface,src);

  /* argv[1], the angle of rotation. */
  angle = NUM2DBL(argv[0]);

  /* Parsing of argv[2] is delayed until below, because its type
     affects which function we call. */

  /* argv[3] (optional), rotozoom smoothly? */
  if(argc > 2)
    smooth = argv[2];

  /* argv[1], the zoom factor(s) */
  if(TYPE(argv[1])==T_ARRAY)            /* if we got separate X and Y factors */
  {

#ifdef HAVE_ROTOZOOMXY
    /* Do the real function. */
    zoomx = NUM2DBL(rb_ary_entry(argv[1],0));
    zoomy = NUM2DBL(rb_ary_entry(argv[1],1));
    dst = rotozoomSurfaceXY(src, angle, zoomx, zoomy, smooth);
    if(dst == NULL)
      rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());
#else
    /* Raise SDLError. You should have checked first! */
    rb_raise(eSDLError,"Separate X/Y rotozoom scale factors is not supported by your version of SDL_gfx (%d,%d,%d). Please upgrade to 2.0.13 or later.", SDL_GFXPRIMITIVES_MAJOR, SDL_GFXPRIMITIVES_MINOR, SDL_GFXPRIMITIVES_MICRO);
    return Qnil;
#endif

  }
  /* If we got 1 zoom factor for both X and Y */
  else if(FIXNUM_P(argv[1]) || TYPE(argv[1])==T_FLOAT)
  {
    zoomx = NUM2DBL(argv[1]);
#ifndef HAVE_ROTOZOOMXY
    if(zoomx < 0)                                                               /* negative zoom (for flipping) */
    {
      /* Raise SDLError. You should have checked first! */
      rb_raise(eSDLError,"Negative rotozoom scale factor is not supported by your version of SDL_gfx (%d,%d,%d). Please upgrade to 2.0.13 or later.", SDL_GFXPRIMITIVES_MAJOR, SDL_GFXPRIMITIVES_MINOR, SDL_GFXPRIMITIVES_MICRO);
    }
#endif
    dst = rotozoomSurface(src, angle, zoomx, smooth);
    if(dst == NULL)
      rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());
  }
  else
    rb_raise(rb_eArgError,"wrong zoom factor type (expected Array or Numeric)");

  return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,dst);
}