#include <stdio.h>

#include <concorde.h>
#include <ysmaze2.h>
#include "mzedit.h"
#include "ysgui.h"

#include <msdos.cf>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <wgb.h>
#include <egb.h>

#define BACK_COLOR  15
#define WALL_COLOR   0
#define SWALL_COLOR  4
#define GRID_COLOR   0
#define NUMB_COLOR   9

static void MazeDrawOneWallWin
            (char *egb,int sx,int sy,int vx,int vy,int l,int wal,int pas);
static void WgbLine(char *egb,int x0,int y0,int x1,int y1);
static void WgbPset(char *egb,int x,int y);
static void WgbBox(char *egb,int x0,int y0,int x1,int y1);
static void WgbFilledBox(char *egb,int x0,int y0,int x1,int y1);
static void WgbPrint(char *egb,int x,int y,char *mes);

static void MazeDrawMapOneWallWin
     (char *egb,MAZEMAP *mz,int sx,int sy,int bx,int by,int dir,int l)
{
	int wal,pas,p,vx,vy;
	p= by*(mz->lx) +bx;

	switch(dir)
	{
	default:
		return;
	case 0:
		wal= mz->map[p] & 3;
		pas= mz->map[p] & 16;
		vx=1;vy=0;
		break;
	case 1:
		wal=(mz->map[p] & 12)/4;
		pas= mz->map[p] & 32;
		vx=0;vy=1;
		break;
	case 2:
		if( (++by)==mz->ly )by=0;
		MazeDrawMapOneWallWin(egb,mz,sx,sy+l,bx,by,0,l);
		return;
	case 3:		
		if( (++bx)==mz->lx )bx=0;
		MazeDrawMapOneWallWin(egb,mz,sx+l,sy,bx,by,1,l);
		return;
	}

	MazeDrawOneWallWin(egb,sx,sy,vx,vy,l,wal,pas);
}


void MazeClearMapWin(char *egb)
{
	EGB_color(egb,1,BACK_COLOR);
	WGB_partClearScreen(egb);
}


void MazeDrawMapWin
    (char *egb,MAZEMAP *mz,int lx,int ly,int x1,int y1,int x2,int y2,int l)
{
	int bx,by,sx,sy;

	if(x1<0)x1=0;
	if(y1<0)y1=0;

	for(by=y1; by<=y2; by++)
	{
		for(bx=x1; bx<=x2; bx++)
		{
			sx=lx+(bx % (mz->lx) )*l;
			sy=ly+(by % (mz->ly) )*l;

			MazeDrawMapOneWallWin(egb,mz,sx,sy,bx,by,0,l);
			MazeDrawMapOneWallWin(egb,mz,sx,sy,bx,by,1,l);

			DrawOneFloorCeiling(egb,mz,lx,ly,bx,by,l);
			DrawOneFloorNumber(egb,mz,lx,ly,bx,by,l);
		}
	}

	by=y2;
	sy=ly+(by % (mz->ly) )*l;
	for(bx=x1; bx<=x2; bx++)
	{
		sx=lx+(bx % (mz->lx) )*l;
		MazeDrawMapOneWallWin(egb,mz,sx,sy,bx,by,2,l);
	}
	bx=x2;
	sx=lx+(bx % (mz->lx) )*l;
	for(by=y1; by<=y2; by++)
	{
		sy=ly+(by % (mz->ly) )*l;
		MazeDrawMapOneWallWin(egb,mz,sx,sy,bx,by,3,l);
	}
}


static void MazeDrawOneWallWin
    (char *egb,int sx,int sy,int vx,int vy,int l,int wal,int pas)
{
	int i;

	EGB_writeMode(egb,9);
	EGB_color(egb,0,BACK_COLOR);
	WgbLine(egb,sx,sy,sx+vx*(l-1),sy+vy*(l-1));

	EGB_color(egb,0,GRID_COLOR);
	WgbPset(egb,sx     ,sy     );
	WgbPset(egb,sx+vx*l,sy+vy*l);

	if  (wal==1 && !pas)EGB_color(egb,0,SWALL_COLOR);
	else                EGB_color(egb,0,WALL_COLOR);

	if(wal==1)
	{
		WgbLine(egb,sx,sy,sx+vx*(l-1),sy+vy*(l-1));
	}
	else if(wal==2)
	{
		WgbLine(egb,sx,sy,sx+vx*2,sy+vy*2);
		WgbLine(egb,sx+vx*(l-1),sy+vy*(l-1),sx+vx*(l-2),sy+vy*(l-2));
	}
	else if(wal==0 && pas)
	{
		for(i=0; i<l; i+=2)WgbPset(egb,sx+vx*i,sy+vy*i);
	}
}


void DrawOneFloorCeiling
      (char *egb,MAZEMAP *mz,int sx,int sy,int cx,int cy,int l)
{
	int fc;

	fc=MazeFloorCeiling(mz,cx,cy);
	sx+=cx*l;
	sy+=cy*l;

	
	if(fc & 1)EGB_color(egb,0,WALL_COLOR);
	     else EGB_color(egb,0,BACK_COLOR);
	WgbLine(egb,sx+1,sy+l-2,sx+l-2,sy+l-2);

	if(fc & 2)EGB_color(egb,0,WALL_COLOR);
	     else EGB_color(egb,0,BACK_COLOR);
	WgbLine(egb,sx+1,sy+  2,sx+l-2,sy+  2);
}


void DrawOneFloorNumber
     (char *egb,MAZEMAP *mz,int sx,int sy,int cx,int cy,int l)
{
	int n;
	char c[16];

	n=MazeFloorNumber(mz,cx,cy);

	sx+=cx*l;
	sy+=cy*l;
	EGB_color(egb,0,BACK_COLOR);
	EGB_color(egb,1,BACK_COLOR);
	EGB_color(egb,2,BACK_COLOR);
	WgbFilledBox(egb,sx+1,sy+3,sx+l-2,sy+l-3);

	if(n!=0)
	{
		c[0]=n/100+'0';
		n%=100;
		c[1]=n/10 +'0';
		c[2]=n%10 +'0';
		c[3]=0;
		EGB_color(egb,0,NUMB_COLOR);
		WgbPrint(egb,sx+1,sy+l-3,c);
	}
}


static void WgbLine(char *egb,int x0,int y0,int x1,int y1)
{
	short para[5];

	para[0]=2;
	para[1]=(short)x0;
	para[2]=(short)y0;
	para[3]=(short)x1;
	para[4]=(short)y1;
	WGB_connect(egb,(char *)para);
}

static void WgbPset(char *egb,int x,int y)
{
	short pset[3];

	pset[0]=1;
	pset[1]=(short)x;
	pset[2]=(short)y;

	WGB_pset(egb,(char *)pset);
}

static void WgbBox(char *egb,int x0,int y0,int x1,int y1)
{
	short rect[4];

	rect[0]=(short)x0;
	rect[1]=(short)y0;
	rect[2]=(short)x1;
	rect[3]=(short)y1;
	EGB_paintMode(egb,0x02);
	WGB_rectangle(egb,(char *)rect);
}

static void WgbFilledBox(char *egb,int x0,int y0,int x1,int y1)
{
	short rect[4];

	rect[0]=(short)x0;
	rect[1]=(short)y0;
	rect[2]=(short)x1;
	rect[3]=(short)y1;
	EGB_paintMode(egb,0x20);
	WGB_rectangle(egb,(char *)rect);
	EGB_paintMode(egb,0x02);
}


// typedef struct {
//     short int fontId;		/* 文字種 */
//     short int sizeX;		/* 文字サイズX */
//     short int sizeY;		/* 文字サイズY */
//     short int attribute;	/* 文字スタイル */
//     short int space;		/* 文字間隔 */
//     short int margin;		/* 文字列調整幅 */
// } FONTTYPE;
// 
// typedef struct {
//     unsigned char     *offset;	/* データ格納領域オフセット */
//     unsigned short int segment; /* データ領域セグメント */
//     short int          rowBytes;/* データ横サイズ */
//     short int          sizeX;	/* データ横ドット数 */
//     short int          sizeY;	/* データ縦ドット数 */
// } BITMAP;

static FONTTYPE ftyp;
static BITMAP fbmp;
static struct
{
	unsigned char *dat;
	unsigned short ds;
	short x1,y1,x2,y2;
} putstrc;

#define STR_LEN 80
#define CHR_DOT 6
#define CHR_HEI 12

void WgbInitPrint12()
{
	ftyp.fontId=1;	/* Systen 12dot font */
	ftyp.sizeX=12;
	ftyp.sizeY=12;
	ftyp.attribute=0;
	ftyp.space=0;
	ftyp.margin=0;

	fbmp.offset=MALLOCFUNC(STR_LEN*CHR_DOT*CHR_HEI/8);
	fbmp.segment=getds();

	putstrc.dat=fbmp.offset;
	putstrc.ds=fbmp.segment;
}

static void WgbPrint(char *egb,int x,int y,char *mes)
{
	static struct {
		short x,y,len;
		char mes[80];
	} string;
	Rect rec;
	int i;

	string.x=x;
	string.y=y;
	string.len=strlen(mes);
	strcpy(string.mes,mes);

	FNT_stringSize(mes,&fbmp,&ftyp);
	rec.left=0;
	rec.up=0;
	rec.right=fbmp.sizeX-1;
	rec.down=fbmp.sizeY-1;
	for(i=0; i<fbmp.sizeX*fbmp.sizeY/8; i++)
	{
		fbmp.offset[i]=0;
	}
	FNT_readString(mes,&fbmp,&rec,&ftyp);

	putstrc.x1=x;
	putstrc.y1=y-11;
	putstrc.x2=x+fbmp.sizeX-1;
	putstrc.y2=y;
	EGB_writeMode(egb,9);
	EGB_color(egb,1,BACK_COLOR);
	WGB_putBlockColor(egb,1,(char *)&putstrc);
}
