/*
	repdlin.c

	Copyright (C) 1992 Markus M. Nick

	---------------------------------------------------------------

	This program is distributed in the hope that it will be useful, 
	but WITHOUT ANY WARRANTY; without even the implied warranty of 
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
	documentation `docs\ruby.tex' for more details.

	---------------------------------------------------------------

	Dash Lines '--------' in Mens (auch Popup-Mens) durch richtige 
	Striche ersetzen.
	
	Schnittstellen:
		void install_dash_lines_stuff()
			installiert das Zeug als "Ruby-Hook"

	Dieser Source ist Teil von Ruby.  Ruby ist Freeware. Es gelten 
	die in der Dokumentation `docs\ruby.tex' aufgefhrten 
	Lizenzbedingungen.

	Autoren:		Markus M. Nick
		
	History:
	04.04.92 mmn v1.0	got started...
*/

#define __REPLDLIN__	1
#include <stddef.h>
#include <stdlib.h>
#include <aes.h>
#include <vdi.h>
#include <tos.h>
#include "portab.h"
#include "ruby.h"
#include "stuff.h"

#include "sav_regs.h"


/* == declarations == */

/* die Ruby-Hook-Funktion selbst */
static BOOLEAN dash_lines_hook _((OBJECT *tree, int obj));


/* Der alte Wert von RUBY_HOOK.  Wir bilden eine Kette a la XBRA beim 
	Trap-Verbiegen.  Damit kann man ohne besonderen Aufwand beliebig viele 
	"Ruby-Hooks" einh„ngen. */
static RUBY_HOOK old_ruby_hook;


/* == Installationsfunktion == */

void install_dash_lines_hook()
{
	/* replace_dash_lines() als "Ruby-Hook" installieren */
	old_ruby_hook = ruby_hook;		/* alten Hook fr's Durchhangeln merken */
	ruby_hook = dash_lines_hook;	/* und unseren als neuen eintragen */
}


/* == some static declarations == */

static BOOLEAN is_dash_line _((char *obj_text));
static int cdecl draw_dash_line _((PARMBLK *paramblk));


/* == implementations == */

static int cdecl draw_dash_line(paramblk)
PARMBLK *paramblk;
{
	static int mcl_new_state;	/* `static' und ohne Initialisierung!! */
	/*
		Zeichnen der Linie in der St„rke 2.
		Das Disablen bernimmt das AES.
	 */
	save_regs();	
		/* vor save_regs() drfen keine lokalen `auto'-Variablen 
			deklarieren, da sonst Registerinhalte zerst”rt werden 
			k”nnen! */
	{	
		int mcl_points[8];
		mcl_new_state = paramblk->pb_currstate;
		
		/* fr Clipping sorgen */
		clip_start(paramblk->pb_xc, paramblk->pb_yc, paramblk->pb_wc, paramblk->pb_hc);
		/* ^- mit vs_clip() alleine kommt `ruby_popup()' v”llig 
			durcheinander */

		/* Zeichnen... */	
		vswr_mode(lib_handle, 1);	/* replace */
		vsl_color(lib_handle, 1);	/* black */
		vsl_type(lib_handle, 1);
		vsl_ends(lib_handle, 0, 0);
		vsl_width(lib_handle, 1);

		/* line		(0,1) ------ (2,3)
					(6,7) ------ (4,5)	*/
		mcl_points[0] = paramblk->pb_x;
		mcl_points[1] = paramblk->pb_y + paramblk->pb_h/2 - 1;	/* "- 1" nach dl, 04/10/92 */
		mcl_points[2] = mcl_points[0] + paramblk->pb_w;
		mcl_points[3] = mcl_points[1];
		mcl_points[4] = mcl_points[2];
		mcl_points[5] = mcl_points[3] + 1;
		mcl_points[6] = mcl_points[0];
		mcl_points[7] = mcl_points[1] + 1;
		v_pline(lib_handle, 4, mcl_points);

		/* ursprngliches Clipping wiederherstellen */
		clip_end();
	}

	/* return_restore_regs() muž unbedingt im „užersten Scope aufgerufen 
		werden!  Der Aufruf ist zwingend, um die Register wiederherzustellen, 
		damit das AES "keine Krise kriegt" */
	return_restore_regs(mcl_new_state);		/* the AES disables the line */
}


static BOOLEAN is_dash_line(obj_text)
char *obj_text;
{
	/* prfen, ob der String nur Dashs enth„lt */
	while (*obj_text++ == '-');
	return (obj_text[-1] == '\0');
}


static BOOLEAN dash_lines_hook(tree, obj)
OBJECT *tree;
int obj;
{
	/*
		Im bergebenen OBJECT-Baum (Men-Baum) '------'-G_STRINGs durch
		unsere hbschere Variante ersetzen.
	 */
	OBJECT *that = &tree[obj];
	unsigned char ub_type = that->ob_type;
	unsigned char Xob_type = (unsigned)that->ob_type >> 8;

	switch (tree[obj].ob_type) {
	case G_STRING:
		if ((that->ob_state & DISABLED) && is_dash_line(that->ob_spec.free_string)) {
			RUBY_USERBLK *p_ruby_userblk = install_ruby_userblk(tree, obj, tree[obj].ob_type);
			p_ruby_userblk->ub_code = draw_dash_line;

			/* LTMF should ignore it! (might be important!) */
			that->ob_flags |= LX_LTMFIGNR;

			/* ruby() mit TRUE anzeigen, daž wir schon alles erledigt haben 
				und Ruby beruhigt zum n„chsten Index weitergehen kann. */
			return TRUE;
		}
	}

	return !!old_ruby_hook && (*old_ruby_hook)(tree, obj);
		/* wenn noch ein Hook in der Kette ist, diesen anspringen 
			oder ruby() soll sich d'rum kmmern... */
}


/* -eof- */
