/****************************************************************
*																																*
*	 Filename : PlotL2.c																					*
*																																*
*****************************************************************
*																																*
*		Comment : Level 2 von der Plotlibrary. Unterstützt die			*
*							alle Level 1 Funktionen ohne Open- und Closeplot.	*
*							Zusätzlich sind weitere Unterfunktionen dazu			*
*							gekommen wie die Liste zeigt.											*
*																																*
*			                    Funktionen														*
*	                        ==========														*
*																																*
*				delcurve()				löscht eine bestimmte Kurve						*
*				getsize()					berechnet die Grösse der Daten				*
*				valsize()					berechnet Anzahl Elemente							*
*				getdata()					generiert math. Kurve									*
*				getcurve()				alloziert Speicher für eine Kurve			*
*				calcdata()				berechnet die Daten aus math. Funk.		*
*				setminmax()				setzt neue Grenzen in plot						*
*				checkbound()			kontrolliert die Grenzen für != LIN		*
*				deldata()					löscht Kurve anhand id oder namen			*
*				setaxisname()			gibt einer Achse einen Namen					*
*				setunit()					setzt Achseneinheit										*
*				settitel()				setzt Graphiktitel										*
*				setcurvename()		setzt Kurvenname											*
*				setstring()				kopiert und setzt einen String				*
*				delstring()				löscht einen String										*
*				setvalue()				setzt Grenzwerte											*
*				getvalue()				holt aktuelle Grenzwerte							*
*				setautoval()			setzt auto. Grenzwertanpassung				*
*				setgrid()					setzt Gitterparameter									*
*				setfill()					setzt Musterparameter									*
*				setmes()					setzt Achsenmasstab										*
*				set3doptions()		legt 3D Ausgabe fest									*
*				setplotsize()			legt Plotterausgabe fest							*
*				setcurvecolor()		setzt Kurvenfarbe											*
*																																*
*				Rev : V1.0																							*
*																																*
*		History : V1.0 erstellen dieses Files							15/11/89	*
*																																*
*				Doc : Plotlibrary User's Guide													*
*																																*
*			 Bugs : keine bekannten																		*
*																																*
*			Autor : Oesch Silvano																			*
*																																*
*			Datum : 15/11/89																					*
*																																*
****************************************************************/

/****************************************************************
*																																*
*	Plotlibrary Includedateien																		*
*																																*
****************************************************************/

#include "Plot.h"
#include "PlotL2.h"
#include "GfxL3.h"
#include "OpClL2.h"

/****************************************************************
*																																*
*	externe Variablen																							*
*																																*
****************************************************************/

extern struct Plot *plot;
extern int plerr;

/****************************************************************
*																																*
*	Function : delcurve()																					*
*																																*
*****************************************************************
*																																*
*		 Input : curve																							*
*							struct Curve *curve																*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Loescht eine komplette Kurve aus der Liste der			*
*						 der aktiven Kurven. Der allozierte Speicher wird		*
*						 an das System zurückgegeben. Die Plotstruktur			*
*						 wird korrigiert.																		*
*																																*
****************************************************************/

static void delcurve(curve)
struct Curve *curve;
{
	dellist(curve);										/* lösche aus Liste					*/
	if (curve->val)
		free(curve->val);								/* vorhandene Daten löschen	*/
	if (curve->titel)
		free(curve->titel);							/* vorhandener Name löschen	*/
	free(curve);											/* Speicher freigeben				*/
	if (plot->first == NULL)					/* war es die  letzte ?			*/
	{																	/* Ja												*/
		if (plot->disp != NULL)					/* Bildschirm geöffnet ?		*/
			ScCloseGraphics();						/* dann schliessen					*/
		initplot();											/* plot initialisieren			*/
	}
	else															/* sonst										*/
		if (plot->autoval == AUTOON)		/* nur wenn gewünscht				*/
			setminmax();									/* refresh der plotstruktur	*/
}

/****************************************************************
*																																*
*	Function : getdata()																					*
*																																*
*****************************************************************
*																																*
*		 Input : function,xmin,xmax,count														*
*							(*function())			math. Berechnungsfunktion				*
*							int xmin					Startwert												*
*							int xmax					Endwert													*
*							int count					Anzahl zu berechnende Elemente	*
*																																*
*		Output : int returnset			ID der neuen Kurve							*
*							!= FALSE					neue ID													*
*							== FALSE					Fehler													*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion ist die zweite Stufe der Get_Data-	*
*						 funktion. Es wird eine Kurve mittels einer math.		*
*						 Funktion berechnet. Wenn die Funktion erfolgreich	*
*						 ausgeführt werden konnte, wird die neue Kurve			*
*						 zur Kurvenliste addiert. Ansonsten werden alle			*
*						 angeforderten Resourcen freigegeben.								*
*																																*
****************************************************************/

int getdata(function,xmin,xmax,count)
DATA (*function)(DATA);
DATA	xmin,
			xmax;
int		count;
{
	int returnset;										/* Rückgabewert							*/
	struct Curve *curve;							/* Kurvenzeiger							*/

	curve = getcurve(count);					/* alloziere Kurve count		*/
																		/* Datenfeldern							*/
	if ( curve == NULL)								/* Fehler ?									*/
		setreturn(FALSE);								/* Ja, zurück								*/
	else															/* sonst weiter							*/
	{

		curve->xmin = xmin;							/* initialisiere bestehende	*/
		curve->xmax = xmax;							/* Werte, sonst müssen sie	*/
		curve->count = count;						/* weiter gegeben werden		*/

		calcdata(curve,function);				/* berechne Datenelemente		*/
		addlist(curve);									/* füge zur liste und hole	*/
																		/* die ID										*/
		if (plot->autoval == AUTOON)		/* nur wenn gewünscht				*/
			setminmax();									/* Grenzen korrigieren			*/
		setreturn(curve->id);						/* ID als Rückgabewert			*/
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : getsize()																					*
*																																*
*****************************************************************
*																																*
*		 Input : count																							*
*							int count			Anzahl Datenelemente in der Kurve		*
*																																*
*		Output : int size				benötigte Bytes des Datenarrays			*
*																																*
*****************************************************************
*																																*
*	 Comment : Berechnet die benötigte Grösse in Bytes eines			*
*						 Datenfeldes. Der eingestellte Darstellungstyp			*
*						 wird berücksichtigt.																*
*																																*
****************************************************************/

int getsize(count)
int count;
{
	return((int)(sizeof(DATA)*count*valsize()));
}

/****************************************************************
*																																*
*	Function : valsize()																					*
*																																*
*****************************************************************
*																																*
*		 Input : void																								*
*																																*
*		Output : int returnset	Grösse des Sizefaktors							*
*							!= FALSE			alles klar													*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion Übergibt die Anzahl Datenelemente		*
*						 eines Datenpaares. Der eingestellte Kurventyp			*
*						 wird berücksichtigt.																*
*																																*
****************************************************************/

int valsize()
{
	int returnset;

	switch (plot->typ)									/* welcher Typ					*/
	{
		case D2:	setreturn(D2MULT);			/* 2 Datenfelder				*/
							break;
		case NIV:	setreturn(NIVMULT);			/* 2 Datenfelder				*/
							break;
		case D3:	setreturn(D3MULT);			/* 3 Datenfelder				*/
							break;
		default:	seterror (INVCURTYP);		/* kein gültiger Typ		*/
							setreturn(FALSE);				/* sofort zurück				*/
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : getcurve()																					*
*																																*
*****************************************************************
*																																*
*		 Input : count																							*
*							int count				Anzahl notwendiger Datenelemente	*
*																																*
*		Output : struct Curve *		Kurvenzeiger mit Array						*
*							* != NULL				komplette Kurve erstellt					*
*							* == NULL				Speicherfehler oder								*
*															falscher Typ in plot definiert		*
*																																*
*****************************************************************
*																																*
*	 Comment : Es wird eine komplette Kurvenstruktur alloziert.		*
*						 Wenn kein Speicher vorhanden für die Kurve oder 		*
*						 für die Daten ist, gibt es eine Fehler. Vorhandene	*
*						 Resourcen werden freigegeben. Die Daten werden in	*
*						 abhängigkeit des Types in der Plotstruktur					*
*						 alloziert. Es gibt einen Fehler wenn dieser Typ		*
*						 nicht definiert ist.																*
*						 Alle Werte der Struktur sind gelöscht!							*
*																																*
****************************************************************/

struct Curve *getcurve(count)
int count;
{
	int curvesize,										/* grösse der Kurve					*/
			valsize;											/* Grösse des Datenfeldes		*/
	struct Curve *curve,							/* Kurvenzeiger							*/
							 *returnset;					/* Rückgabewert							*/

	curvesize = sizeof(struct Curve);	/* Grösse bestimmen und 		*/
	curve = (struct Curve *)calloc(1,curvesize);
																		/* Speicher holen						*/
	if ( curve == FALSE)							/* bekommen ?								*/
	{																	/* Nein, Fehler							*/
		seterror(MEMGETDATA);
		setreturn (FALSE);
	}
	else															/* Ja, prüfe Type für				*/
	{																	/* berechnung des Daten-		*/
																		/* feldes										*/
		valsize = getsize(count);				/* hole Grösse							*/
		if (valsize == NULL)						/* ohne Fehler							*/
			setreturn(FALSE);							/* Nein											*/
		else
		{
			curve->val = (DATA *)malloc(valsize);
																		/* Speicher holen						*/
			if (curve->val == NULL)				/* bekommen ?								*/
			{															/* Nein !!									*/
				free(curve);								/* Kurvenspeicher freigeben	*/
				seterror(MEMGETDATA);				/* und Fehler setzten				*/
				setreturn (FALSE);
			}
			else													/* und sonst								*/
			{
				curve->maxcount = count;
																		/* init. maxcount						*/
				setreturn(curve);						/* mit Kurvenzeiger zurück	*/
			}
		}
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : calcdata()																					*
*																																*
*****************************************************************
*																																*
*		 Input : curve,function																			*
*							struct Curve *curve		Kurvenstruktur							*
*							DATA (*function)()		Funktionsadresse						*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Berechnet Kurvenwerte mithilfe einer								*
*						 mathematischen Funktion. Die Daten werden in ein		*
*						 Array geschrieben welches schon vorbereitet ist.		*
*						 Die minmaxwerte werden mit den ersten Daten				*
*						 gesetzt und danach kontrolliert gesetzt.						*
*																																*
****************************************************************/

static void calcdata(curve,function)
struct Curve *curve;
DATA (*function)(DATA);
{
	DATA	step,												/* Differenz zwischen x1,x2	*/
				x,													/* x Werte									*/
				y,													/* y Wert										*/
				*array=curve->val;					/* Feldzeiger initialisiert	*/
	int 	i,													/* counter									*/
				init=NULL;									/* switch initialisiert			*/

	step = (curve->xmax-curve->xmin)/(curve->count-1);
																		/* berechne Schrittweite		*/
	for (i=0;i<curve->count;i++)			/* für alle Felder					*/
	{
		x=curve->xmin+i*step;						/* x-Werte berechnet				*/

/****************************************************************
*	Dieser Wert könnte auch aufaddiert werden, die Rechnungs-			*
*	fehler werden dadurch aber immer grösser. Desshalb wird				*
*	x immer mit Start + step*counter berechnet.										*
****************************************************************/

		y=(*function)(x);								/* berechne y								*/
		*array++=x;											/* Schreibe Werte in Array	*/
		*array++=y;
		if (init)												/* Daten schon init ?				*/
		{
			if (curve->ymin > y)					/* ok, nur min und max			*/
				curve->ymin = y;						/* setzten									*/
			else if (curve->ymax < y)
				curve->ymax=y;
		}
		else														/* nein, also init. mit			*/
		{
			curve->ymin = curve->ymax = y;
																		/* ersten Werten die vor-		*/
																		/* handen.									*/
			init ++;											/* init switch setzten			*/
		}
	}
}

/****************************************************************
*																																*
*	Function : setminmax()																				*
*																																*
*****************************************************************
*																																*
*		 Input : void																								*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Setzt die min - maxparameter in der Plotstruktur		*
*						 anhand der minmax-Werte in den Kurvenstrukturen.		*
*						 Wenn kein automatisches setzten dieser Werte				*
*						 gewünscht wird, muss der autoval Parameter in der	*
*						 Plotstruktur gesetzt sein welche vor dem Aufruf		*
*						 dieser Funktion abgefragt werden muss.							*
*						 Der clippindikator wird gelöscht.									*
*																																*
****************************************************************/

void setminmax()
{
	struct Curve *curve = plot->first;
																		/* Kurvenstruktur auf erste	*/
																		/* Kurve initialisieren			*/
	if (curve)												/* wenn Kurve vorhanden			*/
	{
		plot->xmin = curve->xmin;				/* Werte auf erste Kurve		*/
		plot->xmax = curve->xmax;				/* setzten									*/
		plot->ymin = curve->ymin;
		plot->ymax = curve->ymax;
		plot->zmin = curve->zmin;
		plot->zmax = curve->zmax;
		curve = curve->next;						/* nächste Kurve nehmen			*/
	}

	while (curve != NULL)							/* alle vorhandenen Werte		*/
	{																	/* kontrollieren						*/
		if (plot->xmin > curve->xmin)		/* vergleichen und nur			*/
			plot->xmin = curve->xmin;			/* schreiben wenn not-			*/
		if (plot->xmax < curve->xmax)		/* wendig										*/
			plot->xmax = curve->xmax;
		if (plot->ymin > curve->ymin)
			plot->ymin = curve->ymin;
		if (plot->ymax < curve->ymax)
			plot->ymax = curve->ymax;
		if (plot->zmin > curve->zmin)
			plot->zmin = curve->zmin;
		if (plot->zmax < curve->zmax)
			plot->zmax = curve->zmax;
		curve = curve->next;						/* nächste Kurve nehmen			*/
	}
	plot->clipp = NOCLIPP;						/* kein Clipping mehr 			*/
																		/* notwendig								*/
	if (plot->xmes != LIN)						/* wenn nicht LIN kontr.		*/
		checkbound(&plot->xmin);
	if (plot->ymes != LIN)
		checkbound(&plot->ymin);
	if (plot->zmes != LIN)
		checkbound(&plot->zmin);

}

/****************************************************************
*																																*
*	Function : checkbound()																				*
*																																*
*****************************************************************
*																																*
*		 Input : min																								*
*							DATA *min				Pointer auf ersten Wert						*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Kontrolliert die log. Grenzen	auf ihre negativen	*																																*
*						 Werte. Wenn neg. Werte vorhanden sind, werden sie	*
*						 auf 1.0 bzw. 3 Dekaden tiefer gesetzt. Für diese		*
*						 Darstellung wird dann das Clipping benötigt.				*
*																																*
****************************************************************/

static void checkbound(min)
DATA *min;
{
	DATA *max = min+1,
			 maxvalue = 1.0;						/* max. Wert									*/

	if (*max <= 0.0)								/* max kleiner = NULL					*/
	{																/* Ja													*/
		*max = maxvalue;							/* dann neuer Wert setzten		*/
		plot->clipp = CLIPP;					/* Clipping notwendig	 				*/
	}

	if (*min <= 0.0)								/* min kleiner = NULL					*/
	{																/* Ja													*/
		*min = *max/1000;							/* dann neuer Wert setzten		*/
		plot->clipp = CLIPP;					/* Clipping notwendig	 				*/
	}
}

/****************************************************************
*																																*
*	Function : deldata()																					*
*																																*
*****************************************************************
*																																*
*		 Input : id,name																						*
*							int id				zu löschende Kurve mit ID						*
*							char *name		zu löschende Kurve mit Name					*
*																																*
*																																*
*		Output : int returnset																			*
*							!= FALSE			alles klar													*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Löscht eine komplette Kurve aus der Liste der			*
*						 der aktiven Kurven. Die allozierte Speicher wird		*
*						 an das System zurückgegeben.												*
*																																*
*						 Diese Funktion erfüllt 4 Optionen:									*
*																																*
*							- alle Kurven löschen															*
*							- letzte Kurve der Liste löschen									*
*							- Kurve mit ID löschen														*
*							- Kurve mit Namen löschen													*
*																																*
****************************************************************/

int deldata(id,name)
int id;
char *name;
{
	int returnset;										/* allg. Rückgabewert				*/
	struct Curve *curve;							/* Kurvenzeiger							*/

	switch (id)												/* welcher typ zum löschen	*/
	{
		case DELALL:
			while (plot->first != NULL)		/* solange Kurven vorhanden	*/
				delcurve(plot->first);			/* gib Kurven frei					*/
			setreturn(TRUE);							/* alles ok									*/
			break;

		case DELLAST:
			delcurve(plot->last);					/* gib Kurven frei					*/
			setreturn(TRUE);							/* alles ok									*/
			break;

		case NOID:
			curve = slistname(name);			/* suche Kurvenzeiger				*/
			if (curve == NULL)						/* gefunden									*/
				setreturn(FALSE);						/* Nein Fehler							*/
			else													/* Ja												*/
			{
				delcurve(curve);						/* lösche Kurve							*/
				setreturn(TRUE);						/* alles ok									*/
			}
			break;

		default:												/* irgend eine ID						*/
			curve = slistid(id);					/* suche Kurve							*/
			if (curve == NULL)						/* gefunden ?								*/
				setreturn(FALSE);						/* Nein Fehler							*/
			else													/* und sonst								*/
			{
				delcurve(curve);						/* löschen									*/
				setreturn(TRUE);						/* alles ok									*/
			}
			break;
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : setaxisname()																			*
*																																*
*****************************************************************
*																																*
*		 Input : axis,axisname																			*
*							int axis					Achsenid												*
*							char *axisname		neuer Achsenname								*
*																																*
*		Output : int returnset																			*
*							!= FALSE					alles ok												*
*							== FALSE					Fehler													*
*																																*
*****************************************************************
*																																*
*	 Comment : Setzt oder löscht einen AXNAMLEN (definiert in			*
*						 Plot.h) Zeichen grossen Titel welcher jeder				*
*						 Achse gegeben werden kann.													*
*						 In einen temp Variable wird die Adresse des				*
*						 enstrechenden Strings geladen. Danach wird die			*
*						 Lösch- oder Setzfunktion aufgerufen.								*
*																																*
****************************************************************/

setaxisname(axis,axisname)
int axis;
char *axisname;
{

	int returnset;										/* allg. Rückgabewert				*/
	char **temp;											/* Adr. von der Adresse			*/
																		/* des Strings							*/

	switch(axis)											/* welche Achse							*/
	{																	/* entsprechende Adresse		*/
		case XAXIS:											/* des Strings							*/
			temp = &plot->xname;
			break;
		case YAXIS:
			temp = &plot->yname;
			break;
		case ZAXIS:
			temp = &plot->zname;
			break;
		default:
			break;
	}
	if (axisname == NULL)							/* löschen ?								*/
		setreturn(delstring(temp));			/* Ja												*/
	else															/* sonst setzten						*/
		setreturn(setstring(temp,axisname,AXNAMLEN));

	return(returnset);
}

/****************************************************************
*																																*
*	Function : setunit()																					*
*																																*
*****************************************************************
*																																*
*		 Input : axis,unit																					*
*							int axis					Achsenid												*
*							char *unit				neuer Eiheitenname							*
*																																*
*		Output : int returnset																			*
*							!= FALSE					alles ok												*
*							== FALSE					Fehler													*
*																																*
*****************************************************************
*																																*
*	 Comment : Setzt oder löscht einen UNITLEN (definiert in			*
*						 Plot.h) Zeichen grossen Titel											*
*																																*
****************************************************************/

setunit(axis,unit)
int axis;
char *unit;
{

	int returnset;										/* allg. Rückgabewert				*/
	char **temp;											/* Adr. von der Adresse			*/
																		/* des Strings							*/

	switch(axis)											/* welche Achse							*/
	{																	/* entsprechende Adresse		*/
		case XAXIS:											/* des Strings							*/
			temp = &plot->xunit;
			break;
		case YAXIS:
			temp = &plot->yunit;
			break;
		case ZAXIS:
			temp = &plot->zunit;
			break;
		default:
			break;
	}
	if (unit == NULL)									/* löschen ?								*/
		setreturn(delstring(temp));			/* Ja												*/
	else															/* sonst setzten						*/
		setreturn(setstring(temp,unit,UNITLEN));

	return(returnset);
}

/****************************************************************
*																																*
*	Function : settitel()																					*
*																																*
*****************************************************************
*																																*
*		 Input : titel																							*
*							char *titel				neuer Graphikname								*
*																																*
*		Output : int returnset																			*
*							!= FALSE					alles ok												*
*							== FALSE					Fehler													*
*																																*
*****************************************************************
*																																*
*	 Comment : Setzt oder löscht einen TITELLEN (definiert in			*
*						 Plot.h) Zeichen grossen Titel											*
*																																*
****************************************************************/

settitel(titel)
char *titel;
{

	int returnset;										/* allg. Rückgabewert				*/
	char **temp;											/* Adr. von der Adresse			*/
																		/* des Strings							*/

	temp = &plot->titel;
	if (titel == NULL)								/* löschen ?								*/
		setreturn(delstring(temp));			/* Ja												*/
	else															/* sonst setzten						*/
		setreturn(setstring(temp,titel,TITELLEN));

	return(returnset);
}

/****************************************************************
*																																*
*	Function : setcurvename()																			*
*																																*
*****************************************************************
*																																*
*		 Input : id,name																						*
*							int id				id der Kurve												*
*							char *name		neuer Name der Kurve								*
*																																*
*		Output : int returnset																			*
*							!= FALSE			alles klar													*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Dies Funktion setzt oder löscht einen CURNAMLEN		*
*						 (definiert in Plot.h) grossen Kurvennamen.					*
*																																*
****************************************************************/

setcurvename(id,name)
int id;
char *name;
{
	int returnset;										/* allg Rückgabewert				*/
	char **temp;											/* Adr. von der Adresse			*/
																		/* des Strings							*/
	struct Curve *curve;							/* Kurvenzeiger							*/

	curve = slistid(id);							/* suche Kurve							*/
	if (curve == NULL)								/* gefunden ?								*/
		setreturn(FALSE);								/* Nein, Fehler							*/
	else
	{
		temp = &curve->titel;						/* Adresse von Stringzeiger	*/
		if (name == NULL)								/* löschen oder setzen ?		*/
			setreturn(delstring(temp));		/* löschen									*/
		else
			setreturn(setstring(temp,name,CURNAMLEN));
																		/* setzen										*/
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : setstring()																				*
*																																*
*****************************************************************
*																																*
*		 Input : string,name,maxlen																	*
*							char **string			Zeiger auf einen Stringzeiger		*
*							char *name				Stringzeiger										*
*							int maxlen				max. Stringlänge								*
*																																*
*		Output : int returnset																			*
*							!= FALSE					alles klar											*
*							== FALSE					Fehler													*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion kopiert den String name und setzt		*
*						 die neue Adresse an die Stelle, wohin string				*
*						 zeigt. Der String name wird jedoch auf die					*
*						 maximale Länge kontrolliert.												*
*																																*
****************************************************************/

static int setstring(string,name,maxlen)
char **string,
		 *name;
int maxlen;
{
	int returnset,										/* allg Rückgabewert				*/
			namlen;												/* stringlänge							*/
	char *newname;										/* neue Speicheradresse			*/

	if (*string != NULL)
	{
		seterror(STRALLSET);
		setreturn(FALSE);
	}
	else
	{
		namlen = strlen(name);					/* berechne Länge						*/
		if (namlen > maxlen)						/* grösser als maxlen				*/
		{																/* Ja Fehler								*/
			seterror(NAMTOBIG);
			setreturn(FALSE);
		}
		else														/* also kopiere							*/
		{
			newname = malloc(namlen+1);		/* länge + 1 holen					*/
			if (newname == NULL)					/* bekommen									*/
			{
				seterror(NOMEMNAM);					/* Nein, Fehler							*/
				setreturn(FALSE);
			}
			else													/* kopiere String						*/
			{
				*string = strcpy(newname,name);
				setreturn(TRUE);						/* alles ok									*/
			}
		}
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : delstring()																				*
*																																*
*****************************************************************
*																																*
*		 Input : string																							*
*							char **string				Zeiger auf Stringzeiger				*
*																																*
*		Output : int returnset																			*
*							!= FALSE						alles klar										*
*							== FALSE						Fehler												*
*																																*
*****************************************************************
*																																*
*	 Comment : Löscht einen String welcher an der Adresse string	*
*						 referenziert ist.																	*
*																																*
****************************************************************/

int delstring(string)
char **string;
{
	int returnset;										/* allg Rückgabewert				*/

	if (*string == NULL)							/* ist String vorhanden			*/
	{
		seterror(NONAMGIV);							/* Nein, Fehler							*/
		setreturn(FALSE);
	}
	else									
	{
		free(*string);									/* gib Speicher frei				*/
		*string = NULL;									/* und setzte auf NULL			*/
		setreturn(TRUE);								/* alles klar								*/
	}
	return(returnset);
}

/****************************************************************
*																																*
*	Function : setvalue()																					*
*																																*
*****************************************************************
*																																*
*		 Input : typ,value																					*
*							int typ				Funktionsauswahl										*
*							DATA value    neuer Wert													*
*																																*
*		Output : int returnset																			*
*							!= FALSE    	alles klar													*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setze oder löscht die Darstellungs-	*
*						 grenzen welche vom User gewählt wurden.						*
*						 Beim setzten wird wird eine Überlappung der Werte	*
*						 z.Bsp. xmin > xmax kontroliert und ein Fehler			*
*						 Fehler gestzt.																			*
*																																*
****************************************************************/

int setvalue(typ,value)
int typ;
DATA value;
{

	int returnset;										/* allg Rückgabewert				*/
	DATA *min,*max;										/* Adr von Datenpaar				*/

	if (typ == CLEAR)									/* CLEAR gesetzt ?					*/
	{
		setminmax();										/* Ja, neu setzten					*/
		setreturn(TRUE);								/* alles klar								*/
	}
	else															/* also nicht CLEAR					*/
	{
		switch (typ/2*2)								/* berechne typ von min			*/
		{																/* Weise Adr. von min zu		*/
			case XMIN: min = &plot->xmin;
				break;
			case YMIN: min = &plot->ymin;
				break;
			case ZMIN: min = &plot->zmin;
				break;
		}
		max = min+1;										/* max Daten 1 Elem höher		*/

/****************************************************************
*																																*
*	Folgende Bedingung muss für ein erfolgreiches setzten der			*
*	minimalen Datenwerte erfüllt sein:														*
*																																*
*		-	der neue Wert darf nicht grösser sein als der gesetzte		*
*			max Wert des Wertepaares.																	*
*																																*
*	Wenn der neue Wert kleiner ist als der minimale Wert, so wird	*
*	der Clipping indikator gesetzt. Bei der Darstellung der Kurve	*
*	wird dieser Indikator getestet ob ein Clipping notwendig ist.	*
*	Der Clipping Indikator wird nur in der setminmax Funktion			*
*	zurückgesetzt.																								*
*																																*
*	Für die max. Werte gelten die gleichen umgekehrten						*
*	Bedingungen.																									*
*																																*
****************************************************************/

		switch(typ)											/* welcher Typ							*/
		{
			case XMIN:										/* alle min Werte						*/
			case YMIN:
			case ZMIN:
			if (value >= *max)						/* value grösser= als max ?	*/
			{															/* Ja												*/
				seterror(VALTOHIGH);				/* Fehler										*/
				setreturn(FALSE);
			}
			else													/* Nein											*/
			{
				if (value > *min)						/* value grösser als min ?	*/
					plot->clipp = CLIPP;			/* Ja, clippen notwendig		*/
				*min = value;								/* neuer min Wert zuweisen	*/
				setreturn(TRUE);						/* alles klar								*/
			}
			break;
	
			case XMAX:										/* alle max Werte						*/
			case YMAX:
			case ZMAX:
				if (value <= *min)					/* value kleiner= als min ?	*/
			{															/* Ja												*/
					seterror(VALTOLOW);				/* Fehler										*/
					setreturn(FALSE);
				}
				else												/* Nein											*/
				{
				if (value < *max)						/* value kleiner als max ?	*/
						plot->clipp = CLIPP;		/* Ja, clippen notwendig		*/
					*max = value;							/* neuer max Wert zuweisen	*/
					setreturn(TRUE);					/* alles klar								*/
				}
				break;

			default:											/* falscher Parameter				*/
				seterror(PARASEVAL);				/* Fehler										*/
				setreturn(FALSE);
				break;
		}
	}

	return(returnset);								/* und zurück								*/
}

/****************************************************************
*																																*
*	Function : getvalue()																					*
*																																*
*****************************************************************
*																																*
*		 Input : typ,value																					*
*							int typ				Funktionsauswahl										*
*							DATA *value   neuer Wert													*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt die Variable value auf den		*
*						 gewünschten aktuellen Grenzwert.										*
*																																*
****************************************************************/

void getvalue(typ,value)
int typ;
DATA *value;
{

	DATA *min,*max;										/* Adr von Datenpaar				*/

		switch (typ/2*2)								/* berechne typ von min			*/
		{																/* Weise Adr. von min zu		*/
			case XMIN: min = &plot->xmin;
				break;
			case YMIN: min = &plot->ymin;
				break;
			case ZMIN: min = &plot->zmin;
				break;
		}
		max = min+1;										/* max Daten 1 Elem höher		*/

		switch(typ)											/* welcher Typ							*/
		{
			case XMIN:										/* alle min Werte						*/
			case YMIN:
			case ZMIN:
				*value = *min;							/* min Wert zuweisen				*/
				break;
	
			case XMAX:										/* alle max Werte						*/
			case YMAX:
			case ZMAX:
				*value = *max;							/* max Wert zuweisen				*/
				break;

		}
}

/****************************************************************
*																																*
*	Function : setautoval()																				*
*																																*
*****************************************************************
*																																*
*		 Input : para																								*
*							int para				Autovalparameter									*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Setzt den Autovalparameter. Wenn AUTOON gesetzt		*
*						 wird, dann werden alle minimalen und maximalen			*
*						 automatisch nach jeder Lade- oder Rechenfunktion		*
*						 neu gesetzt.																				*
*																																*
****************************************************************/

void setautoval(para)
int para;
{

	if (para == AUTOON)								/* Wenn AUTOON							*/
	{
		plot->autoval = AUTOON;					/* dann setzten und					*/
		setminmax();										/* neue Werte berechnen			*/
	}
	else															/* sonst										*/
	{
		plot->autoval = AUTOOFF;				/* AUTOOFF setzten					*/
		plot->clipp = CLIPP;						/* Clipping notwendig				*/
	}
}

/****************************************************************
*																																*
*	Function : setgrid()																					*
*																																*
*****************************************************************
*																																*
*		 Input : typ																								*
*							int typ			Gitterparameter												*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt den Gitterparameter in der		*
*						 Plotstruktur. Dieser Parameter wird erst bei der		*
*						 Ausgabe der Graphik abgefragt.											*
*																																*
****************************************************************/

void setgrid(typ)
int typ;
{

	if (typ == GRID)									/* wenn es GRID ist					*/
		plot->grid = GRID;							/* setzte GRID							*/
	else															/* sonst										*/
		plot->grid = NOGRID;						/* setzte NOGRID						*/

}

/****************************************************************
*																																*
*	Function : setfill()																					*
*																																*
*****************************************************************
*																																*
*		 Input : typ																								*
*							int typ			Musterparameter												*
*																																*
*		Output : void																								*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt den Musterparameter in der		*
*						 Plotstruktur. Dieser Parameter wird erst bei der		*
*						 Ausgabe der Graphik abgefragt.											*
*																																*
****************************************************************/

void setfill(typ)
int typ;
{

	if (typ == STYLE)									/* wenn es STYLE ist				*/
		plot->style = STYLE;						/* setzte STYLE							*/
	else															/* sonst										*/
		plot->style = NOSTYLE;					/* setzte NOSTYLE						*/

}

/****************************************************************
*																																*
*	Function : setmes()																						*
*																																*
*****************************************************************
*																																*
*		 Input : axis,typ																						*
*							int axis			Achsenidentifikation								*
*							int typ				Masstabparameter										*
*																																*
*		Output : int returnset	allg Rückgabewert										*
*							!= FALSE    	alles klar													*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt bei der axis den							*
*						 angegebenen typ. Dieser typ wird erst bei dem			*
*						 Aufbau der Ausgabe abgefragt. Für die LOG oder LN	*
*						 Darstellung sind Werte kleiner gleich NULL 				*
*						 erlaubt. Sie werden jedoch bei der Darstellung			*
*						 abgeschnitten. Der minimale Wert wird auf 0.1			*
*						 gesetzt wenn er <= NULL ist. Wenn der maximale 		*
*						 auch <= NULL ist, wird dieser auf 1 gesetzt. Diese	*
*						 können nachträglich verändert werden.							*
*																																*
****************************************************************/

int setmes(axis,typ)
int axis;
int typ;
{

	DATA *min;

	switch(axis)											/* welche Achse							*/
	{
		case XAXIS:											/* x - Achse								*/
			plot->xmes = typ;							/* setzte typ								*/
			min = &plot->xmin;
			break;
		case YAXIS:											/* y - Achse								*/
			plot->ymes = typ;							/* setzte typ								*/
			min = &plot->ymin;
			break;
		case ZAXIS:											/* z - Achse								*/
			plot->zmes = typ;							/* setzte typ								*/
			min = &plot->zmin;
			break;
	}

	if (typ != LIN)										/* wenn nicht LIN						*/
		checkbound(min);								/* auf jedenfall Grenzen		*/
																		/* kontrollieren						*/
	else if (plot->autoval == AUTOON)	/* oder wenn autoval				*/
		setminmax();										/* kontr. Grenzen						*/
	return(TRUE);
}

/****************************************************************
*																																*
*	Function : set3doptions()																			*
*																																*
*****************************************************************
*																																*
*		 Input : typ																								*
*							int typ				Darstellungsparameter								*
*																																*
*		Output : int returnset	allg Rückgabewert										*
*							!= FALSE    	alles klar													*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt für die 3D Darstellung				*
*						 das Crosshatching und die Hiddenlines.							*
*																																*
****************************************************************/

int set3doptions(typ)
int typ;
{

	int returnset = TRUE;

	if (typ & CROSHON)								/* Crosshatching ein			*/
	{
		plot->d3opt |= CROSH;
		typ &= ~CROSHON;
	}
	else if (typ & CROSHOFF)					/* Crosshatching aus			*/
	{
		plot->d3opt &= ~CROSH;
		typ &= ~CROSHOFF;
	}

	if (typ & HIDDENON)								/* Hiddenline ein					*/
	{
		plot->d3opt |= HIDDEN;
		typ &= ~HIDDENON;
	}
	else if (typ & HIDDENOFF)					/* Hiddenline aus					*/
	{
		plot->d3opt &= ~HIDDEN;
		typ &= ~HIDDENOFF;
	}
	if (typ)													/* Optionen vorhanden			*/
	{																	/* Ja, Fehler							*/
		setreturn(FALSE);
		seterror(PARA3DOPT);
	}
	return(returnset);

}

/****************************************************************
*																																*
*	Function : setcurvecolor()																		*
*																																*
*****************************************************************
*																																*
*		 Input : id,name,color																			*
*							int id				id der gesuchten Kurve							*
*							char *name		name der gesuchten Kurve						*
*							int color			Farbe der Kurve											*
*																																*
*		Output : int returnset																			*
*							!= FALSE    	alle klar														*
*							== FALSE			Fehler															*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt bei einer Kurve eine					*
*						 bestimmte Farbe.																		*
*																																*
****************************************************************/

int setcurvecolor(id,name,color)
int id;
char *name;
int color;
{

	int returnset;										/* allg Rückgabewert				*/
	struct Curve *curve;							/* Kurvenzeiger							*/

		if (id == NOID)									/* keine ID, also Namen			*/
		{
			curve = slistname(name);			/* suche Kurvenzeiger				*/
			if (curve == NULL)						/* gefunden									*/
				setreturn(FALSE);						/* Nein Fehler							*/
			else													/* Ja												*/
			{
				curve->color = color;				/* setzte Farbe							*/
				setreturn(TRUE);						/* alles ok									*/
			}
		}
		else
		{
			curve = slistid(id);					/* suche Kurve							*/
			if (curve == NULL)						/* gefunden ?								*/
				setreturn(FALSE);						/* Nein Fehler							*/
			else													/* und sonst								*/
			{
				curve->color = color;				/* setzte Farbe							*/
				setreturn(TRUE);						/* alles ok									*/
			}
		}
	return(returnset);								/* und zurück								*/
}

/****************************************************************
*																																*
*	Function : setplotsize()																			*
*																																*
*****************************************************************
*																																*
*		 Input : x,y,xsize,ysize,attr,name													*
*							int x						Start von rechten Rand						*
*							int y						Start von oberem Rand							*
*							int xsize				Länge der Ausgabe									*
*							int ysize				Höhe der Ausgabe									*
*							int attr				Ausgabeattribute									*
*							char *name			Ausgabedatei											*
*																																*
*		Output : int returnset																			*
*							!= FALSE 				alle klar													*
*							== FALSE				Fehler														*
*																																*
*****************************************************************
*																																*
*	 Comment : Diese Funktion setzt alle Paremter für die Ausgabe	*
*						 einer Graphik auf einen Plotter. Der Name wird wie	*
*						 normal kopiert und gesetzt. Die Abfrage dieser			*
*						 Parameter wird erst im Level 3 bei der Plotausgabe	*
*						 gemacht.																						*
*																																*
****************************************************************/

int setplotsize(x,y,xsize,ysize,attr,name)
int x,
		y,
		xsize,
		ysize,
		attr;
char *name;
{

	int returnset;										/* allg. Rückgabewert				*/

	plot->xout = x;										/* Start rechter Rand				*/
	plot->yout = y;										/* Start oberer Rand				*/
	plot->xlength = xsize;						/* Länge										*/
	plot->ylength = ysize;						/* Höhe											*/
	plot->pldisp = attr;							/* Plotterattribute					*/
	if (name)													/* Nur wenn name gegeben		*/
	{
		if (plot->outname)							/* Wenn name vorhanden dann	*/
			delstring(&plot->outname);		/* dann löschen							*/
		setreturn(setstring(&plot->outname,name,80));
	}																	/* und name setzten					*/
	if (returnset)
		plot->pldisp |= PLDATASET;			/* Daten gesetzt						*/
	return(returnset);
}

