/******************************************************************************
*									      *
*	(C) 1993 by K. Ballueder					      *
*									      *
*	See README and COPYING for details.				      *
*									      *
*	Please feel free to contact me:					      *
*		kballued@charon.physik.uni-osnabrueck.de		      *
*		kballued@jupiter.rz.uni-osnabrueck.de			      *
*									      *
******************************************************************************/

/***********************************************************************

graphic.c:	Graphic routines (wat sonst?)

*****************************************************end of header*****/

#include "bdash.h"
#include "systems.h"
#include "graphic.h"
#include "io.h"
#include "scores.h"
#include "zfopen.h"

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

#ifdef OS_DOS
#	include <alloc.h>
#	include <mem.h>
#	include <dos.h>
#else
#	include "string.h"	/* fuer memmove */
#endif

#include "vgax.h"
#include "gr_interface.h"
#include "linux_gl.h"
#include "dos_bgi.h"
#include <vgagl.h>

#ifdef ANIMOBJECT
	#include "AnimObject.h"
	#define GOBJECT AnimObject
#else
	#include "GObject.h"
	#define GOBJECT GObject
#endif


int gxoffset_x = 0, gxoffset_y = 0;

int gr_maxx, gr_maxy;


#define ONSCREEN(x,y) ((gxoffset_x <= x)&&(x < gxoffset_x+10)&&(gxoffset_y <= y)&&(y <gxoffset_y+8))

void erase_score(void);

 
#ifndef DUMMY_VERSION

void display(int px, int py)
{
	register int x,y;

	debug_printf("entering display()\n");

		gxoffset_x = 0; gxoffset_y = 0;

		while(px-gxoffset_x >= 6)
		gxoffset_x++;
		while(py-gxoffset_y >= 4)
		gxoffset_y++;

		for(x=0;x<10;x++)
			for(y=0;y<8;y++)
				display_image(x<<5,y*25,figur[level_table[y+gxoffset_y][x+gxoffset_x]]);
		display_score();
		update_graphics();
		debug_printf("leaving display()\n");
}


void draw_image(int x, int y, unsigned char object)
{
	if(ONSCREEN(x,y))
		display_image((x-gxoffset_x)<<5,(y-gxoffset_y)*25,figur[object]);
}
void draw_spieler(int x, int y, int player)
{
	if(ONSCREEN(x,y))
		display_image((x-gxoffset_x)<<5,(y-gxoffset_y)*25,figur[player == 0 ? FELD_SPIELER_1:FELD_SPIELER_2]);
}

void draw_leer(int x, int y)
{
	if(ONSCREEN(x,y))
		display_image((x-gxoffset_x)<<5,(y-gxoffset_y)*25,figur[FELD_LEER]);
}

void move_object(int alt_x, int alt_y, int neu_x, int neu_y, unsigned obj_num)
{

	int x1 = (alt_x-gxoffset_x)*IMAGEWIDTH, x2 = (neu_x-gxoffset_x)*IMAGEWIDTH;
	int y1 = (alt_y-gxoffset_y)*IMAGEHEIGHT, y2 = (neu_y-gxoffset_y)*IMAGEHEIGHT;	
	int step, xstep = (x2-x1)/ANIMSTEPS, ystep = (y2-y1)/ANIMSTEPS;
	
	if(obj_num == FELD_STEIN) obj_num = FELD_STEIN_2;
	if(obj_num == FELD_BOMBE) obj_num = FELD_BOMBE_2;
	if(ONSCREEN(alt_x,alt_y))
	{	gl_fillbox(x1, y1, IMAGEWIDTH, IMAGEHEIGHT,0);
		if(ONSCREEN(neu_x,neu_y))
		{	for(step=1;step < ANIMSTEPS; step++)
			{	gl_fillbox(x1,y1,IMAGEWIDTH,IMAGEHEIGHT,0);
				display_image(x1+xstep*step, y1,figur[obj_num]);
			}
			for(step=1;step < ANIMSTEPS; step++)
			{	gl_fillbox(x2,y1,IMAGEWIDTH,IMAGEHEIGHT,0);
				display_image(x2, y1+ystep*step,figur[obj_num]);
			}
		}
		gl_fillbox(x1, y1, IMAGEWIDTH, IMAGEHEIGHT, 0);
		gl_fillbox(x2, y1, IMAGEWIDTH, IMAGEHEIGHT, 0);
		display_image(x2, y2,figur[obj_num]);
	}
	level_table[alt_y][alt_x] = FELD_LEER;
	level_table[neu_y][neu_x] = obj_num;
}


void display_message(char *l1, char *l2, char *l3)
{
	int width, pos;
	int x1, x2 ,y1, y2;

	width = TEXTWIDTH(l1);
	width = TEXTWIDTH(l2) > width ? TEXTWIDTH(l2) : width;
	width = TEXTWIDTH(l3) > width ? TEXTWIDTH(l3) : width;

	x1 = (gr_maxx-width-8)>>1;
	y1 = (gr_maxy-30)>>1;
	x2 = (gr_maxx+width+8)>>1;
	y2 = (gr_maxy+34)>>1;
	gr_fillbox(x1,y1,x2-x1+1,y2-y1+1,BLUE);
	gr_line(x1,y1,x2,y1,TEXTCOLOR);
	gr_line(x1,y2,x2,y2,TEXTCOLOR);
	gr_line(x1,y1,x1,y2,TEXTCOLOR);
	gr_line(x2,y1,x2,y2,TEXTCOLOR);
 	gr_line(x1+1,y2+1,x2+1,y2+1,0);
	gr_line(x2+1,y1+1,x2+1,y2+1,0);
	gr_line(x1+2,y2+2,x2+2,y2+2,0);
	gr_line(x2+2,y1+2,x2+2,y2+2,0);

	pos = gr_maxx / 2;
	write_text(pos-TEXTWIDTH(l1)/2,(gr_maxy>>1)-12,l1);
	write_text(pos-TEXTWIDTH(l2)/2,(gr_maxy>>1)-2,l2);
	write_text(pos-TEXTWIDTH(l3)/2,(gr_maxy>>1)+8,l3);
	update_graphics();
	CLEAR_KEY_BUF

	WAITKEY	
	display(player_x[0],player_y[0]);
	update_graphics();
}




void gr_display_score(unsigned long score)	/* called by display_score() */
{
	static char buf[10]; /* should be enough */

	sprintf(buf,"%lu",score);
	write_text(gr_maxx-TEXTWIDTH(buf),gr_maxy-TEXTHEIGHT(buf),buf);
}

void erase_score(void)	/* remove score from screen */
{
	display_image(9<<5,7*25,figur[level_table[7+gxoffset_y][9+gxoffset_x]]);
	display_image(8<<5,7*25,figur[level_table[7+gxoffset_y][8+gxoffset_x]]);
}

int load_graphics(void) /* Laden der Bildchen und der Palette */
												/* Initialisieren der Grafik */
{
	FILE *datafile;
	int i,dummy,r,g,b;

	extern void *figur[NUM_OF_FIGURS];

	DacPalette256 palette;

	initgraphics();
	datafile = zfopen(DATAPATH FILEDATA,"rb");
	if(datafile == NULL)
	{			
		leavegraphics();
		perror("no graphic definitions");
		return -2;
	}

	for(i=0;i<NUM_OF_FIGURS;i++)
	{ 	figur[i]=load(new(GOBJECT,32,25,1),datafile);
		if(figur[i] == NULL)
		{ 	perror("load_graphics no object");
			return -1;
		}
	}
	fclose(datafile);
	datafile = zfopen(globale_flags.monochrome?DATAPATH FILECOLORBW:\
	DATAPATH FILECOLOR,"rt"); /* Palete lesen ColorMaP */
	if(datafile == NULL)
	{	
		leavegraphics();
		perror("no graphics palette");
		return -1;
	}

	for(i=0;i<256;i++)
	{ 	fscanf(datafile,"%d %d %d %d",&dummy,&r,&g,&b);
		palette[i][0] = r>>2; palette[i][1] = g>>2; palette[i][2] = b>>2;
	}
	fclose(datafile);
	setpalette(&palette);
	return 0;
}


void scroll_up(int py)
{
	int x;

	if(gxoffset_y > level_y_size-9 || (py-gxoffset_y < 4))
		return;

	erase_score();
	gxoffset_y++;
	_scroll_up();
	for(x = 0; x < 10; x++)
		display_image(x<<5,175,figur[level_table[7+gxoffset_y][x+gxoffset_x]]);
	display_score();
	update_graphics();
}

void scroll_down(int py)
{
	int x;

	if(gxoffset_y == 0 || py-gxoffset_y > 4)
		return;
	gxoffset_y--;

	_scroll_down();
	for(x = 0; x < 10; x++)
	display_image(x<<5,0,figur[level_table[gxoffset_y][x+gxoffset_x]]);
	display_score();
	update_graphics();
}

void scroll_left(int px)
{
	register int y;

	if(gxoffset_x > level_x_size-11 || px-gxoffset_x < 5)
		return;

	erase_score();
	gxoffset_x++;
	_scroll_left();
	for(y = 0; y < 8; y++)
		display_image(288,y*25,figur[level_table[y+gxoffset_y][9+gxoffset_x]]);
	display_score();
	update_graphics();
}

void scroll_right(int px)
{
	register int y;


	if(gxoffset_x == 0 || px-gxoffset_x > 5)
		return;

	erase_score();
	gxoffset_x--;
	_scroll_right();
	for(y = 0; y < 8; y++)
		display_image(0,y*25,figur[level_table[y+gxoffset_y][gxoffset_x]]);
	display_score();
	update_graphics();
}
#else
int load_graphics(void)
{	return 0; }

#pragma warn -par
#pragma warn -use
#include <stdio.h>

void display(int gxoffset_x, int gxoffset_y)
{
}

void scroll_up(int py) /* Spielfeld um eine Zeile hochscrollen */
{
	puts("scroll_up()");
}
void scroll_down(int py) /* Spielfeld um eine Zeile herunterrollen */
{
	puts("scroll_down()");
}
void scroll_left(int px) /* Spielfeld um eine Spalte nach links scrollen */
{
	puts("scroll_left()");
}
void scroll_right(int px) /* Spielfeld um eine Spalte nach rechts scrollen */
{
	puts("scroll_right()");
}
void draw_image(int x, int y, unsigned char object) /* Feld malen */
{}
void draw_spieler(int x, int y, int player) /* Die Spielfiguren darstellen, bei x,y */
{}
void draw_leer(int x, int y) /* bei x,y ein leeres Feld darstellen */
{}
void display_message(char *l1, char *l2, char *l3)
{
	puts("display_message():");
	puts("{"); puts(l1); puts(l2); puts(l3); puts("}");
}

/* ein Objekt verschieben */

void move_object(int alt_x, int alt_y, int neu_x, int neu_y, unsigned obj_num)
{}

void _display_score(void)
{}

#endif
