/* call-seq:
 *     new(size, depth=0, flags=[SWSURFACE])  ->  Screen
 *     (aliases: set_mode, instance)
 *
 *  Create a new Rubygame window if there is none, or modify the existing one.
 *  You cannot create more than one Screen; the existing one will be replaced.
 *  (This is a limitation of SDL.)
 *  Returns the resulting Screen.
 *
 *  This method takes these arguments:
 *  size::  requested window size (in pixels), in the form [width,height]
 *  depth:: requested color depth (in bits per pixel). If 0 (default), the
 *          current system color depth.
 *  flags:: an Array of zero or more of the following flags (located under the
 *          Rubygame module).
 *          
 *          SWSURFACE::  Create the video surface in system memory.
 *          HWSURFACE::  Create the video surface in video memory.
 *          ASYNCBLIT::  Enables the use of asynchronous updates of the 
 *                       display surface. This will usually slow down 
 *                       blitting on single CPU machines, but may provide a
 *                       speed increase on SMP systems.
 *          ANYFORMAT::  Normally, if a video surface of the requested 
 *                       bits-per-pixel (bpp) is not available, Rubygame
 *                       will emulate one with a shadow surface. Passing 
 *                       +ANYFORMAT+ prevents this and causes Rubygame to
 *                       use the video surface regardless of its depth.
 *          DOUBLEBUF::  Enable hardware double buffering; only valid with 
 *                       +HWSURFACE+. Calling #flip will flip the
 *                       buffers and update the screen. All drawing will
 *                       take place on the surface that is not displayed at
 *                       the moment. If double buffering could not be 
 *                       enabled then #flip will just update the
 *                       entire screen.
 *          FULLSCREEN:: Rubygame will attempt to use a fullscreen mode. If
 *                       a hardware resolution change is not possible (for 
 *                       whatever reason), the next higher resolution will
 *                       be used and the display window centered on a black
 *                       background.
 *          OPENGL::     Create an OpenGL rendering context. You must set
 *                       proper OpenGL video attributes with GL#set_attrib
 *                       before calling this method with this flag. You can
 *                       then use separate opengl libraries (for example rbogl)
 *                       to do all OpenGL-related functions.
 *                       Please note that you can't blit or draw regular SDL
 *                       Surfaces onto an OpenGL-mode screen; you must use
 *                       OpenGL functions.
 *          RESIZABLE::  Create a resizable window. When the window is 
 *                       resized by the user, a ResizeEvent is
 *                       generated and #set_mode can be called again
 *                       with the new size.
 *          NOFRAME::    If possible, create a window with no title bar or
 *                       frame decoration.
 *                       Fullscreen modes automatically have this flag set.
 */
VALUE rbgm_screen_setmode(int argc, VALUE *argv, VALUE module)
{
  SDL_Surface *screen;
  int w, h, depth, i;
  Uint32 flags;

  w = h = depth = flags = 0;

  if(argc < 1 || argc > 3)
        rb_raise(rb_eArgError,"Wrong number of args to set mode(%d for 1)",argc);

  if(argc >= 1)
        {
          w = NUM2INT(rb_ary_entry(argv[0],0));
          h = NUM2INT(rb_ary_entry(argv[0],1));
        }

  if(argc >= 2 && argv[1] != Qnil)
        depth = NUM2INT(argv[1]);

  if(argc >= 3 && argv[2] != Qnil)
        {
    switch( TYPE(argv[2]) ){
    case T_ARRAY:;
      for(i=0;  i < RARRAY(argv[2])->len;  i++)
        {
          flags |= NUM2UINT(  rb_ary_entry( argv[2],i )  );
        }
      break;
    case T_FIXNUM:;
      flags = NUM2UINT( argv[2] );
      break;
    default:;
      rb_raise(rb_eArgError,"Wrong type for argument `flags' (wanted Fixnum or Array).");
    }
        }

  screen = SDL_SetVideoMode( w,h,depth,flags );

  if( screen==NULL )
        {
          rb_raise(eSDLError,"Couldn't set [%d x %d] %d bpp video mode: %s",
                           w, h, depth, SDL_GetError());
        }
  //format = screen->format;
  //printf("New screen will be: %dx%d, %d bpp. Masks: %d, %d, %d, %d\n",w,h,depth,format->Rmask,format->Gmask,format->Bmask,format->Amask);
  return Data_Wrap_Struct( cScreen,0,0,screen ); 
}