/*{{{}}}*/
/*{{{  includes*/
#ifdef CONFIG_H
#   include "config.h"
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <pwd.h>
#include <unistd.h>

#define FILEC_C
#define I_GETTK_C
#define I_MAIN_C
#define I_MESSAGES_C
#define I_SCREEN_C

#include "origami.h"
#include <lib/ori_add_lib.h>
/*}}}  */

#ifdef FILEC
  /*{{{  user completion*/
  private int user_completion(char *n)
  {
    boolean conflict;
    boolean found;

    if (n[0]!=HOME_CHAR)
       return(True);

    conflict=False;
    found=False;
    if (n[1])
     /*{{{  try to expand*/
     { char const *user;
       int ul=strlen(n+1);

       start_getpwent();
       for (;(user=next_getpwent());)
          if (!strncmp(n+1,user,ul))
           /*{{{  user matches the start*/
             if (found)
              /*{{{  get minimum extension*/
              { char *old,c;
                char const *new;

                for (old=n+1,new=user;;new++,old++)
                   if ((c= *new)!=*old)
                    { conflict=True;
                      break;
                    }
                   else if (c=='\0')
                      break;
                 *old='\0';
              }
              /*}}}  */
             else
              /*{{{  use as completion*/
              { strcpy(n+1,user);
                found=True;
              }
              /*}}}  */
           /*}}}  */
       end_getpwent();
     }
     /*}}}  */
    return (conflict || !found);
  }
  /*}}}  */
#endif
/*{{{  filename completion*/
char *filec(char *filen)
{
  char *ret=0;
# ifdef FILEC
  boolean user=False;

  if (*filen)
   /*{{{  try to complete*/
   { static char dir[_POSIX_PATH_MAX+1];
     char full_path[_POSIX_PATH_MAX+_POSIX_PATH_MAX+1];
     DIR *dirptr;
     boolean conflict;

     /*{{{  maybe cut length*/
     { int l;

       if ((l=strlen(filen))>=_POSIX_PATH_MAX)
          filen+=_POSIX_PATH_MAX-l;
     }
     /*}}}  */
     conflict=False;
     /*{{{  get directory name*/
     { if (dir_name((unsigned char*)dir,(unsigned char*)filen))
        /*{{{  found path_separator, splitt filename*/
        { filen+=strlen(dir);
          home_expand(dir);
        }
        /*}}}  */
       else
        /*{{{  single filename*/
        { if (filen[0]==HOME_CHAR)
           /*{{{  expand user*/
           { int l;

             strcpy(dir,filen);
             l=strlen(dir);
             if (!(conflict=user_completion(dir)))
                strcat(dir,PATH_SEP);
             ret=dir+l;
             user=True;
           }
           /*}}}  */
          else
           /*{{{  use . as dir*/
             strcpy(dir,CURR_DIR);
           /*}}}  */
        }
        /*}}}  */
     }
     /*}}}  */
     if (!user)
        if ((dirptr=opendir(dir)))
         /*{{{  try to get file from directory*/
         { struct dirent *f;
           int fl;

           strcpy(full_path,dir);
           for (fl=strlen(filen);(f=readdir(dirptr));)
            /*{{{  check hit for file f*/
              if (!strncmp(filen,f->d_name,fl))
               /*{{{  file matches the start*/
                 if (ret)
                  /*{{{  get minimum completion*/
                  { char *sf,*sr,c;

                    for (sr=ret,sf=f->d_name+fl;;sr++,sf++)
                       if ((c= *sr)=='\0')
                        { if (*sf)
                             conflict=True;
                          break;
                        }
                       else if (*sf!=c)
                        { conflict=True;
                          break;
                        }
                    *sr='\0';
                  }
                  /*}}}  */
                 else
                  /*{{{  use file as completion*/
                  { strcpy(dir,f->d_name);
                    ret=dir+fl;
                  }
                  /*}}}  */
               /*}}}  */
            /*}}}  */
           closedir(dirptr);
           if (!conflict && ret)
            { strcat(full_path,PATH_SEP);
              strcat(full_path,dir);
              if (is_dir((FILE*)0,full_path))
                 strcat(ret,PATH_SEP);
            }
         }
         /*}}}  */
        else
           conflict=True;
     if (!scr_off && verbose && (conflict || !ret || !*ret) )
      { bell_audible();
        bell_visible();
      }
   }
   /*}}}  */
# endif

  return(ret?ret:(char*)empty_text);
}
/*}}}  */
