//-----------------------------------------------------------------------------
// Project            	RenderKit
// Class		G3DSDLCamera
// Creator            	Philippe C.D. Robert
// Maintainer         	Philippe C.D. Robert
// Creation Date      	Sun Jul 16 23:23:46 CEST 2000
//
// Copyright (c) Philippe C.D. Robert
//
// The RenderKit is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the Free 
// Software Foundation
//
// $Id: G3DSDLCamera.m,v 1.35 2001/07/15 13:56:15 probert Exp $
//-----------------------------------------------------------------------------

#import "G3DSDLCamera.h"
#import "G3DSDLEventHandler.h"

#import <RenderKit/RenderKit.h>

#ifdef XMESA
#include "GL/xmesa.h"
#endif

#define FRAME 25

/*
 * The camera
 *
 */

static int sc_bpp;
static BOOL isFullScreen;
static id _cam_obj = NULL;
static unsigned videoFlags;

SDL_Surface *sdl_screen;

NSString *G3DSDLCameraException = @"G3DSDLCameraException";

@implementation G3DSDLCamera

//-----------------------------------------------------------------------------
// Class methods
//-----------------------------------------------------------------------------

+ (void)initialize
{
  static BOOL tooLate = NO;

  [super initialize];

  if (!tooLate) {
    tooLate = YES;
  }
}

//-----------------------------------------------------------------------------
// Init methods
//-----------------------------------------------------------------------------

- (id)initWithSize:(NSSize)aSize
{
  return [self initWithSize:aSize depth:16 fullscreen:NO];
}

- (id)initWithSize:(NSSize)aSize depth:(int)bpp fullscreen:(BOOL)yn
{
  return [self initWithSize:aSize
	       depth:bpp
	       fullscreen:yn 
	       visualInfo:NULL];
}

- (id)initWithSize:(NSSize)aSize depth:(int)bpp fullscreen:(BOOL)yn visualInfo:(G3DVisualInfo*)visual
{
  if ((self = [super initWithSize:aSize])) {
    sc_bpp = bpp;
    isFullScreen = yn;

    if (visual) {
      _colInfo = *visual;
    }
    else {
      _colInfo.red = 5;
      _colInfo.green = 5;
      _colInfo.blue = 5;
      _colInfo.alpha = 5;
      _colInfo.doubleBuffered = 1;
      _colInfo.depthSize = 16;
      _colInfo.stencilSize = 8;
    }

    _cam_obj = self;
  }

  return self;
}

- (void)dealloc
{
  // Only one cam at the time allowed for now...
  SDL_Quit();

  [super dealloc];
}

//-----------------------------------------------------------------------------
// Rendering methods
//-----------------------------------------------------------------------------

- (void)setupCamera
{
#ifdef DEBUG
  GLenum err;
  const GLubyte *str;
#endif DEBUG  
  NSString *proc = [[[NSProcessInfo processInfo] arguments] objectAtIndex:0];

  // Setup SDL...
  if( SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0 ) {
    [NSException raise:G3DSDLCameraException format:@"Could not initialise the SDL camera: %s",SDL_GetError()];
    return;
  }
  
  videoFlags = SDL_OPENGL;
  if (isFullScreen) videoFlags |= SDL_FULLSCREEN;
  
  /* Initialize the display - should be more configurable */
  SDL_GL_SetAttribute( SDL_GL_RED_SIZE, _colInfo.red);
  SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, _colInfo.green);
  SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, _colInfo.blue);
  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, _colInfo.depthSize);
  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, _colInfo.stencilSize);
  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, _colInfo.doubleBuffered);
  
  sdl_screen=SDL_SetVideoMode(_size.width, _size.height, sc_bpp, videoFlags);
  if (sdl_screen == NULL) {
    SDL_Quit();
    [NSException raise:G3DSDLCameraException format:@"Could not set the GL mode: %s",SDL_GetError()];
    return;
  }
  
  // Some other things
  glClearColor([backgroundColour red],[backgroundColour green],[backgroundColour blue],[backgroundColour alpha]);
  
  if (cameraFlags.isFullscreen) {
#ifdef XMESA
    XMesaSetFXmode(XMESA_FX_FULLSCREEN);
#endif XMESA
  }

  [self setViewportWithSize:_size];

  // Z Buffering
  if (cameraFlags.doDepthTest) {
    glEnable(GL_DEPTH_TEST);
  }

  // Everything is OK now
  cameraFlags.canRender = YES;

  [[G3DRenderEngine renderEngine] initEngine];

#ifdef DEBUG
  if ((err = glGetError())!=GL_NO_ERROR) {
    str = gluErrorString(err);
    NSLog([NSString stringWithFormat:@"GL error while initialising: %s\n",str]);
  }
#endif DEBUG

  // Notify the renderDelegate
  if (renderDelegate && [renderDelegate respondsToSelector:@selector(cameraDidInitialise:)]) {
    [renderDelegate cameraDidInitialise:self];
  }
}

- (void)render
{
  [super render];

  SDL_GL_SwapBuffers();  
}

//-----------------------------------------------------------------------------
// callbacks
//-----------------------------------------------------------------------------

- (void)toggleFullscreen
{
  const SDL_VideoInfo *info;
  SDL_Rect **modes;
  
  info = SDL_GetVideoInfo();

  modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
  if ( modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1) {
    return;
  }

  _size.width = modes[0]->w;
  _size.height = modes[0]->h;
  sc_bpp=info->vfmt->BitsPerPixel;

  isFullScreen = isFullScreen ? NO : YES;

  videoFlags = SDL_OPENGL;
  if (isFullScreen) {
    videoFlags |= SDL_FULLSCREEN;
  }

  sdl_screen=SDL_SetVideoMode(_size.width, _size.height, sc_bpp, videoFlags);
  if (sdl_screen == NULL) {
    [NSException raise:G3DSDLCameraException format:@"Could not set the GL mode: %s",SDL_GetError()];
    SDL_Quit();
    return;
  }

  [self setViewportWithSize:_size];
}

@end



