/* HeaderFiles */

#include <stdio.h>
#include <exec/memory.h>
#include <libraries/dosextens.h>
#include <intuition/intuitionbase.h>

/*  Macros */

#define ACTIVE_SCREEN IntuitionBase->ActiveScreen
#define ACTIVE_WINDOW IntuitionBase->ActiveWindow
#define CLASS         ((Message)? Message->Class: 0 )

/* Declarations */

struct Library      * OpenLibrary() ;
struct Window       * OpenWindow() ;
struct IntuiMessage * GetMsg() ,
                    * Message = NULL ;

VOID   CloseLibrary() ;

/* externe Strukturen */

struct IntuitionBase    * IntuitionBase ;
struct GfxBase          * GfxBase ;

/* Funktionen */

SHORT OpenLib()
{
  if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0)))
    { return (1) ; }

  if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0)))
    { return (2) ; }

  return(0) ;
}

VOID CloseLib()
{
  if(IntuitionBase) CloseLibrary(IntuitionBase);
  if(GfxBase)       CloseLibrary(GfxBase);
}

struct Window   * win = NULL ;
struct RastPort * RP  = NULL ;

struct Task *FindTask() ;

VOID Print() ;
VOID Block() ;
VOID Line() ;
ULONG GetMessage() ;
struct Window *GetWindow() ;
void * calloc() ;
extern long Lock(), Examine(), ExNext() ;
char * strsave() ;
struct Dir_Eintrag * sortiere_liste() ;

struct Dir_Eintrag {
                     struct Dir_Eintrag * next  ;
                     struct Dir_Eintrag * prev  ;
                     int                  ebene ;
                     char               * name  ;
                   }  ;

struct anti_list   {
                     struct anti_list * next  ;
                     char             * name  ;
                   }  ;

struct anti_list * anti_list_anf = NULL ;

struct Dir_Eintrag * Dir_Anfang = NULL ,
                   * Dir_Ende   = NULL ,
                   * window_anf = NULL ,
                   * window_end = NULL ;

FILE  * datei_zeiger,
      * datei_zeiger1;

int     i,
        xpos = 0 ,
        ypos = 0 ,
        R_Rand = 8,
        O_Rand = 11,
        max_laenge = 0,
        max_hoehe  = 0,
        max_window_height = 0 ,
        TEXTCOL = 1 ,
        MARKCOL = 3 ,
        LINECOL = 2 ,
        delay   = 0 ,
        scroll  = 8 ,
        new     = 0 ,
        list    = 0 ,
        sort    = 0 ,
        temp    = 0 ,
        file    = 0 ;

char    *prog_name,
        command_string[100] ,
        newdir[200] ,
        newdirBCPL[200] ,
        rootdir[40] ,
        text1[40] ,
        text2[80] ,
        dirlist[50] ,
        antilist[50] ,
        configfile[50] ,
        rootdir_list[5][40] = {
                                "DH0:",
                                "\0",
                                "\0",
                                "\0",
                                "\0"
                              } ;

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

main ( argc , argv )
  int argc ;
  char * argv[] ;
{
  int zaehler = 0 ;
  prog_name = "KCD" ;

  sprintf( configfile, "s:%s.cfg"     , prog_name ) ;
  sprintf( dirlist   , "s:%s.list"    , prog_name ) ;
  sprintf( antilist  , "s:%s.antilist", prog_name ) ;
  strcpy( command_string , "setenv NewPath %s" ) ;

  if( datei_zeiger = fopen( configfile , "r" ) )
   {
    while ( lese_config_file( datei_zeiger ) )
    {
     if( !stricmp( text1 , "TEXTCOLOR" ) )
      { TEXTCOL = atoi(text2) ; continue ; }

     if( !stricmp( text1 , "MARKCOLOR" ) )
      { MARKCOL = atoi(text2) ; continue ; }

     if( !stricmp( text1 , "LINECOLOR" ) )
      { LINECOL = atoi(text2) ; continue ; }

     if( !stricmp( text1 , "WINDOWX" ) )
      {
       xpos    = atoi(text2) ;
       if( xpos<0 )
        xpos = 0 ;
       continue ;
      }

     if( !stricmp( text1 , "WINDOWY" ) )
      {
       ypos    = atoi(text2) ;
       if( ypos<0 )
        ypos = 0 ;
       continue ;
      }

     if( !stricmp( text1 , "ROOTDIR" ) )
      { strcpy(rootdir_list[zaehler],text2) ; ++zaehler ; continue ; }

     if( !stricmp( text1 , "DELAY" ) )
      { delay   = atoi(text2) ; continue ; }

     if( !stricmp( text1 , "SORT" ) )
      { sort  = atoi(text2) ; continue ; }

     if( !stricmp( text1 , "SCROLL" ) )
      {
       scroll  = atoi(text2) ;
       if( scroll<1 || scroll>4 )
        scroll=8 ;
       if( scroll == 3 )
        scroll=4 ;
       continue ;
      }

     if( !stricmp( text1 , "NOT" ) )
      { make_anti_list( text2 ) ; continue ; }

     if( !stricmp( text1 , "COMMAND" ) )
      { strcpy( command_string , text2 ) ; continue ; }

     printf("\n%s nicht erlaubt in Konfigurations-Datei %s.\n\n" , text1 , configfile ) ;
     End(0) ;
    }
   }
  fclose( datei_zeiger ) ;

  if( argc>2 )
      print_use() ;

  if( argc == 2 )
   {
    if( argv[1][0] == '-' )
     switch( argv[1][1] )
      {
        case 'n' :
        case 'N' :
                      new = 1 ;
                      break ;

        case 'l' :
        case 'L' :
                      list = 1 ;
                      break ;

        case '?' :
                      print_use() ;
                      break ;

        case 'f' :
        case 'F' :
                      strcpy( dirlist, argv[1]+2 ) ;
                      if( !fopen( dirlist ,"r") )
                       {
                        printf( "\nKann Datei `%s' nicht oeffnen !\n\n", dirlist ) ;
                        End(0) ;
                       }
                      file = 1 ;
                      break ;

        default :
                      print_use() ;
      }
    else
     {
      int laenge ;

      laenge = strlen(argv[1]) ;
      temp = 1 ;
      if( laenge == 1 && argv[1][0] == '?' )
        print_use() ;
      sprintf( dirlist, "RAM:%s.list", prog_name) ;
      strcpy(rootdir_list[0],argv[1]) ;
      if( (argv[1][laenge-1] != '/') &&
          (argv[1][laenge-1] != ':') )
       {
        rootdir_list[0][laenge]   = '/' ;
        rootdir_list[0][laenge+1] = '\0' ;
       }

      rootdir_list[1][0] = '\0' ;
     }
   }

  if(OpenLib())
    printf("\nKann Library nicht oeffnen!\n\n"), exit(0) ;

  if( !(datei_zeiger = fopen( dirlist ,"r")) || new || list || temp )
   {
    fclose( datei_zeiger ) ;

    if( list )
     {
      if( datei_zeiger1 = fopen( antilist ,"r") )
       {
        printf( "\nDatei `%s' schon vorhanden.\n", antilist ) ;
        printf( "-->Von Hand mit `delete %s' loeschen.\n\n", antilist ) ;
        End(0) ;
       }

      if( !(datei_zeiger1 = fopen( antilist ,"w")) )
       {
        printf( "\nKann Datei `%s' nicht zum schreiben oeffnen !!\n\n", antilist ) ;
        End(0) ;
       }
     }
     else
      if( !temp)
       lese_anti_list() ;

    if( datei_zeiger = fopen( dirlist ,"w"))
     {
      if( !temp )
       printf("\nDirectory-Struktur wird ermittelt.\nBitte etwas Geduld.\n\n");
      for( zaehler = 0 ; zaehler<6 && rootdir_list[zaehler][0]!='\0' ; ++zaehler )
       {
        strcpy( rootdir , rootdir_list[zaehler] ) ;
        fprintf( datei_zeiger, " 0 %s\n", rootdir ) ;
        if( !temp )
         printf( "Untersuche %s\n", rootdir ) ;
        search_dir( rootdir , 1 ) ;
        if( sort )
         Dir_Anfang = sortiere_liste( Dir_Anfang , 1 ) ;
        for( window_anf = Dir_Anfang ; window_anf ; window_anf = window_anf->next )
         fprintf( datei_zeiger , "%2d %s\n", window_anf->ebene , window_anf->name ) ;
        Dir_Anfang = NULL ;
        Dir_Ende   = NULL ;
        window_anf = NULL ;
        window_end = NULL ;
       }
      fclose( datei_zeiger ) ;
      if( !temp )
        End(0) ;
       else
        {
         max_laenge = 0 ;
         max_hoehe  = 0 ;
        }
     }
     else
     {
      printf( "\nKann Datei `%s' nicht oeffnen !!\n\n", dirlist ) ;
      End(0) ;
     }
   }

  lese_structur() ;

  if( max_hoehe == 1 )
   {
    printf( "Keine Unterverzeichnisse gefunden.\n") ;
    End(0) ;
   }

  max_hoehe = 8*max_hoehe + 18 ;

  if( max_hoehe > ACTIVE_SCREEN->Height )
    max_hoehe = ACTIVE_SCREEN->Height ;

  max_window_height = max_hoehe ;

  if( max_hoehe+ypos > ACTIVE_SCREEN->Height )
    max_hoehe = ACTIVE_SCREEN->Height - ypos ;

  max_laenge += 20 ;

  if( max_laenge < 110 )
    max_laenge = 110 ;

  if( max_laenge > ACTIVE_SCREEN->Width )
    max_laenge = ACTIVE_SCREEN->Width ;

  if( max_laenge+xpos > ACTIVE_SCREEN->Width )
    xpos = ACTIVE_SCREEN->Width - max_laenge ;

  if(!( win = GetWindow(xpos , ypos , max_laenge , max_hoehe , 0 ,
                        WINDOWCLOSE|ACTIVATE|WINDOWSIZING|WINDOWDRAG|REPORTMOUSE,
                        prog_name,0)))
    End(0) ;

  RP = win->RPort ;

  strcpy( newdir , "" ) ;

  zeige_structur() ;

  End(0) ;
}

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

print_use()
{
  printf( " %s 1.0 by Karsten Krauskopf, Feb 1990\n", prog_name );
  printf( "  USE: %s [ ? | -n | -l | -f<file> | <Directory> | <Device:> ]\n", prog_name );
  printf( "    ? .. dieser Text\n" );
  printf( "   -n .. Datei %s neu ermitteln\n", dirlist );
  printf( "   -l .. Datei %s neu ermitteln\n", antilist );
  printf( "   -f .. Struktur aus Datei <file>\n\n" );
  End(0) ;
}

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

End( error )
  int error ;
{
  if ( win )
   CloseWindow( win ) ;
  CloseLib() ;
  exit( error );
}

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

lese_config_file( datei )
  FILE *datei ;
{
  char zeile[120] ;
  char *pointer, c ;
  int  textnummer = 0 , i ;

next_zeile:
  if( !fgets(zeile,120,datei) )
   return 0 ;

  pointer = text1 ;

  for( i=0 ; i<120 ; ++i )
  {
   switch( zeile[i] )
   {
    case '\n' :
    case ';'  :
                 i = 120 ;
                 break ;

    case '\''  :
                 pointer = text2 ; ++i ;
                 *pointer = '\0' ;
                 while( zeile[i] < 120 )
                  {
                   if( zeile[i] == '\'' )
                     { i = 120 ; textnummer = 4 ; break ; }
                   *pointer = zeile[i] ; ++pointer ; ++i ; *pointer = '\0' ;
                  }
                 break ;

    case ' ' :
                 if( textnummer == 1 || textnummer == 3 )
                   {
                     ++textnummer ;
                     if( textnummer == 2 )
                       pointer = text2 ;
                   }
                 break ;

    default  :
                 if( textnummer == 0 || textnummer == 2 )
                   ++textnummer ;
                 *pointer = zeile[i] ;
                 ++pointer ;
                 *pointer = '\0' ;
                 break ;

   }
  }
  if( textnummer >= 3 )
    return 1 ;
  textnummer=0 ;
  pointer=text1 ;
  goto next_zeile ;
}

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

lese_anti_list()
{
  char Directory[200] ;
  struct anti_list *ptr ;

  if( datei_zeiger1 = fopen( antilist ,"r") )
   while ( fgets( &Directory , 200 , datei_zeiger1 ) )
    if( Directory[0] == '-' )
     {
      Directory[strlen(Directory)-1] = '\0' ;
      make_anti_list( &Directory[1] ) ;
     }
  fclose( datei_zeiger1 ) ;
}

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

make_anti_list( Dir_Name )
  char *Dir_Name ;
{
  static struct anti_list *new_entry = NULL ,
                          *ptr                     ;
  static int               new_entry_counter = 101 ;

  ++new_entry ;
  if( (++new_entry_counter) > 100 )
   {
    new_entry_counter = 1 ;
    if ( !(new_entry = (struct anti_list *) calloc(100,sizeof(struct anti_list))) )
     platzprobleme() ;
   }

  new_entry->next  = (struct anti_list *) NULL ;
  new_entry->name  = strsave( Dir_Name ) ;

  if( !anti_list_anf )
   {
    anti_list_anf = new_entry ;
    ptr = new_entry ;
    return ;
   }
  ptr->next = new_entry ;
  ptr = new_entry ;
}

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

suche_anti_list( Dir_Name )
  char *Dir_Name ;
{
  struct anti_list *ptr ;

  for( ptr = anti_list_anf ; ptr ; ptr = ptr->next )
   if( !stricmp( Dir_Name , ptr->name ) )
    return 1 ;
  return 0 ;
}

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

search_dir( name , ebene )
  char *name  ;
  int   ebene ;
{
  struct FileInfoBlock * fib ;
  BPTR                   lok ;
  char                   temp[200] ;
  int                    i ;

  if(!(lok=Lock (name,ACCESS_READ)))
   {
    printf( "\nDirectory %s nicht gefunden.\n\n", name ) ;
    End(0) ;
   }

  if (!(fib = (struct FileInfoBlock *) calloc(1,sizeof(struct FileInfoBlock))))
   {
    printf ("\nCan't allocate FileInfoBlock.\n\n") ;
    End(0) ;
   }

  if(!Examine(lok,fib))
   {
    printf("\nExamine failed.\n\n") ;
    End(0) ;
   }

  while ( ExNext( lok , fib ) )
   if( fib->fib_DirEntryType > 0 )
    {
     strcpy( temp , name );
     if (ebene == 1)
       strcat(temp,fib->fib_FileName);
      else
       strcat(temp,"/"),strcat(temp,fib->fib_FileName);

     if( list )
      {
       if( !suche_anti_list( temp ) )
        {
         fprintf( datei_zeiger1, "%s\n"  , temp ) ;
         make_eintrag( ebene , fib->fib_FileName ) ;
         search_dir( temp , ebene+1 ) ;
        }
      }
      else
       if( !suche_anti_list( temp ) )
        {
         make_eintrag( ebene , fib->fib_FileName ) ;
         search_dir( temp , ebene+1 ) ;
        }
    }

ende:
  if ( lok ) UnLock( lok ) ;
}

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

lese_structur()
{
  char Directory[35] ;

  if( !( datei_zeiger = fopen( dirlist , "r" )))
   {
    printf("\nKann Datei `%s' nicht oeffnen !!!\n\n", dirlist ) ;
    End(0) ;
   }

  while ( fgets( &Directory , 35 , datei_zeiger ) )
  {
   Directory[strlen(Directory)-1] = '\0' ;
   Directory[2] = '\0' ;
   make_eintrag( atoi(Directory) , &Directory[3] ) ;
  }

  if( max_hoehe < 1 )
   {
    printf("\nDatei `%s' hat keine Eintraege !!\n\n", dirlist ) ;
    End(0) ;
   }
}

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

make_eintrag( Ebene , Dir_Name )
  int    Ebene    ;
  char  *Dir_Name ;
{
  static struct Dir_Eintrag *new_entry         = NULL ;
  static int                 new_entry_counter = 101  ;

  ++max_hoehe ;
  ++new_entry ;
  if( (++new_entry_counter) > 100 )
   {
    new_entry_counter = 1 ;
    if ( !(new_entry = (struct Dir_Eintrag *) calloc(100,sizeof(struct Dir_Eintrag))) )
     platzprobleme() ;
   }

  if( max_laenge < ( R_Rand + Ebene*32 + 8*strlen(Dir_Name) ) )
   max_laenge = R_Rand + Ebene*32 + 8*strlen(Dir_Name) ;

  if( Dir_Anfang )
   {
    new_entry->next  = (struct Dir_Eintrag *) NULL ;
    new_entry->prev  = Dir_Ende ;
    new_entry->ebene = Ebene ;
    new_entry->name  = strsave( Dir_Name ) ;

    Dir_Ende->next   = new_entry ;
    Dir_Ende         = new_entry ;

    return ;
   }

  new_entry->next     = (struct Dir_Eintrag *) NULL ;
  new_entry->prev     = (struct Dir_Eintrag *) NULL ;
  new_entry->ebene    = Ebene ;
  new_entry->name     = strsave( Dir_Name ) ;

  Dir_Anfang = new_entry ;
  Dir_Ende   = new_entry ;
}

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

char *strsave(s)
  register char *s ;
{
  register char * cp = calloc( strlen(s)+1, 1 ) ;

  if ( cp )
   {
    strcpy( cp , s ) ;
    return cp ;
   }
  platzprobleme() ;
}

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

struct Dir_Eintrag * hole_eintrag( position )
        int     position ;
{
  struct Dir_Eintrag * ptr ;

  for( ptr = window_anf ; ptr ; ptr = ptr->next , --position )
   if( !position ) return ptr ;
}

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

ermittle_dir( pointer )
        struct Dir_Eintrag * pointer ;
{
  struct Dir_Eintrag * ptr ;
  int ebene ;
  char temp[200] ;

  ebene = pointer->ebene ;
  strcpy( newdir , pointer->name ) ;

  for( ptr = pointer ; ptr ; ptr = ptr->prev )
   if( ptr->ebene < ebene )
    {
     ebene = ptr->ebene ;
     strcpy( temp , ptr->name ) ;
     if( ptr->ebene >0 )
      strcat( temp , "/" ) ;
     strcat( temp , newdir ) ;
     strcpy( newdir , temp ) ;
    }
  newdirBCPL[0] = (char)strlen(newdir) ;
  newdirBCPL[1] = '\0' ;
  strcat( newdirBCPL , newdir ) ;
}

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

zeige_structur()

{
  int   i,
        pos,
        pos_alt,
        x,
        y,
        anzahl_zeilen,
        anzahl_spalten,
        hoehe,
        breite ,
        activ = 1 ;

  struct Dir_Eintrag * ptr = NULL ;

  ModifyIDCMP( win , MOUSEBUTTONS|CLOSEWINDOW|REFRESHWINDOW ) ;

anfang:
  anzahl_zeilen  = (win->Height-13)/8 ;
  anzahl_spalten = (win->Width-25)/8 ;
  hoehe  = win->Height ;
  breite = win->Width ;

  i = 0 ;
  for ( ptr = Dir_Anfang ; ptr ; ptr = ptr->next )
   {
    if ( i == anzahl_zeilen )
     break ;
    zeige_eintrag( ptr , i ) ;
    ++i ;
   }

  window_anf = Dir_Anfang ;
  if( ptr )
    window_end = ptr->prev ;
   else
    window_end = Dir_Ende ;

  pos_alt = -1 ;

  while( 1 )
  {
   while(ACTIVE_WINDOW != win)
    { Delay(10) ; activ = 0 ; }

   if( delay )
    Delay(delay) ;

   if ( win->Height != hoehe || win->Width != breite )
    {
     Block(RP,0,2,11,win->Width-17,win->Height-2);
     goto anfang;
    }
   pos = ((win->MouseY)-12)/8 ;

   if ( pos != pos_alt && pos>=0 && pos<anzahl_zeilen )
    {
     if( pos_alt >= 0 )
      {
       ptr = hole_eintrag( pos_alt ) ;
       x = R_Rand + ptr->ebene*32 ; y = 18+pos_alt*8 ;
       Print(RP, ptr->name, TEXTCOL, x, y) ;
      }

     ptr = hole_eintrag( pos ) ;
     x = R_Rand + ptr->ebene*32 ; y = 18+pos*8 ;
     Print(RP, ptr->name, MARKCOL , x, y) ;
     pos_alt = pos ;
    }

   if ( pos <= 0 && window_anf != Dir_Anfang )
    {
     int z ;

     window_anf = window_anf->prev ;
     window_end = window_end->prev ;
     ++pos_alt ;
     for( z=0 ; z<8 ; z+=scroll )
      ScrollRaster(RP,0,-scroll,2,11,win->Width-17,O_Rand+anzahl_zeilen*8) ;
     zeige_eintrag( window_anf , 0 ) ;
    }

   if (pos >= anzahl_zeilen-1 && window_end != Dir_Ende )
    {
     int z ;

     window_anf = window_anf->next ;
     window_end = window_end->next ;
     --pos_alt ;
     for( z=0 ; z<8 ; z+=scroll )
      ScrollRaster(RP,0,scroll,2,11,win->Width-17,O_Rand+anzahl_zeilen*8) ;
     zeige_eintrag( window_end , anzahl_zeilen-1 ) ;
    }

   if( GetMessage( win ) )
    {
     if ( (CLASS == MOUSEBUTTONS) && ptr )
      {
       if( activ )
        {
         char temp[200] ;

         ermittle_dir( ptr ) ;
         sprintf( temp , command_string , newdir ) ;
         Execute( temp , 0 , 0 ) ;
         End(0) ;
        }
        else
         if ( Message->Code == SELECTUP )
          activ = 1 ;
      }

     if ( CLASS == CLOSEWINDOW )
      {
       Execute( "setenv newpath" , 0 , 0 ) ;
       break ;
      }

    }
  }
}

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

zeige_eintrag( eintrag , zeile )
   struct Dir_Eintrag * eintrag ;
   int                  zeile ;

{
  int    x, y, j, ebene ;
  struct Dir_Eintrag * ptr ;

  x = R_Rand +(eintrag->ebene)*32 ; y = O_Rand+7+zeile*8 ;
  Print( RP , eintrag->name , TEXTCOL , x , y ) ;
  if( eintrag->ebene )
    {
      if( eintrag->next && ( eintrag->ebene == eintrag->next->ebene ) )
          Line( RP,LINECOL,x-18,y-7,x-18,y );
        else
          Line( RP,LINECOL,x-18,y-7,x-18,y-3 ) ;
      Line(RP,LINECOL,x-18,y-3,x-2,y-3) ;
      ebene = eintrag->ebene ;
      ptr = eintrag ;
      while ( ptr )
        {
          ptr = ptr->next ;
          if( ptr->ebene < ebene )
            {
              ebene = ptr->ebene ;
              x = R_Rand+ebene*32 ; y = 18+zeile*8 ;
              Line(RP,LINECOL,x-18,y-7,x-18,y);
            }
        }
    }
}

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

struct Window *GetWindow(left,top,width,height,idcmp,flags,title,gad)
  SHORT  left,top,width,height ;
  ULONG  idcmp,flags ;
  STRPTR title ;
  struct Gadget *gad ;

{
  struct NewWindow NW ;

  NW.LeftEdge    = left ;
  NW.TopEdge     = top ;
  NW.Width       = width ;
  NW.Height      = height ;
  NW.DetailPen   = -1 ;
  NW.BlockPen    = -1 ;
  NW.IDCMPFlags  = idcmp ;
  NW.Flags       = flags ;
  NW.FirstGadget = gad ;
  NW.CheckMark   = NULL ;
  NW.Title       = title ;
  NW.Screen      = ACTIVE_SCREEN ;
  NW.BitMap      = NULL ;
  NW.MinWidth    = width ;
  NW.MinHeight   = 34 ;
  NW.MaxWidth    = width  ;
  NW.MaxHeight   = max_window_height ;
  NW.Type        = WBENCHSCREEN ;

  return(OpenWindow(&NW)) ;
}

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

ULONG GetMessage(MW)  /* Intuition-Message lesen */
  struct Window *MW ;
{
  ULONG class = 0 ;

  if ( Message = GetMsg(MW->UserPort))
    {
      class = Message->Class ;
      ReplyMsg(Message) ;
    }
  return class ;
}

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

VOID Line(RP, col, x1, y1, x2, y2)
  struct RastPort *RP ;
  SHORT  col, x1, y1, x2, y2 ;
{
  SetDrMd(RP, JAM1) ;
  SetAPen(RP, col) ;
  Move(RP, x1, y1) ;
  Draw(RP, x2, y2) ;
}

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

VOID Block(RP, col, x1, y1, x2, y2)
  struct RastPort *RP ;
  SHORT  col, x1, y1, x2, y2 ;
{
  if ( (x1>x2)||(y1>y2)) return ;
  SetDrMd(RP, JAM1) ;
  SetAPen(RP, col) ;
  RectFill(RP, x1, y1, x2, y2) ;
}

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

VOID Print(RP, text, col, xpos, ypos)
  struct RastPort *RP ;
  STRPTR text ;
  SHORT  col, xpos, ypos ;
{
  SetDrMd(RP, JAM1) ;
  SetAPen(RP, col) ;
  Move(RP, xpos, ypos);
  Text(RP, text, strlen(text));
}

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

platzprobleme()
{
  printf( "\nKein Platz mehr fuer weiter Eintraege.\n\n") ;
  End(0) ;
}

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

int stricmp(str1,str2)
register char *str1,*str2;
{
  register int index = 0;

  while ( str1[index] && str2[index] && tolower(str1[index]) == tolower(str2[index]) )
    ++index;

  return( (tolower(str1[index]) < tolower(str2[index])) ? -1 :
        ( (tolower(str1[index]) > tolower(str2[index])) ?  1 : 0) );
}

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

struct Dir_Eintrag * sortiere_liste( anfang , ebene )
  struct Dir_Eintrag * anfang ;
  int                  ebene ;
{
  struct Dir_Eintrag * ptr1 , * ptr2 ;

  ptr1 = anfang ;
  ptr2 = ptr1   ;

  while( ptr2 && (ptr2->ebene >= ebene) )
   {
    if( ptr2->ebene > ebene )
      {
        ptr2 = sortiere_liste( ptr2 , ebene+1 ) ;
        while( ptr2 && (ptr2->ebene > ebene) )
          ptr2 = ptr2->next ;
        continue ;
      }
    ptr2 = ptr2->next ;
   }

  while( 1 )
   {
    while( ptr1 && (ptr1->ebene != ebene) )
      ptr1 = ptr1->next ;
    if( !ptr1 || (ptr1->ebene < ebene ) )
      break ;
    ptr2 = ptr1->next ;
    while(1)
     {
      while( ptr2 && (ptr2->ebene > ebene) )
        ptr2 = ptr2->next ;
      if( !ptr2 || (ptr2->ebene < ebene ) )
        break ;
      if( ( sort > 0 && stricmp( ptr1->name , ptr2->name ) > 0 ) ||
          ( sort < 0 && stricmp( ptr1->name , ptr2->name ) < 0 )   )
        {
          struct Dir_Eintrag * hilf1 , *hilf2 , *hilf3 ;

          hilf1 = ptr1 ;
          while( hilf1->next && (hilf1->next->ebene > ebene ))
            hilf1 = hilf1->next ;

          hilf2 = ptr2 ;
          while( hilf2->next && (hilf2->next->ebene > ebene ))
            hilf2 = hilf2->next ;

          if( ptr1 == anfang )
            anfang = ptr2 ;

          ptr1->prev->next = ptr2 ;
          ptr2->prev->next = ptr1 ;
          hilf3 = hilf1->next ;
          hilf1->next = hilf2->next ;
          hilf2->next = hilf3 ;

          hilf3 = ptr1->prev ;
          ptr1->prev = ptr2->prev ;
          ptr2->prev = hilf3 ;
          if( hilf2->next )
            hilf2->next->prev = hilf2 ;
          if( hilf1->next )
            hilf1->next->prev = hilf1 ;

          hilf3 = ptr1 ;
          ptr1 = ptr2 ;
          ptr2 = hilf3 ;
        }
      ptr2 = ptr2->next ;
     }
    ptr1 = ptr1->next ;
   }
  return anfang ;
}

