/*
   play.cc

   This file is part of LuxMan.
   
   Copyright (C) 1994,1995 Frank McIngvale (frankm@nuance.com)
   
   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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <vga.h>
#include <rawkey/rawkey.h>
#include <stdlib.h>
#include <gtools/bitmap.h>
#include <gtools/gr.h>
#include <argv/argv.h>
#include "dotmap.h"
#include "sigs.h"
#include "bigdotmap.h"
#include "run.h"
#include "globals.h"
#include "score.h"
#include "banner.h"
#include "sound.h"
#include "error.h"
#include "highscore.h"
#include "calib.h"

extern "C" {
  typedef struct {
	char *mazename;
	char *fruitname;
	int fruitval;
	int max_fruit;
  } Level;
}

static Level levels[] = {
  { "m1.map", "cherry.map", 100, 10 },
  { "m2.map", "berry.map", 200, 10 },
  { "m2.1.map", "can.map", 300, 10 },
  { "m2.5.map", "apple.map", 500, 10 },  
  { "m8.map", "apple.map", 500, 10 },
  { "m6.map", "shield.map", 1000, 10 },
  { "m3.map", "shield.map", 1000, 10 },  
  { "m7.map", "tbird.map", 2000, 10 },
  { "m5.map", "tbird.map", 2000, 10 },
  { "m9.map", "chest.map", 5000, 10 },
  { "m10.map", "chest.map", 5000, 10 } };


static void draw_level_display( int level, int wrap )
{
  Bitmap *fruit;
  int i;
  int w, h;
  
  fruit = new Bitmap( levels[0].fruitname );
  w = fruit->w;
  h = fruit->h;
  delete fruit;

  gr_fillbox( 5*(w+4), 198-h, 10*(w+4), 199, BLACK );
  
  for( i=0; i<5; ++i ) 
	{
	  fruit = new Bitmap( levels[level-1].fruitname );
	  put_bitmap_t( (5+i)*(fruit->w+4), 198-fruit->h, fruit );
	  delete fruit;

	  if ( level == 1 )
		{
		  if ( wrap )
			level = sizeof( levels ) / sizeof( Level );
		  else
			return;
		}
	  else
		--level;
	}
}

int run_game( int *level, int skill )
{
  RunState *runstate;
  Font *small_font;
  float fps;
  Bitmap *lux;
  int r;
  int num_levels, cur_level;
  int wrap=0;
  int score;
  
  num_levels = sizeof( levels ) / sizeof( Level );

  if ( gb_start_level < 1 || gb_start_level > num_levels )
	fatal( "Bad start level: %d\nValid range: [%d,%d]\n", gb_start_level,
		  1, num_levels );
	  
  cur_level = gb_start_level;
  
  runstate = new RunState;
  runstate->tile = new Bitmap( "tile.map" );
  runstate->maze = new Bitmap( levels[cur_level-1].mazename );

  lux = new Bitmap( "lux_l1.map" );

  runstate->dotmap = new DotMap( runstate->maze, runstate->tile, 2, 2 );
  runstate->bigdotmap = new BigDotMap( runstate->maze, runstate->tile );

  small_font = new Font( "small.font" );

  runstate->lives = 2;
  runstate->next_free = 10000;

  runstate->skill = skill;

//  Snd_effect ( SND_BEGIN, CHAN4 );

  runstate->score = new Score( 319 - gr_textw( "00000000", small_font ),
					   runstate->maze->h*runstate->tile->h + 2, small_font );

  runstate->frames = 0;
  runstate->seconds = 0;
  runstate->level = 1;
  runstate->fruitname = levels[cur_level-1].fruitname;
  runstate->fruitval = levels[cur_level-1].fruitval;
  runstate->max_fruit = levels[cur_level-1].max_fruit;
  runstate->play_intro = 1;
  
  do {
	draw_level_display( cur_level, wrap );
	
	r = run_screen( runstate );

	if ( r == 1 )
	  {
		if ( cur_level < num_levels )	
		  ++cur_level;
		else
		  {
			cur_level = 1;
			wrap = 1;
		  }

		delete runstate->maze;
		delete runstate->dotmap;
		delete runstate->bigdotmap;

		runstate->maze = new Bitmap( levels[cur_level-1].mazename );
		runstate->dotmap = new DotMap( runstate->maze, runstate->tile, 2, 2 );
		runstate->bigdotmap = new BigDotMap( runstate->maze, runstate->tile );

		runstate->fruitname = levels[cur_level-1].fruitname;
		runstate->fruitval = levels[cur_level-1].fruitval;
		runstate->max_fruit = levels[cur_level-1].max_fruit;
	  }

  } while( runstate->lives >= 0 && cur_level <= num_levels );

  alarm( 0 );
  
  display_banner( "Player One", "Game Over", small_font, 2 );

  score = runstate->score->get();
  *level = runstate->level;
  
  if ( runstate->seconds > 0 )
	fps = ((float)runstate->frames)/((float)runstate->seconds);
  else
	fps = 0;
  
  alarm( 10 );

  delete lux;
  delete small_font;
  delete runstate->maze;
  delete runstate->tile;
  delete runstate->dotmap;
  delete runstate->bigdotmap;
  delete runstate->score;
  delete runstate;

  printf("%f fps\n", fps );

  alarm( 0 );
  
  return score;
}
