#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dpl.h>

int x_size=832,
    y_size=512;

#define dpl_arg_sep '~'

float near_clip=4.0f, far_clip=2000.0f;

/*{{{  static char *find_dpl_arg ( char *dpl_arg, char *find_arg )*/
static char *find_dpl_arg ( char *dpl_arg, char *find_arg )
{
  char *check=dpl_arg, *ret=NULL;
  int len=strlen(find_arg);

  while (*check) {
    /* printf ("checking %s with %s, %d chars\n", find_arg, check, len ); */
    if (strncmp (check, find_arg, len) == 0) {
      /* found it ? */
      /* printf ("preliminary match, on %s\n", check ); */
      while ((*check) != dpl_arg_sep) {
        if ((*check) == 0x0) return NULL;
        /* printf ("skipping %c\n", *check ); */
        check++;
      }
      check++;
      if ((*check) == 0x0) return NULL;
      else {
        /* printf ("match, returning %s!\n", check ); */
        return check;
		}
    }
    else check++;
  }
  return NULL;
}
/*}}}  */

/*{{{  int screen_resolution ( dpl_argv )*/
int screen_resolution ( char *dpl_argv )
{
  char *video=find_dpl_arg ( dpl_argv, "video" );

  if (video == NULL) return 0;

  if (strncmp ( video, "ntsc", 4 ) == 0) {
    x_size=704;
    y_size=480;
    return 1;
  }

  if (strncmp ( video, "ntsc_rgb", 4 ) == 0) {
    x_size=704;
    y_size=480;
    return 1;
  }

  if (strncmp ( video, "vga", 3 ) == 0) {
    x_size=640;
    y_size=480;
    return 1;
  }

  if (strncmp ( video, "pal", 3 ) == 0) {
    x_size=832;
    y_size=512;
    return 1;
  }

  if (strncmp ( video, "pal_rgb", 7 ) == 0) {
    x_size=832;
    y_size=512;
    return 1;
  }

  if (strncmp ( video, "hires", 5 ) == 0) {
    x_size=1024;
    y_size=768;
    return 1;
  }

  if (strncmp ( video, "svga", 4 ) == 0) {
    x_size=832;
    y_size=512;
    return 1;
  }

  if (strncmp ( video, "nucolor", 7 ) == 0) {
    x_size=640;
    y_size=480;
    return 1;
  }

  if (strncmp ( video, "kaiser", 6 ) == 0) {
    x_size=832;
    y_size=256;
    return 1;
  }

  else {
    printf ("Unknown video format %s\n", video );
    x_size=640;
    y_size=480;
    return 0;

  }
}
/*}}}  */

/*{{{  dpl_ZONE *initialize_eyes ( char *dpl_args, int stereo,*/
dpl_ZONE *initialize_eyes ( int stereo,
                            dpl_VIEW **lye,
                            dpl_VIEW **rye,
                            float fog_near )
{
  dpl_DCS *d;
  dpl_ZONE *z;
  dpl_VIEW *eye;
  float fog_far;

  if (fog_near > far_clip)
    fog_far=fog_near+256;
  else
    fog_far=far_clip;


  printf ("initialize eyes\n" );

  z=dpl_NewZone();

  printf ("create 1st view\n" );

  *lye = dpl_NewView();

  if ((*lye) == NULL) {
    printf ("NULL eye\n" );
    return NULL;
  }

  eye=*lye;

  d=dpl_NewDCS();
  dpl_SetViewDCS(eye, d);

  dpl_SetZoneAllViewsOn ( z );
//  dpl_AddZoneToScene ( z );
  dpl_SetViewClipPlanes ( eye, near_clip, far_clip );
  dpl_SetViewBackGround ( eye, 0.4f, 0.6f, 0.9f );
  dpl_SetViewFog        ( eye, 0, 0.5f, 0.5f, 0.6f, fog_near, fog_far );
  dpl_SetViewPort       ( eye, 0, 0, x_size-1, y_size-1 );
  dpl_SetViewProjection ( eye,
                          -1.0f, -1.0f, 1.0f, 1.0f,
								  1.3f );
  dpl_AddViewToScene ( eye );

  dpl_FlushDCS(d);
  dpl_FlushView(eye);
  dpl_FlushZone(z);

  if (stereo == 0) {
    *rye=NULL;
  }
  else {
	 printf ("create 2nd view\n" );
    *rye = dpl_NewView();
    if ((*rye) == NULL) {
      printf ("NULL rye\n" );
		return NULL;
    }

    eye=*rye;

    d=dpl_NewDCS();
    dpl_SetViewDCS(eye, d);

    dpl_SetViewClipPlanes ( eye, near_clip, far_clip );
    dpl_SetViewBackGround ( eye, 0.4f, 0.6f, 0.9f );
    dpl_SetViewFog        ( eye, 0, 0.5f, 0.5f, 0.6f, fog_near, fog_far );
    dpl_SetViewPort       ( eye, 0, 0, x_size-1, y_size-1 );
    dpl_SetViewProjection ( eye,
                            -1.0f, -1.0f, 1.0f, 1.0f,
                            1.3f );
    dpl_AddViewToScene ( eye );

    dpl_FlushDCS(d);
    dpl_FlushView(eye);
  }
  return z;
}
/*}}}  */

/*{{{  static char *explode_an_arg( char *dpl_args, char **where, char sep )*/
static char *explode_an_arg( char *dpl_args, char **where, char sep )
{
  int explode=1, good_chars=0;
  char *arg0=dpl_args;


  while (explode) {
    if (*dpl_args == sep) {
      /*{{{  a separator*/
      /* end of a string */
      if (good_chars) {
        *where=malloc(good_chars+1);
        memcpy ( *where, arg0, good_chars );
        (*where)[good_chars]=0x0;
        dpl_args++;
      }
      else {
        *where=malloc(1);
        (*where)[0]=0x0;
        dpl_args++;
      }
      /*}}}  */
      explode=0;
    }
    else if (*dpl_args) {
      good_chars++;
      dpl_args++;
    }
    else {
      /*{{{  end of whole dpl_args string*/
      if (good_chars) {
        *where=malloc(good_chars+1);
        memcpy ( *where, arg0, good_chars );
        (*where)[good_chars]=0x0;
        explode=0;  /* ensure we return pointer to (char) 0x0 */
      }
      else return NULL;
      /*}}}  */
    }
  }
  return dpl_args;
}
/*}}}  */
/*{{{  static int explode_args ( char **argv, char *dpl_args, char dpl_arg_sep )*/
int explode_args ( char **argv, char *dpl_args, char sep )
{
  int argc=0;

  while (*dpl_args) {
    dpl_args=explode_an_arg(dpl_args, &argv[argc], sep);
    if (dpl_args)
      argc++;
    else
      return argc;
  }
  return argc;
}
/*}}}  */

/*{{{  dpl_ZONE *initialize_all ( char *dpl_args,*/
dpl_ZONE *initialize_all ( char *dpl_args,
									int stereo,
                           dpl_VIEW **lye,
                           dpl_VIEW **rye,
                           float fog_near )
{
  dpl_ZONE *z;
  char *argv[32];
  int argc=0;

  argc = explode_args ( argv, dpl_args, dpl_arg_sep );

  dpl_Init ( argc, argv );

  z = initialize_eyes ( stereo, lye, rye, fog_near );

  return z;
}
/*}}}  */

