/*      dirtree.c                                  08.05.95       */
/*
/  --------------------------------------------------------------
/  Copyright (C) 1993: Michael Braun
/                      Kaetinger Muehlenweg 103 A
/                      D-28816 Stuhr
/  --------------------------------------------------------------
/
/    editor main program
/
*/


/************************/
/*  include files       */
/************************/

#define _GLOBAL_
#include "config.h"
#include "global.h"
#include "standard.h"
#include "dirtree.h"
#include "directry.h"
#include "wildname.h"


/************************/
/* some defines         */
/************************/

#define MAX_DIR_LEVEL 64


/************************/
/* local structures     */
/************************/

static const char *symbol_string [] [4]   /* 2. index = 0 : ASCII  */
                                          /*          = 1 : VGA    */
                                          /*          = 2 : VT100  */
                                          /*          = 3 : ANSI   */
                = { /*    0      1      2                  3       */
   /* SYMB_VERTICAL */  {"|  ", "³  ", "\033(0x  \033(B", "\033(03  \033(B"},
   /* SYMB_SPACES   */  {"   ", "   ", "\033(0   \033(B", "\033(0   \033(B"},
   /* SYMB_BOT_LEFT */  {"+--", "ÀÄÄ", "\033(0mqq\033(B", "\033(0@DD\033(B"},
   /* SYMB_T_RIGHT  */  {"+--", "ÃÄÄ", "\033(0tqq\033(B", "\033(04DD\033(B"}
                  };


/************************/
/*  module definitions  */
/************************/

/* -FF- */

void one_directory (int level, int max_level,
                    enum TERM_TYPE term_type,
                    int last_entry[], char *path,
                    int debug_flag)
{
struct DIR_ENTRY *de;
int ii, nn, dir_num, total_num;
size_t save_len;

/* construct array with all directory entries */
   de = get_directory_buffer (path, de, &dir_num, &total_num);
   if (de == NULL)
   {
      printf (" (open error on path \"%s\")", path);
      return;
   }

/* show some more information */
   if (debug_flag)
   {
      printf (" (level=%d, dirs=%d, files=%d)",
                 level, dir_num, (total_num-dir_num));
   }

/* loop for all directory entries */
   for (ii = 0 ; ii < dir_num ; ii++)
   {
   /* skip special dirs "." and ".." */
      if (strcmp (de[ii].name, "." ) == 0) continue;
      if (strcmp (de[ii].name, "..") == 0) continue;

   /* check for overflow */
      if (level >= max_level)
      {
         printf (" ... ");

         if (level >= (MAX_DIR_LEVEL-1))
            printf ("max. level exceeded");

         break;
      }

   /* new line */
      printf ("\n");

   /* print left-hand part of graphik */
      for (nn = 0 ; nn < level ; nn++)
      {
         if (last_entry[nn])
            printf ("%s", symbol_string[SYMB_SPACES][term_type]);
         else
            printf ("%s", symbol_string[SYMB_VERTICAL][term_type]);
      }  /* for nn */

   /* print right-hand side of graphic */
      if (ii == (dir_num-1))
         printf ("%s", symbol_string[SYMB_BOT_LEFT][term_type]);
      else
         printf ("%s", symbol_string[SYMB_T_RIGHT][term_type]);

   /* print directory name */
      printf ("%s", de[ii].name);

   /* recursive call of same procedure */
      {
         last_entry[level] = (ii == (dir_num-1));
   
      /* construct full pathname */
         save_len = strlen (path);
         strncat (path, FILE_SEPARATOR, BUF_256);
         strncat (path, de[ii].name, BUF_256);
   
         one_directory ((level+1), max_level, term_type,
                        last_entry, path, debug_flag);
   
      /* restore old pathname */
         path[save_len] = '\0';
      }
   }  /* for ii */

/* free old buffer */
   if (de)
      free (de);

   return;

}  /* one_directory */

/* -FF- */

/* ----------------------------------------------------------- */
/*  main program                                               */
/* ----------------------------------------------------------- */

int main (argc, argv)       /* hier bei main (und nur hier !): */
int argc;                   /* keine ANSI-Schreibweise, wegen  */
char *argv [];              /* des c-compiler unter ultrix     */
{
static int last_entry [MAX_DIR_LEVEL];
static char pathname  [BUF_256];
static enum TERM_TYPE term_type;
static int ii, max_level, debug_flag;


/* help command line options */
   if (argc >= 2)
   {
      if ((stricmp (argv[1], "-?")    == 0) ||
          (stricmp (argv[1], "-h")    == 0) ||
          (stricmp (argv[1], "-help") == 0))
      {
         printf ("\n program \"dirtree\" - M. Braun - 08.05.95 \n");
         printf ("\n usage: dirtree [pathname [options]] \n");
         printf ("\n - [pathname] : default: \".\" \n");
         printf ("\n - [options]  : -? | -h | -help \n");
         printf (  "                -ascii | -vga | -vt100 | -ansi \n");
         printf (  "                -level <max.level> \n");
         printf (  "                -debug \n");
         printf ("\n examples: dirtree \n");
         printf (  "           dirtree .. \n");
         printf (  "           dirtree ..\\test_dir -ascii \n");
         printf (  "           dirtree C: -level 3 \n");
         printf (  "           dirtree C:\\USR -vga -level 4 -debug \n");
         exit (-1);
      }
   }


/* default values */
   strcpy (pathname, ".");   /* default: current directory */

#if (ACT_SERVER == SERVER_VGA)
   term_type = TERM_VGA;
#elif (ACT_SERVER == SERVER_VT_100)
   term_type = TERM_VT_100;
#else
   term_type = TERM_ASCII;
#endif

   max_level = MAX_DIR_LEVEL-1;
   debug_flag = 0;
   

/* actual parameters */
   if (argc >= 2)
      strncpy (pathname, argv[1], BUF_256);

   for (ii = 2 ; ii < argc ; ii++)
   {
   /* terminal type */
      if (stricmp (argv[ii], "-ascii") == 0)
         term_type = TERM_ASCII;

      if (stricmp (argv[ii], "-vga") == 0)
         term_type = TERM_VGA;

      if (stricmp (argv[ii], "-vt100") == 0)
         term_type = TERM_VT_100;

      if (stricmp (argv[ii], "-ansi") == 0)
         term_type = TERM_ANSI;

   /* max. level */
      if (stricmp (argv[ii], "-level") == 0)
         max_level = min (max_level, atoi (argv[ii+1]));

   /* debug option */
      if (stricmp (argv[ii], "-debug") == 0)
         debug_flag = 1;
   }  /* for ii */


/* now do it ! */
   printf ("%s", pathname);
   one_directory (0, max_level, term_type,
                  last_entry, pathname, debug_flag);
   printf ("\n");


   exit (0);
   return (0);
}  /* main */

/* -FF-  */

/* Modification History */
/* 03.05.95 - file erzeugt */
