//				TEXTOUT.CPP

#include <windows.h>

#include "textout.h"
#include "dasm.h"

int lastline=0;
int firstline=0;
int firstchar=0;
BOOL addedlines=FALSE;
char *MainBuff[MAX_PAGES];
char hdr[] =";             Created by Borg Disassembler\r\n";
char hdr2[]=";                   written by Cronos\r\n";

void DumpToFile(HWND hwnd,char *filename)
{ SECURITY_ATTRIBUTES securityatt;
  HANDLE efile;
  DWORD num;
  int i;
  int page,pageline;
  securityatt.nLength=sizeof(SECURITY_ATTRIBUTES);
  securityatt.lpSecurityDescriptor=NULL;
  securityatt.bInheritHandle=FALSE;
  efile=CreateFile(filename,GENERIC_WRITE,0,&securityatt,CREATE_NEW,0,NULL);
  if(efile==INVALID_HANDLE_VALUE)
  { MessageBox(hwnd,"File Creation Failed","Borg Disassembler Alert",MB_OK);
	 return;
  }
  WriteFile(efile,hdr,strlen(hdr),&num,NULL);
  WriteFile(efile,hdr2,strlen(hdr2),&num,NULL);
  WriteFile(efile,"\r\n",2,&num,NULL);
  for(i=0;i<lastline;i++)
  { page=i/MAX_LINES;
	 pageline=i-page*MAX_LINES;
	 WriteFile(efile,MainBuff[page]+pageline*MAXLINELEN,
		 strlen(MainBuff[page]+pageline*MAXLINELEN),&num,NULL);
	 WriteFile(efile,"\r\n",2,&num,NULL);
  }
  CloseHandle(efile);
}

void DeleteBuff(void)
{ int page,pageline;
  int i;
  page=lastline/MAX_LINES;
  pageline=lastline-page*MAX_LINES;
  for(i=0;i<page;i++)
  { if(MainBuff[i]!=NULL)free(MainBuff[i]);
	 MainBuff[i]=NULL;
  }
  if(pageline)free(MainBuff[page]);
}

void PrintBuff(char *szFormat,...)
{ int page;
  int pageline;
  EnterCriticalSection(&cs);
  page=lastline/MAX_LINES;
  pageline=lastline-page*MAX_LINES;
  va_list vaArgs;
  va_start(vaArgs,szFormat);
  if(!pageline)
  { MainBuff[page]=(char *)malloc(MAX_LINES*MAXLINELEN+50);
  }
  { wvsprintf(MainBuff[page]+pageline*MAXLINELEN,szFormat,vaArgs);
	 lastline++;
  }
  va_end(vaArgs);
  addedlines=TRUE;
  LeaveCriticalSection(&cs);
}

void LastPrintBuffEpos(UINT xpos)
{ int i;
  int page;
  int pageline;
  EnterCriticalSection(&cs);
  page=(lastline-1)/MAX_LINES;
  pageline=(lastline-1)-page*MAX_LINES;
  i=strlen(MainBuff[page]+pageline*MAXLINELEN);
  while(i<xpos)
  { (MainBuff[page])[pageline*MAXLINELEN+i]=' ';
	 (MainBuff[page])[pageline*MAXLINELEN+i+1]=0;
	 i++;
  }
  LeaveCriticalSection(&cs);
}

void LastPrintBuff(char *szFormat,...)
{ int page,mchar,pchar;
  int pageline;
  char tbuff[1000];
  EnterCriticalSection(&cs);
  va_list vaArgs;
  va_start(vaArgs,szFormat);
  page=(lastline-1)/MAX_LINES;
  pageline=(lastline-1)-page*MAX_LINES;
  pchar=strlen(MainBuff[page]+pageline*MAXLINELEN);
  mchar=pchar+wvsprintf(MainBuff[page]+pageline*MAXLINELEN+strlen(MainBuff[page]+pageline*MAXLINELEN)
	 ,szFormat,vaArgs);
  if(mchar>MAXLINELEN)
  { lstrcpy(tbuff,MainBuff[page]+(pageline+1)*MAXLINELEN-1);
	 (MainBuff[page]+(pageline+1)*MAXLINELEN-1)[0]=0;
  }
  va_end(vaArgs);
  addedlines=TRUE;
  LeaveCriticalSection(&cs);
  if(mchar>MAXLINELEN)
  { PrintBuff(";");
    if(pchar>60)pchar=60;
	 LastPrintBuffEpos(pchar);
	 LastPrintBuff("%s",tbuff);
  }
}

void DoPaint(HWND hWnd,int cxChar,int cyChar)
{
  HDC         hDC;   // handle for the display device
  PAINTSTRUCT ps;    // holds PAINT information
  UINT        nI;
  RECT rRect;
  UINT nScreenRows;
  int page;
  int pageline;
  int yoffs;
  int startpt;

  EnterCriticalSection(&cs);
  memset(&ps, 0x00, sizeof(PAINTSTRUCT));
  hDC = BeginPaint(hWnd, &ps);
  // Included as the background is not a pure color
  SetBkMode(hDC, TRANSPARENT);
  SelectObject(hDC,GetStockObject(SYSTEM_FIXED_FONT));
  GetClientRect(hWnd,&rRect);
  nScreenRows = rRect.bottom/cyChar;
  ShowScrollBar (hWnd, SB_VERT, (nScreenRows<lastline));
  ShowScrollBar (hWnd, SB_HORZ, MAXLINELEN>(rRect.right/cxChar));
  if(processing)yoffs=cyChar;
  else yoffs=0;
  startpt=firstline;
  //if((yoffs)&&(firstline))startpt--;
  for(nI=startpt;(nI<lastline)&&(nI<firstline+100);nI++)
  { page=nI/MAX_LINES;
	 pageline=nI-page*MAX_LINES;
	 TabbedTextOut(hDC,2-firstchar*cxChar,(nI-firstline)*cyChar+yoffs,MainBuff[page]+pageline*MAXLINELEN,
		lstrlen(MainBuff[page]+pageline*MAXLINELEN),0,NULL,2-firstchar*cxChar);
  }
  // Inform Windows painting is complete
  EndPaint(hWnd,&ps);
  LeaveCriticalSection(&cs);
}


