/*********************************************************************
	>>>>>  Prior.c   Prioritaeten-Routinen von `TaskDrive`.

	Autor: Rudolf Gierlinger   A - 4692 Niederthalheim 50

	Verwendung und Verbreitung fuer NICHTKOMMERZIELLEN Gebrauch
	erlaubt, solange der Autorenvermerk nicht geloescht wird !

						Dezember 1988
 *********************************************************************/
#include "Prior.H"

#define TASKNODE 		TaskPtr->tc_Node

struct StringInfo PriorStrg =
{ 	StrPuff,NULL,0,PUFLEN,0,0,0,0,
	0,0, 	/* Koord. */
	0,0L,NULL
};

/*=== FUNCTION  SuchNamen_inRRList ===*/
/* Durchsucht eine Taskliste, reserviert einen Speicherbereich für jeden Task
   und hinterlegt dort Informationen über diesen.

   GLOBAL EFFECT ON: Anzahl, EintrPtr[];
   ARGS:    DieseList ... Zeiger auf eine Liste (z.B. Waiting/Ready-Tasklist)
   RESULTS: - Anzahl wird entsprechend erhöht,
            - in EintrPtr[] (=ZeigerFeld) werden die Zeiger auf je eine
              Info-Struktur über jeden Task gestellt.
*/
VOID SuchNamen_inRRList(DieseList)
	struct List *DieseList;
{
	REGISTER 		int 	 i;
	struct Task 	 	*TaskPtr;
	struct TaskEintr 	*TmpPtr;

   for 	(TaskPtr = (struct Task *) (*DieseList).lh_Head;   /* Kopf der Liste */
	 TASKNODE.ln_Succ && (Anzahl < MAXEINTR);
	 TaskPtr = (struct Task *)TASKNODE.ln_Succ )
   {

	if (! (TmpPtr = (struct TaskEintr *)
			AllocMem(sizeof(struct TaskEintr),MEMF_PUBLIC) )
	   ) 	break;  /* kein Speicher; keine Registrierung. */

     /* TaskPtr als Kennummer zum Wiederfinden ! */
	TmpPtr->MyID  = TaskPtr;

	TmpPtr->Prior = TASKNODE.ln_Pri;
	strcpy (TmpPtr->PriPuff,PUFDEF);
	switch (TASKNODE.ln_Type)
	{	case NT_TASK: 	 TmpPtr->Typus="  Task "; break;
		case NT_PROCESS: TmpPtr->Typus=" Prozeß"; break;
		default:	 TmpPtr->Typus=" Zombie"; break;
	};

	for (i=0; i <= NAMLEN; i++) 	/* Namen kopieren */
		if ( (TmpPtr->Name[i] = TASKNODE.ln_Name[i]) == '\0' )
		   break; 		/* wenn Name < maxlen */

	for (;  i < NAMLEN; i++) 	/* mit Spaces auf NAMLEN auffüllen */
		TmpPtr->Name[i] = ' ';
	TmpPtr->Name[NAMLEN] = '\0'; 	/* und abschließen */

	EintrPtr[Anzahl] = TmpPtr;
	Anzahl++;

   }
}

/*=== FUNCTION  Aendere_Prior ===*/
/* Sucht den zu ändernden Task nochmal in der Liste, (Identifikation per
   Task-Struktur-Adresse) und ändert ev. dessen Priorität.
   Meldung, falls sich der Task schon verabschiedet hat.
   Benutzt von "PriorHandling" !

   ARGS:    TaskID   ... muß Adresse der Taskstruktur enthalten.
            NewPrior ... gewünschte neue Priorität.
   RESULTS: -
*/
VOID Aendere_Prior(TaskID,NewPrior)
	struct Task 	*TaskID;
	BYTE   		NewPrior;
{  
	struct Task 	*TaskPtr;
	BOOL 		Gefunden = FALSE;

 static struct IntuiText PosT = {GRUEN,SCHWARZ,JAM2,6,3,NULL," Schade um ihn. ",NULL};
 static struct IntuiText NegT = {SCHWARZ,0,JAM1,6,3,NULL,"Wie bitte ?",NULL};
 static struct IntuiText Unm1 = {GRUEN,0,JAM1,142,5,NULL,
				"Dieser Task wurde bereits beendet.",NULL};
 static struct IntuiText Unmoegl= {ROT,0,JAM1,170,18,NULL,
				"Bitte 'Aktuell!' anklicken!",&Unm1};

 Forbid(); 			/* WAIT-QUEUE durchsuchen */
   for 	(TaskPtr=(struct Task *) ExecBase->TaskWait.lh_Head;
	 TASKNODE.ln_Succ;
	 TaskPtr = (struct Task *)TASKNODE.ln_Succ)
     if (TaskID == TaskPtr) 	/* stimmt die TaskStructAdr? */
	{	SetTaskPri(TaskPtr,NewPrior);
		DisplayBeep(ScrPtr);
		Gefunden = TRUE;	
	}

   if (!Gefunden)
   { 				/* READY-QUEUE durchsuchen */
     for (TaskPtr=(struct Task *) ExecBase->TaskReady.lh_Head;
	  TASKNODE.ln_Succ;
	  TaskPtr = (struct Task *)TASKNODE.ln_Succ)
      if (TaskID == TaskPtr)
	{	SetTaskPri(TaskPtr,NewPrior);
		DisplayBeep(ScrPtr);
		Gefunden = TRUE;	
	}
   }
 Permit();

   if (!Gefunden)
     while(! AutoRequest(FenstPtr,&Unmoegl,&PosT,&NegT,NULL,NULL,540,49))
	; 			/* Benutzer hat 'wie bitte?' angeklickt. */
   else 			/* Int-Gadget-Struct aktualisieren */
     EintrPtr[Wahl]->Prior = (BYTE)PriorStrg.LongInt;

}

/*=== FUNCTION  PriorHandling ===*/
/* Aendert per Aufruf von Aendere_Prior die Prioritaet.
   Erledigt VORHER etliche Sicherheitsabfragen.
*/
VOID PriorHandling()
{	
	REGISTER LONG gInt; 	/* fuer Integer-Wert im Gadget */

 static struct IntuiText Life1= {ROT    ,0,JAM1,6,3,NULL,"Hollareituliööö",NULL};
 static struct IntuiText Life2= {SCHWARZ,0,JAM1,6,3,NULL," That's Life ",NULL};
 static struct IntuiText nErl2= {SCHWARZ,0,JAM1,40,20,NULL,
				"(nur -128..+127 möglich)",NULL};
 static struct IntuiText nErl1= {ROT,0,JAM1,48,7,NULL,
				"Priorität ist ZU HOCH !",&nErl2};

 static struct IntuiText Klar = {SCHWARZ,  0,JAM1,6,3,NULL,"Völlig",NULL};
 static struct IntuiText UnKlr= {ROT,SCHWARZ,JAM2,6,3,NULL," Ähh... Nein. ",NULL};
 static struct IntuiText Folg2= {SCHWARZ,0,JAM1,12,18,NULL,
				"so EXTREME PRIORITÄTEN verwendest",NULL};
 static struct IntuiText Folg1= {SCHWARZ,0,JAM1,12,7,NULL,
				"Sind dir die Folgen klar, wenn du",&Folg2};

 static struct IntuiText Aend  = {SCHWARZ,  0,JAM1,6,3,NULL," Ja. ",NULL};
 static struct IntuiText nAend = {ROT,SCHWARZ,JAM2,6,3,NULL," NEIN! ",NULL};
 static struct IntuiText PriAeTx2={ROT,0,JAM1,170,18,NULL,"Priorität ?",NULL};
 static struct IntuiText PriAeTxt={ROT,0,JAM1,195, 6,NULL,"Neue",&PriAeTx2};

   gInt = PriorStrg.LongInt;
  /* neue Prior == alte; Aendern nicht noetig */
   if (gInt == EintrPtr[Wahl]->Prior) return;

   if ( (gInt>127) || (gInt<-128) )
		AutoRequest(FenstPtr,&nErl1,&Life1,&Life2,NULL,NULL,313,65);
   else 
	#define AET_LEN  7+PUFLEN+1/*fuer 1Space*/
	#define NAE_LEN 13+PUFLEN
   {	char 	AeTx[AET_LEN], 	/* Ja, ja strcat braucht unbedingt */
		nAeTx[NAE_LEN], /* einen ausreichenden  Zielstring */
		Puf[NAE_LEN];

	if ( (gInt>4) || (gInt<-4) )
	   if  (AutoRequest(FenstPtr,&Folg1,&UnKlr,&Klar,NULL,NULL,313,65))
		return; 	/* Folgen sind dem Anwender unklar. */

	strcpy(AeTx ," Neu: ");
	strcpy(nAeTx," wie bisher ");

		sprintf(Puf,"%3.3d",gInt);
		strcat(AeTx,Puf);
	Aend .IText = 			/* 'Neu:' */
		strcat(AeTx," ");
		sprintf(Puf,"%3.3d",EintrPtr[Wahl]->Prior);
	nAend.IText = 			/* 'wie bisher' */
		strcat(Puf,nAeTx);

	if (!AutoRequest(FenstPtr,&PriAeTxt,&nAend,&Aend,NULL,NULL,404,47))
	   Aendere_Prior(EintrPtr[Wahl]->MyID, (BYTE)gInt);
   }
}

/*=== FUNCTION  ChangeOwnTask ===*/
/* Aendert den Namen & Prioritaet des eigenen Tasks.
   RESULT: Name 	<= OldName;
           ReturnWert 	== OldPri;
*/
LONG ChangeOwnTask(Name,NewPri)
	char *Name;
	LONG  NewPri;
{
	char *OldName;
	LONG  OldPri;
	struct Task *OwnTask;

   Forbid(); /* Taskwechsel unterbinden */
     OwnTask = (struct Task *) FindTask(0L);
     OldName = OwnTask->tc_Node.ln_Name;
     OldPri  = SetTaskPri(OwnTask,NewPri);
     OwnTask->tc_Node.ln_Name = Name; /* neuer Name */
   Permit();
   /* zwei! Rueckgabewerte: */
   Name = OldName;
   return(OldPri);
}

