/*->c.DrawLib */

/* Library of functions to make Draw files */


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



#include "h.os"
#include "h.bbc"
#include "h.wimp"
#include "h.wimpt"

#include "h.drawlevel0"



#include "h.def"
#include "h.wos"
#include "h.ram"


#include "h.drawlib"




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

char fontname[48]="\1Corpus.Medium";
int  fwidth=600;


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

static int vthickness;


#define WIDTH (vthickness)



static int cpx;       /* x font size in Draw units */
static int cpfx;      /* font painter cpx */
static int cpy;       /* y font size in Draw units */
static int cx=0;
static int cy=0;
static int drawtoff; /* flags the start of the line object */
static int drawfoff; /* flags the start of the text object */
static int textlen;
static int xlo,xhi,ylo,yhi;
static int abended;
static int linecolour;
static int fontfcolour;
static int fontbcolour;

int drawheadersize;

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

void flushdraw(Draw_diag * diag)
{
 int * drawt;

 if(drawtoff)
 {
  drawt=(int*)(diag->data+drawtoff);

/*  dprintf(6,"flush len=%d",(diag->length-drawtoff+4));  */

  *drawt++=(diag->length-drawtoff+4);
  *drawt++=xlo;
  *drawt++=ylo;
  *drawt++=xhi;
  *drawt++=yhi;
 }
}


void closedraw(Draw_diag * diag)
{
 flushdraw(diag);
 drawtoff=0;
}




void startdraw(int x,int y,Draw_diag * diag)
{
 int * buffp;
 int   nelem;
 int   i;

 if(!drawtoff)
 {
  buffp=(int*)(diag->data+diag->length);

  xlo=x-2*WIDTH;
  xhi=x+2*WIDTH;
  ylo=y-2*WIDTH;
  yhi=y+2*WIDTH;

  *buffp++=2;
  diag->length+=4;

  drawtoff=diag->length;
  *buffp++=17*4;

  *buffp++=xlo;
  *buffp++=ylo;
  *buffp++=xhi;
  *buffp++=yhi;

  *buffp++=-1;             /* fill colour */
  *buffp++=linecolour;     /* outline colour */
  *buffp++=WIDTH;          /* width */

  *buffp++=0;              /* style */

  diag->length+=9*4;

  *buffp++=0;
  diag->length+=4;

 }
 else
 {
  if(x<xlo) {xlo=x-2*WIDTH;}
  if(x>xhi) {xhi=x+2*WIDTH;}
  if(y<ylo) {ylo=y-2*WIDTH;}
  if(y>yhi) {yhi=y+2*WIDTH;}
 }
}



void vecmove(int x, int y,Draw_diag * diag)
{
 int * buffp;

 if(cx==x && cy==y && drawtoff) return;

 cx=x;
 cy=y;

 closefont(diag);
 startdraw(x,y,diag);
 buffp=(int*)(diag->data+diag->length-4);
 *buffp++=2; /* tag == move */
 *buffp++=x;
 *buffp++=y;
 diag->length+=8;

 *buffp++=0;
 diag->length+=4;
}



void vecdraw(int x,int y,Draw_diag * diag)
{
 int * buffp;

 cx=x;
 cy=y;

 closefont(diag);
 startdraw(x,y,diag);
 buffp=(int*)(diag->data+diag->length-4);
 *buffp++=8; /* tag == draw */
 *buffp++=x;
 *buffp++=y;
 diag->length+=8;

 *buffp++=0;
 diag->length+=4;
}



void veclinecolour(int pal,Draw_diag * diag)
{
 if(pal!=linecolour)
 {
  closedraw(diag);
  linecolour=pal;
 } 
}



void veccurve(int x1,int y1,int x2,int y2,int x3,int y3,Draw_diag * diag)
{
 int * buffp;

 if(abended) return;


 cx=x3;
 cy=y3;

 closefont(diag);
 startdraw(x1,y1,diag);
 buffp=(int*)(diag->data+diag->length-4);

 *buffp++=6; /* tag == curve */
 *buffp++=x1;
 *buffp++=y1;
 *buffp++=x2;
 *buffp++=y2;
 *buffp++=x3;
 *buffp++=y3;

 diag->length+=24;

 *buffp++=0;
 diag->length+=4;

}





void vectextsize(int xsize,int ysize,Draw_diag * diag)
{
 if(cpx!=xsize || cpy!=ysize)
 {
  closefont(diag);
  cpx=xsize;
  cpfx=(cpx*1000)/fwidth;
  cpy=ysize;
 }
}




void vectextcolour(int fpal,int bpal,Draw_diag * diag)
{
 if(fontfcolour!=fpal || fontbcolour!=bpal)
 {
  closefont(diag);
  fontfcolour=fpal;
  fontbcolour=bpal;
 }
}





void flushfont(Draw_diag * diag)
{
 int * drawt;

 if(drawfoff)
 {
  drawt=(int*)(diag->data+drawfoff);
  *drawt++=(diag->length-drawfoff+4);
  *drawt++=xlo;
  *drawt++=ylo;
  *drawt++=xhi;
  *drawt++=yhi;
 }
}



void closefont(Draw_diag * diag)
{
 flushfont(diag);
 drawfoff=0;
}




void startfont(int x,int y,Draw_diag * diag)
{
 int * buffp;

 if(!drawfoff)
 {

  buffp=(int*)(diag->data+diag->length);

  *buffp++=1;
  diag->length+=4;
  drawfoff=diag->length;
  *buffp++=16*4;

  *buffp++=xlo;
  *buffp++=ylo;
  *buffp++=xhi;
  *buffp++=yhi;

  *buffp++=fontfcolour; /* colour */
  *buffp++=fontbcolour; /* background */
  *buffp++=1;           /* font */
  *buffp++=cpfx;        /* x font size */
  *buffp++=cpy;         /* y font size */

  *buffp++=x;
  *buffp++=y;

  *buffp++=0;           /* zero len string */

  xhi=xlo=x;
  ylo=y-cpy;
  yhi=y+cpy;

  textlen=0;

  diag->length+=13*4;
 }
}




void vecsym(int x,int y,int c,Draw_diag * diag)
{
 int * buffp;

 closedraw(diag);
 if(drawfoff && (x!=xhi || y!=(ylo+cpy))) closefont(diag);
 startfont(x,y,diag);

 buffp=(int*)(diag->data+diag->length);

 *(((char*)buffp)-4+(textlen & 0x3))=c;
 xhi+=cpx;
 textlen++;
 if(!(textlen & 0x3))
 {
  *buffp++=0;
  diag->length+=4;
 }
}








void vecfillcolour(int fillcolour,Draw_diag * diag,int offset)
{
 int * buffp;

 if(!diag->data || diag->length<=offset)
 {
  dprintf(0,"fill failed data=%x length=%d offset=%d",diag->data,
                                   diag->length,offset);
  return;
 }

 buffp=(int*)(diag->data+offset);

/* dprintf(0,"*buff=%d fill=%d offset=%d",*buffp,fillcolour,offset); */

 if(*buffp==2) *(buffp+6)=fillcolour;
 else
 {
  dprintf(0,"miss *buff=%d fill=%d offset=%d",*buffp,fillcolour);
 }
}


void vecthickness(int width)
{
 vthickness=width;
}



void doopen(Draw_diag * diag,int xsize,int ysize)
{
 int * buffp=(int*)diag->data;
 int * buff=buffp;
 int   fnlen;

 strcpy((char*)buffp,"Draw");
 buffp++;
 *buffp++=201;
 *buffp++=0;

 strcpy((char*)buffp,"CrossStar   ");
 buffp+=3;

 *buffp++=0;
 *buffp++=0;
 *buffp++=xsize;
 *buffp++=ysize;

 /* font table object */

 fnlen=strlen(fontname)+1;
 fnlen=(fnlen/sizeof(int))+((fnlen % sizeof(int))!=0);

 *buffp++=0;
 *buffp++=sizeof(int)*(2+fnlen);
 memset((char*)buffp,0,fnlen*sizeof(int));
 strcpy((char*)buffp,fontname);
 buffp+=fnlen;

 drawtoff=0;
 drawfoff=0;
 abended=0;

 drawheadersize=diag->length=(buffp-buff)*sizeof(int);
}


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


/* trash diag contents */

void cleardiag(Draw_diag * diag)
{
 diag->length=0;
}


/* create a diag */

void opendiag(Draw_diag * diag,int xsize,int ysize)
{
 diag->length=0;
 doopen(diag,xsize,ysize);
}



/* makes sure that a diag can be rendered */

void validdiag(Draw_diag * diag)
{
/* dprintf(1,"foff=%d toff=%d",drawfoff,drawtoff);  */

 flushdraw(diag);
 flushfont(diag);
}



/* terminates a diag */

void closediag(Draw_diag * diag)
{
 closedraw(diag);
 closefont(diag);
}





