/*
**	$Id: BTXService.hpp 1.4 1995/12/03 12:16:23 olsen Exp olsen $
**
**	:ts=4
*/

/*
 * Copyright © 1995 by Olaf Barthel, All Rights Reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software has not been validated by the ``Bundesamt fuer Zulassungen in
 * der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
 * must not be used for accessing the BTX-Network of the Telekom in Germany.
 *
 * Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
 * der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
 * am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
 */

#ifndef _BTXSERVICE_HPP
#define _BTXSERVICE_HPP 1

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

#include <stdio.h>
#include <stdarg.h>

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

class BTXService;

#ifndef _TYPES_HPP
#include "Types.hpp"
#endif

#ifndef _IOCHANNEL_HPP
#include "IOChannel.hpp"
#endif

#ifndef _BTXDISPLAY_HPP
#include "BTXDisplay.hpp"
#endif

#ifndef _APPLICATION_HPP
#include "Application.hpp"
#endif

#ifndef _FONT_H
#include "Font.h"
#endif

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

enum
{
	MODE_Unknown,
	MODE_3in4,
	MODE_8Bit
};

/* information stored at every character location */
struct screen_cell
{
	unsigned short	chr;
	unsigned short	attr;	   /* assigned attributes */
	unsigned short	mark;	   /* markers for each attribute */
	unsigned short	real;	   /* really displayed attributes (size !) */
	unsigned char	set;
	unsigned char	fg;
	unsigned char	bg;
};

struct terminal_status
{
	int cursorx, cursory;			/* cursor position (1 based)  */
	int cursor_on;
	int serialmode; 				/* 1=serial, 0=parallel 	  */
	int wrap;						/* wraparound ? 			  */
	int par_attr;					/* store all attributes 	  */
	int par_fg, par_bg;
	int G0123L[5];					/* which set is addressed by G0, ... */
	int leftright[2];				/* actual lower/upper character set  */
	int lastchar;
	int sshift;
	int save_left;					/* unload L set and invoke previous set  */
	int prim, supp; 				/* where is the prim set (service break) */
	int service_break;				/* (is the protect attr active ?)		 */
	int drcs_bits, drcs_step;
	int drcs_w, drcs_h;
	int col_modmap; 				/* modify 1:colormap, 0:DCLUT */
	int clut;						/* 0 based ! */
	int scroll_upper, scroll_lower;
	int scroll_impl, scroll_area;
	int hold_mosaic;
};

class BTXService
{
	public:

		BTXService();
		~BTXService();

		LONG Open(BTXDisplay *Disp,Application *Appl);
		VOID Close(VOID);

		int ProcessInput(VOID);

		UBYTE ConvertChar(int Char,int Set,int Diacritical_Mark);
		VOID GetMatrix(UBYTE *Matrix,int *CursorX,int *CursorY);

		VOID ToggleReveal(VOID);

		int rows, fontheight;				/* 20 rows(12 high) or 24 rows(10 high) */

	private:

		BTXDisplay 	*AppDisplay;
		Application	*App;

		struct screen_cell screen[24][40];	/* information for every character */
		int reachedEOF;
		struct terminal_status t,backup;	/* local terminal status */
		unsigned int pushback;				// can push up to four bytes back into the input stream
		UBYTE pushedback[4];				// bytes pushed back if any
		UBYTE data[4][2*FONT_HEIGHT];		/* local font definition */
		FILE *protocolfile;

		FILE *telefile;						// Telesoftware landet hier
		char telename[256];					// Name sollte lang genug sein
		long telesize;						// Länge der Datei
		char teledate[20];					// Datum, sofern vorhanden
		int telemode;						// Kodierung, entweder 3-in-4 oder 8-Bit
		int telesequence;					// Sequenznummer
		BOOL teledownload;					// True, falls Download erlaubt ist
		unsigned char telebuffer[3000];		// Blockpuffer

		int transparent_max;				// Wieviele Bytes noch, bis der transparente Modus
											// verlassen wird?
		int transparent_collected;			// Wieviele Bytes schon im Puffer stecken

		unsigned char transparent_buffer[256];	// Blockpuffer

		BOOL reveal;

		int transferTimeStamp;				// Der ganze andere Kram für FIF
		UWORD transferID;
		BOOL is_fif;
		int blockNumber,numberOfBlocks;
		char restartCode[40],continueCode[40];
		int restartLen,continueLen;
		UWORD blockChecksum;
		char fileName[256];
		char dateTime[16];
		ULONG fileLength;
		int fileCoding;
		char codingString[256];
		char userField[256];
		char destinationName[256];
		int compressionMode;
		ULONG fileChecksum;

		void init_layer6(void);
		int process_BTX_data(void);
		inline int layer2getc(void);
		inline void layer2ungetc(int c);
		void default_sets(void);
		void move_cursor(int cmd, int y=0, int x=0);
		int primary_control_C0(int c1);
		void supplementary_control_C1(int c1, int fullrow);
		void do_US(void);
		void do_ESC(void);
		int do_CSI(void);
		void do_DRCS(void);
		void do_DRCS_data(int c);
		void log_DRC(int c, int bits);
		void do_DEFCOLOR(void);
		void do_DEFFORMAT(void);
		void do_RESET(void);
		void do_Telesoftware(void);
		void set_attr(int a, int set, int col, int mode);
		void output(int c);
		void redrawc(int x, int y);
		void updatec(int real, int x, int y);
		void redraw_screen_rect(int x1, int y1, int x2, int y2);
		void update_DRCS_display(int start, int stop, int step);
		void clearscreen(void);
		void scroll(int up);
		void write(const STRPTR what,int len);
		int decode_3in4(const UBYTE *data,UBYTE *out,int total);
		void do_TransparentData(void);
		void do_FIF(void);

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

		int LZH_Decode(FILE *fi, FILE *fo, long filesize, ULONG *CRC_32);
		int RLE_Decode(FILE *fi,FILE *fo,long filesize,ULONG *CRC_32);
};

#endif	// _BTXSERVICE_HPP
