/* data compression removed from sendline bit as some hp printers
   don't  understand the compressed data format,  -plus will re-enable it */

#define XSIZECM 20.32		/* at 120 DPI  */
#define YSIZECM 25.4		/* at 72 DPI */
#define NXBITS 1440 /* 1064 	8 inches */
#define NYBITS 1800  /* 1424 	10 inches */
extern int hp_plus;
#ifdef __TURBOC__
#include <alloc.h>
#endif
#include "all.h"
#include <math.h>
#include "core.h"
#include "mygraph.h"
#include "mydev.h"
#define dp if (dop)
#ifndef __TURBOC__
#define huge
#endif
#define true (!false)
#define false 0
int dop=false;

int d_open(double x, double y);
extern int dev_low;
extern int cur_colori, cur_filli;
extern int gdebug;
extern int nxbits,nybits;
#define dbg if (gdebug==true)
int bitmap_print(void);
int bitmap_free(void);
int bitmap_alloc(void);
int bitmap_paint(int row, int x1, int x2);
int printmem(char *x,int n);
void pprintf(va_list arg_list, ...);
int dvitype(void);

/*--------------------------------------------------------------*/
/*	Bitmap output for EPSON printers 			*/
/*--------------------------------------------------------------*/
int bitmap_print(void);
char *bitmap_line(int y);
int bitmap_size(int *xbits, int *ybits, double *width, double *height);
bitmap_size(int *xbits, int *ybits, double *width, double *height)
{
	*xbits = NXBITS; *ybits = NYBITS; *width = XSIZECM; *height = YSIZECM;
	if (dev_low) {*xbits = *xbits/2; *ybits = *ybits/2;}

}
int print_row(int i);
#ifndef __TURBOC__
uint32 coreleft(void)
{
	return 4000000;
}
#endif

bitmap_free(void)
{
	printf("core left %ld \n",coreleft());
}
bitmap_alloc(void)
{
}
unsigned int grey_bits[] = {0x0000, 0x0200, 0x0802, 0x0a02,
		0x5050, 0x5250, 0x5852, 0x5a52,
		0xa5a5, 0xa7a5, 0xada7, 0xafa7,
		0xf5f5, 0xf7f5, 0xfdf7, 0xfff7, 0xffff};
unsigned int cur_bits[4];
#define NGREY 17
set_grey(float f)
{
	int i,j,m;
	i = (1.0-f)*(NGREY-.8);
	m = grey_bits[i];
	for (j=0; j<4; j++) {
		cur_bits[j] = m & 0x000f;
		m = m >> 4;
	}
}
bitmap_paint(int row, int x1, int x2)
{
	int i,xm,ym,xadd=0;
	unsigned char *line;
	x1-=1; x2-=1;
	if (x1<0) x1 = 0;
	if (x2>=nxbits) x2 = nxbits-1;
	ym = row % 4;
	if ((row & 4)>0) xadd = 1;
	line = bitmap_line(row);
	for (;x1<=x2;x1++) {
		xm = 1 << ((x1+xadd) % 4);
		if ((cur_bits[ym] & xm)!=0) {
			i = line[x1/2];
			if (x1 % 2==0) i = (i & 0xf0) | (cur_filli << 4);
			else i = (i & 0x0f) | cur_filli;
			line[x1/2] = i;
		}
	}
}
unsigned char *bitmapv[NYBITS];
int bitmapn[NYBITS];
char *bitmap_line(int y)
{
	static unsigned char bitrow[NXBITS/2+3];
	static unsigned char bitc[NXBITS],*o,*bc,c;
	int nc,x,i,j;
	static lasty = -2;
	if (lasty==y) return bitrow;
	if (y<0 || y>=nybits) printf("y is out of range %d \n",y);
	if (y>=nybits) y = nybits-1;
	dp printf("--Core left %ld  line %d \n",coreleft(),y);

	if (lasty != -2) {
	  o = &bitc[0];
	  for (x=0; x<(nxbits/2) ; x++) {
		c = bitrow[x];
		nc = 0;
		for (;x<(nxbits/2-1) && bitrow[x+1]==c && nc<250; x++) nc++;
		*o++ = nc;
		*o++ = c;
	  }
	  nc = o-bitc;
	  bitmapn[lasty] = nc;
	  if (bitmapv[lasty]!=NULL) bitmapv[lasty] = realloc(bitmapv[lasty],nc);
	  else bitmapv[lasty] = malloc(nc);
	  if (bitmapv[lasty]==0) {
		printf("Failed to allocate enough memory for bitmap \n");
		abort();
	  }
	  dp printf("saving line length %d \n",nc);
	  memcpy(bitmapv[lasty],bitc,nc);
	  o = bitmapv[lasty];
	}
	lasty = y;
	if (bitmapv[y]==NULL) {
		memset(bitrow,0,nxbits/2);
 dp		printf("returning blank line\n");
		return bitrow;
	}
	dp printf("Expanding line %d (%p) \n",y,bitmapv[y]);

	nc = 0;
	bc = bitmapv[y];
	for (i=0, o = bitrow; i<bitmapn[y]; i+=2) {
		dp printf("E, %d %d \n",bc[i],bc[i+1]);
		for (j=0; j<=bc[i]; j++) {
			*o++ = bc[i+1]; nc++;
			if (nc>nxbits/2) {
				printf("gone past end\n");
				return bitrow;
			}
		}
	}
	return bitrow;
}
bitmap_pixel(int x, int y)
{
	static char *line;
	static int ly= -2,i;
/*	if (x<0 || x>nxbits || y < 0 || y > nybits) return; */
	line = bitmap_line(y);
	i = line[x/2];
	if (x % 2==0) i = (i & 0xf0) | (cur_colori << 4);
	else i = (i & 0x0f) | cur_colori;
	line[x/2] = i;
/* 	line[x/2] |= (1 << (x % 2)); */
	ly = y;
}

dvitype(void)
{
	printf("Usage: DVIPJ   [-old]   [-low]   [outfile.prt]\n");
	if (dev_low) printf("Using 90 DPI\n");
	if (hp_plus)
	 printf("HP PaintJet, (-old turns of data compression)");
	else
	 printf("HP PaintJet, (COMPRESSION OFF)");
}
int ljsendline(char *s, int nc, int y, int plane);

/*
#ifdef __TURBOC__
#include <graphics.h>
xxbitmap_print()
{
	int x,y,z;
	int d_graphmode=0,g_driver=0,g_error;
	double f;
	unsigned char *line;
	printf("press return to enter graphics \n");
	getch();
	dop = false;
	detectgraph(&g_driver, &d_graphmode);
	if (g_driver<0) {
		printf("No graphics hardware detected !!!!! \n");
		gle_abort("Could not load BGI graphics\n");
	}
	initgraph(&g_driver,&d_graphmode,"");
	g_error = graphresult();
	if (g_error<0) {
		printf("Init graph error %s\n",grapherrormsg(g_error));
		gle_abort("Init graph error\n");
	}

	for (y=1; y<399; y++) {
	  line = bitmap_line(y);
	  for (x=0; x<620 ; x++) {
		z = 1 << (x % 8);
		if ((z & line[x/8]) != 0) {
			 putpixel(x,y,2);
		}

	  }
	}

	getch();

	closegraph();
}
#endif
*/
int bitplane(char line[],int x, int p);

bitmap_print(void)
{
	int x,y;
	char *line;
	static unsigned char out_buff[NXBITS+20];
	unsigned char swapbit[256];
	unsigned char swapnib[16]={0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
	unsigned char *o,c;
	int nc,i,n1,n2,plane;

	printf("Writing out bitmap\n");
	for (i=0;i<256;i++) {
		n1 = i & 0xf;
		n2 = (i >> 4) & 0xf;
		swapbit[i] = swapnib[n2] | (swapnib[n1] << 4);
	}
	pprintf("%cE",27); 	/* reset  */
	if (dev_low)  pprintf("\x1b*t90R");	/* set resoulution 150 dpi */
	else          pprintf("\x1b*t180R");	/* set resoulution 150 dpi */
		/*pprintf("\x1b&a%.1fH",0.0); 		 move x */
		/*pprintf("\x1b&a%.1fV",((NYBITS-y)/300.0)*720.0); 	move y */
	if (hp_plus) pprintf("\x1b*b1M");   /* compact,  not used as I think it doesn't work */
	pprintf("\x1b*r3U");	/* use 3 color planes, 8 colors*/
	pprintf("\x1b*r0A");	/* start graphics at left margin */
	for (y=(nybits-1); y>=0; y--) {
	  line = bitmap_line(y);
	  for (plane = 0; plane < 3; plane++) {
	    o = &out_buff[0];
	    for (x=0; x<nxbits/8; x++) {
		c = bitplane(line,x,plane);
		nc = 0;
		if (hp_plus) {
			for (;x<(nxbits/8-1) && bitplane(line,x+1,plane)==c
				&& nc<250; x++) nc++;
			*o++ = nc;
		}
		*o++ = swapbit[c];
	    }
	    ljsendline(out_buff,o-out_buff,y,plane);
	  }
	}
	pprintf("\x1b*rB");		/* end grpahics */
	pprintf("\x0c"); /* form feed, reset origin */
}
bitplane(char line[],int x, int p)
{
	/* x is byte count */
	/* construct a byte from line[x].hi.low.p  ... line[x+7] */
	register xx,i,curbit,c,pm;
	c = 0;
	x = x*8;
	pm = 1 << p;
	curbit = 1;
	for (xx=x; xx<x+8; xx++) {
		i = line[xx/2];
		if (xx % 2==0) i = (i & 0xf0)>>4;
		else i = i & 0xf;
		i = i & pm;
		if (i==0) c = c + curbit;
		curbit = curbit << 1;
	}
	return c;
}
ljsendline(char *s, int nc,int y,int plane)
{
	if (plane==2) 	pprintf("\x1b*b%dW",nc);	/* send y bytes */
	else 		pprintf("\x1b*b%dV",nc);	/* send y bytes */

	printmem(s,nc);
}



