/*
 * Stonage: a puzzle game
 * Copyright (C) 2001 Luc Saillard <luc@saillard.org>
 *
 * Main routine to start program
 * 
 * This program 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; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

#include "stonage.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>

#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>

#include "game.h"
#include "music.h"
#include "level_code.h"
#include "intro.h"
#include "screen.h"

#define XSIZE 640
#define YSIZE 480


static void Init(int argc, char **argv);
static void usage (const char *programname);
static void random_init(void);

SDL_Surface *screen;
static int nosound=0;

int main(int argc, char **argv)
{
  Init(argc,argv);
  Game_Menu_Loop();
  Game_Quit();
  return 0;
}


static void
Init(int argc, char **argv)
{
  int videoflags, video_bpp;
  int opt, skip_introduction;

#ifdef HAVE_GETOPT_LONG
  static struct option long_options[] =
   {
      {"bpp", 		1, 0, 'b'},
      {"warp", 		0, 0, 'w'},
      {"hardware", 	0, 0, 'H'},
      {"fullscreen", 	0, 0, 'f'},
      {"no-sound", 	0, 0, 's'},
      {"level", 	1, 0, 'l'},
      {"difficulty", 	1, 0, 'd'},
      {"version", 	0, 0, 'v'},
      {"skipintro", 	0, 0, 'i'},
      {"no-animation", 	0, 0, 'a'},
      {"help", 		0, 0, 'h'},
      {0, 0, 0, 0}
   };
  int option_index = 0;
#endif

  /* Initialise global game variables */
  game.level=1;
  game.difficulty=DIFFICULT_EASY;
  game.width=XSIZE;
  game.height=YSIZE;
  video_bpp = 0;
  videoflags = SDL_SWSURFACE | SDL_DOUBLEBUF;
  noanimation=nosound=0;
  skip_introduction=0;

  random_init();

  /* Parse command line option */

#ifdef HAVE_GETOPT_LONG
  while ((opt = getopt_long(argc, argv,"b:wHfsl:d:hvia",long_options,&option_index)) != EOF)
#else
  while ((opt = getopt(argc, argv,"b:wHfsl:d:hvia")) != EOF)
#endif
   {
     switch (opt) 
      {
       case 'b': /* --bpp */
	 video_bpp=atoi(optarg);
	 break;
       case 'w': /* --warp */
	 videoflags |= SDL_HWPALETTE;
	 break;
       case 'H': /* --hw */
	 videoflags |= SDL_HWSURFACE;
	 break;
       case 'f': /* --fullscreen */
	 videoflags |= SDL_FULLSCREEN;
	 break;
#if ENABLE_SOUND
       case 's': /* --no-sound */
	 nosound=1;
	 break;
#endif
#ifdef CHEAT_MODE
       case 'l': /* --level */
	 game.level = atoi(optarg);
	 break;
#endif
       case 'd': /* --difficulty */
	 game.difficulty = atoi(optarg);
	 if (game.difficulty<0 || game.difficulty>=DIFFICULT_LEVEL)
	  {
	    fprintf(stderr,"Wrong difficulty %d, must be between 0 and %d\n",game.difficulty,DIFFICULT_LEVEL-1);
	    usage(argv[0]);
	    exit(1);
	  }
	 break;
       case 'v': /* --version */
	 fprintf(stderr,"Stonage (%s)\n",VERSION);
	 fprintf(stderr,"Copyright (C) 2001 Luc Saillard.\n"
	     "Stonage comes with NO WARRANTY,\n"
	     "to the extent permitted by law.\n"
	     "You may redistribute copies of Stonage\n"
	     "under the terms of the GNU General Public License.\n"
	     "For more information about these matters,\n"
	     "see the files named COPYING.\n");
	 exit(0);
       case 'i': /* --skipintro */
	 skip_introduction=1;
	 break;
       case 'a': /* --no-animation */
	 noanimation=1;
	 break;
       case 'h':
	 usage(argv[0]);
	 exit(0);
       default:
	 usage(argv[0]);
	 exit(1);
      }
   }

  /* Initialise SDL library */
  if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 )
   {
     fprintf(stderr, "Impossible d'initialiser SDL: %s\n", SDL_GetError());
     exit(1);
   }
  atexit(SDL_Quit);

  /* Initialize the TTF library */
  if ( TTF_Init() < 0 ) 
   {
     fprintf(stderr, "Couldn't initialize TTF: %s\n", SDL_GetError());
     exit(1);
   }       
  atexit(TTF_Quit);

  screen = SDL_SetVideoMode(640, 480, video_bpp, videoflags);
  if ( screen == NULL )
   {
     fprintf(stderr, "Impossible de passer en 640x480 en %d bpp: %s\n",video_bpp,SDL_GetError());
     exit(1);
   }

  /* No keyboard repeat */
  SDL_EnableKeyRepeat(0,0);

#ifndef DONT_BUILD_INTRO
  if (!skip_introduction)
    Intro(screen,nosound);
#else
  if (!skip_introduction)
    Game_SplashScreen();
#endif

#if ENABLE_SOUND
  if (!nosound)
    Music_Init();
#endif

 
}


/**
 *
 * Print to stderr, the command option of the program
 *
 */
static void
usage (const char *programname)
{
  fprintf(stderr, "Usage: %s [options]\n", programname);
  fprintf(stderr, "Version: %s\n", VERSION);
#ifdef HAVE_GETOPT_LONG
  fprintf(stderr, "\t-b, --bpp bpp         Number of bits for color graphics\n");
  fprintf(stderr, "\t-w, --warp            Force use Hardware palette\n");
  fprintf(stderr, "\t-H, --hardware        Force use Hardware surface\n");
  fprintf(stderr, "\t-f, --fullscreen      Turn on Fullscreen\n");
#ifdef ENABLE_SOUND
  fprintf(stderr, "\t-s, --no-sound        Turn off Sound support\n");
#endif
#ifdef CHEAT_MODE
  fprintf(stderr, "\t-l, --level level     [CHEAT] start game at specified level\n");
#endif
  fprintf(stderr, "\t-d  --difficulty diff Specify the difficulty of the game (0:easiest-%d:hardest)\n",DIFFICULT_LEVEL-1);
  fprintf(stderr, "\t-v, --version         Print program version number, then exit\n");
  fprintf(stderr, "\t-i, --skipintro       Skip the introduction\n");
  fprintf(stderr, "\t-h, --help            Print this help, then exit\n");
#else
  fprintf(stderr, "\t-b bpp   Number of bits for color graphics\n");
  fprintf(stderr, "\t-w       Force use Hardware palette\n");
  fprintf(stderr, "\t-H       Force use Hardware surface\n");
  fprintf(stderr, "\t-f       Turn on Fullscreen\n");
#ifdef ENABLE_SOUND
  fprintf(stderr, "\t-s       Turn off Sound support\n");
#endif
#ifdef CHEAT_MODE
  fprintf(stderr, "\t-l level [CHEAT] start game at specified level\n");
#endif
  fprintf(stderr, "\t-d diff  Specify the difficulty of the game (0:easiest-%d:hardest)\n",DIFFICULT_LEVEL-1);
  fprintf(stderr, "\t-i       Skip the introduction\n");
  fprintf(stderr, "\t-v       Print program version number, then exit\n");
  fprintf(stderr, "\t-h       Print this help, then exit\n");
#endif
  fprintf(stderr, "\n");
  fprintf(stderr, "Report bugs to luc@saillard.org\n");
}

/**
 *
 * random_init()
 *
 *
 */
static void
random_init(void)
{
#ifdef URANDOM_DEVICE
    int r;
    int f=open(URANDOM_DEVICE,O_RDONLY);
    read(f,&r,sizeof(int));
    read(f,&r,sizeof(int));
    close(f);
#else
    /* This is for system who don't have a /dev/urandom */
    int i,r=0;
    struct timeval tv;
    r=getpid();
    for (i=0;i<6;i++)
     {
       gettimeofday(&tv,NULL);
       r += time(NULL) << 4;
       r += tv.tv_usec >> 4;
       r *= 11;
     }
#endif
    SRANDOM(r);
}



