/* $Revision Header *** Header built automatically - do not edit! ***********
 *
 *	(C) Copyright 1991 by Torsten Jürgeleit
 *
 *	Name .....: language.c
 *	Created ..: Thursday 19-Dec-91 20:21:06
 *	Revision .: 0
 *
 *	Date        Author                 Comment
 *	=========   ====================   ====================
 *	04-Jun-92   Torsten Jürgeleit      use raster for auto requester
 *	11-Apr-92   Torsten Jürgeleit      larger read and line buffer
 *	19-Dec-91   Torsten Jürgeleit      Created this file!
 *
 ****************************************************************************
 *
 *	Support routines for using texts of different languages for ISUP
 *	objects
 *
 * $Revision Header ********************************************************/

	/* Includes */

#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#ifdef AZTEC_C
#include <functions.h>   /* needed for Aztec C - prototypes and pragmas for all Amiga system functions */
#endif
#include <libraries/memwatch.h>   /* header file for memory debug link library (Fish 240) - AFTER functions.h */
#include <string.h>
#include "/requester/requester.h"
#include "/files/files.h"
#include "language.h"

	/* Defines */

#define LANGUAGE_FILE_READ_BUFFER_SIZE	10000
#define LANGUAGE_FILE_LINE_BUFFER_SIZE	1000
#define LANGUAGE_FILE_FLAGS		(TEXT_FILE_FLAG_TRIM_LINE | TEXT_FILE_FLAG_SKIP_COMMENTS | TEXT_FILE_FLAG_SKIP_EMPTY_LINES | TEXT_FILE_FLAG_LINE_CONTINUATION)

#define LANGUAGE_ERROR_REQ_TITLE	" Build Language Text Array "
#define LANGUAGE_ERROR_REQ_POS_TEXT	"_Continue"
#define LANGUAGE_ERROR_REQ_FLAGS	(AUTO_REQ_FLAG_BACK_FILL | AUTO_REQ_FLAG_TEXT_CENTER | AUTO_REQ_FLAG_TEXT_COLOR2 | AUTO_REQ_FLAG_HOTKEY | AUTO_REQ_FLAG_DRAW_RASTER)

	/* Statics */

STATIC BYTE invalid_msg[] = "Invalid";

	/* Build language text array by parsing given text file */

   BYTE **
build_language_text_array(BYTE *name, USHORT entries)
{
   BYTE *error = NULL;
   LONG arg;

   if (name && entries) {
      struct FileData  *fd;
      BYTE error_line[80];

      if (!(fd = open_text_file(name, LANGUAGE_FILE_READ_BUFFER_SIZE,
		    LANGUAGE_FILE_LINE_BUFFER_SIZE, LANGUAGE_FILE_FLAGS))) {
	 error = "Can't open language text file `%s'";
	 arg   = (LONG)name;
      } else {
         BYTE **text_array;

	 if (!(text_array = AllocMem((LONG)(sizeof(BYTE *) * (entries + 1)),
						      (LONG)MEMF_PUBLIC))) {
	    error = "Out of memory";
	 } else {
            BYTE   **array = text_array;
	    USHORT count;

	    /* Init text array entry count */
	    *array++ = (BYTE *)(LONG)entries;

	    /* Read text array entries from text file */
	    count = entries;
	    while (count && error == NULL) {
	       BYTE   *text;
	       USHORT len;

	       switch (read_text_line(fd)) {
		  case TEXT_FILE_STATUS_NORMAL :
		     text = fd->fd_Line;
		     len  = fd->fd_LineLen;
		     if (len < 2) {
			error = "Line %ld invalid";
			arg   = fd->fd_LineNum;
		     } else {

			/* Strip double quotes */
			if (*text++ != '"' || *(text + (len -= 2)) != '"') {
			   error = "Missing double quotes in line %ld";
			   arg   = fd->fd_LineNum;
			} else {
			   BYTE *ptr;

			   if (!(ptr = AllocMem((LONG)(len + 1),
						      (LONG)MEMF_PUBLIC))) {
			      error = "Out of memory";
			   } else {
			      strncpy(ptr, text, (size_t)len);
			      *(ptr + len) = '\0';
			      *array++     = ptr;
			      count--;
			   }
		        }
		     }
		     break;

		  case TEXT_FILE_STATUS_EOF :
		     error = "Too few entries (%ld)";
		     arg   = entries - count;
		     break;

		  case TEXT_FILE_ERROR_LINE_TOO_LONG :
		     error = "Line %ld too long";
		     arg   = fd->fd_LineNum;
		     break;

		  case TEXT_FILE_ERROR_NO_COMMENT_END :
		     error = "No comment end in line %ld";
		     arg   = fd->fd_LineNum;
		     break;

		  case TEXT_FILE_ERROR_READ_FAILED :
		     error = "Read failed";
		     break;
	       }
	    }
	    if (!error) {
	       close_text_file(fd);
	       return(text_array);
	    }
	    FreeMem(text_array, (LONG)(4 * (entries + 1)));
	 }
	 close_text_file(fd);
      }

      /* Display auto request with error message */
      sprintf(&error_line[0], error, arg);   /* private sprintf() !!! */
      auto_request(NULL, LANGUAGE_ERROR_REQ_TITLE, &error_line[0],
				  LANGUAGE_ERROR_REQ_POS_TEXT, NULL, 0L, 0L,
					    LANGUAGE_ERROR_REQ_FLAGS, NULL);
   }
   return(NULL);
}
	/* Get text from given language text array */

   BYTE *
get_language_text(BYTE *text, BYTE **text_array)
{
   BYTE *ptr = &invalid_msg[0];

   if (!text_array) {
      if (text) {
	 ptr = text;
      }
   } else {
      if ((ULONG)text > 0 && (ULONG)text <= (ULONG)*text_array) {
	 ptr = *(text_array + (ULONG)text);
      }
   }
   return(ptr);
}
	/* Free given language text array */

   VOID
free_language_text_array(BYTE **text_array)
{
   BYTE **array;

   if (array = text_array) {
      USHORT entries;

      if (entries = (USHORT)(LONG)*array++) {
	 USHORT i;

	 for (i = 0; i < entries; i++) {
	    BYTE *text = *array++;

	    FreeMem(text, (LONG)(strlen(text) + 1));
	 }
      }
      FreeMem(text_array, (LONG)(sizeof(BYTE *) * (entries + 1)));
   }
}
	/* Private sprintf() with RawDoFmt() from Exec */

#asm
;---------------------------------------------------------------------------
; Support macros
;---------------------------------------------------------------------------

PUSH	MACRO
	movem.l	\1,-(sp)
	ENDM

PULL	MACRO
	movem.l	(sp)+,\1
	ENDM

CALLSYS	MACRO
	XREF	_LVO\1
	jsr	_LVO\1(a6)
	ENDM

;---------------------------------------------------------------------------
; External definitions
;---------------------------------------------------------------------------

	XDEF	_sprintf

;---------------------------------------------------------------------------
; LONG sprintf(BYTE *buffer, BYTE *format, ...)
;---------------------------------------------------------------------------

_sprintf:
	PUSH	d7/a2-a6

	move.l	1*4+6*4(sp),a3		; a3 := output buffer ptr
	move.l	2*4+6*4(sp),a0		; a0 := format string ptr
	lea	3*4+6*4(sp),a1		; a1 := data ptr
	lea	put_char(pc),a2		; a2 := put character routine
	moveq	#0,d7			; d7 := character counter
	move.l	(4).w,a6		; a6 := exec ptr
	CALLSYS	RawDoFmt(a6)		; do format
	move.l	d7,d0			; d0 := character counter

	PULL	d7/a2-a6
	rts

	; --- put character routine for RawDoFmt
put_char:
	move.b	d0,(a3)+		; write character to output buffer
	addq.l	#1,d7			; increment character counter
	rts
#endasm
