#import "LanguageApp.h"
#import <sys/param.h>		/* for MAXPATHLEN */
#import <sys/file.h>		/* for F_OK, etc */
#import <string.h>		/* for strlen, rindex, etc */
#import <libc.h>		/* for access() */

extern	int	NXArgc;
extern	char	**NXArgv;

static NXAtom applicationDirectory;

@implementation Application (Language)

- (NXAtom)applicationDirectory
/*
 * Returns the directory name in which the application is running.  This is
 * useful for forming filenames within a file package.  After calling this
 * method initially, the static string 'applicationDirectory' holds the
 * name of the directory.
 */
{
  if (!applicationDirectory) {
    char rootname[MAXPATHLEN + 1], *tailname;
 
    strcpy(rootname, NXArgv[0]);
    if (tailname = rindex(rootname, '/')) {
      /*
       * There is at least one / in the pathname - clobber it to a null to
       * terminate the rootname string at the trailing /.
       */
      *tailname = '\0';
    } else {
      /* Assume a relative pathname (in the current directory). */
      sprintf(rootname,".");
    }
    applicationDirectory = NXUniqueString((const char *)rootname);
  }

  return applicationDirectory;
}

- (NXAtom)applicationFile:(const char *)fileName
/*
 * Given a filename, return the full pathname of that file within the
 * application's file package.
 */
{
  return [self applicationFile:fileName type:(const char *)nil];
}

- (NXAtom)applicationFile:(const char *)fileName type:(const char *)fileExt;
/*
 * Given a filename and file type (which can be nil), return the full
 * pathname of that file within the application's file package.
 */
{
  char pathname[MAXPATHLEN + 1];
  if (fileExt) {
    sprintf(pathname,"%s/%s.%s",[self applicationDirectory],fileName,fileExt);
  } else {
    sprintf(pathname,"%s/%s",[self applicationDirectory],fileName);
  }
  return NXUniqueString(pathname);
}

- (NXAtom)findLanguageFile:(const char *)fileName type:(const char *)fileExt
{
  const char *const *languages;
  char pathname[MAXPATHLEN + 1];
  NXAtom rootname = [self applicationDirectory];

  /*
   * Iterate over the list of preferred languages, return if we find the
   * desired filename.
   */
  languages = [self systemLanguages];
  while (languages && *languages) {
    const char *language = *languages++;
    if (fileExt) {
      sprintf(pathname,"%s/%s.%s/%s.%s",
	      rootname,language,LANGUAGE_DIRECTORY_SUFFIX,fileName,fileExt);
    } else {
      sprintf(pathname,"%s/%s.%s/%s",
	      rootname,language,LANGUAGE_DIRECTORY_SUFFIX,fileName);
    }
    if (access(pathname, F_OK) == 0) {
      /* We found the desired pathname--make a safe, unique copy and return */
      return NXUniqueString((const char *)pathname);
    }
  }

  /*
   * Haven't found the pathanme yet -- look for the file in the default
   * language directory.
   */
  if (fileExt) {
    sprintf(pathname,"%s/%s.%s/%s.%s",
	rootname,DEFAULT_LANGUAGE,LANGUAGE_DIRECTORY_SUFFIX, fileName,fileExt);
  } else {
    sprintf(pathname,"%s/%s.%s/%s",
	rootname,DEFAULT_LANGUAGE,LANGUAGE_DIRECTORY_SUFFIX,fileName);
  }
  if (access(pathname, F_OK) == 0) {
    /* We found the desired pathname -- make a safe, unique copy and return */
    return NXUniqueString((const char *)pathname);
  }

  /*
   * Still haven't found the pathanme yet -- look for the file in the current
   * directory.
   */
  if (fileExt) {
    sprintf(pathname,"%s/%s.%s", rootname,fileName,fileExt);
  } else {
    sprintf(pathname,"%s/%s", rootname,fileName);
  }
  if (access(pathname, F_OK) == 0) {
    /* We found the desired pathname -- make a safe, unique copy and return */
    return NXUniqueString((const char *)pathname);
  }

  /*
   * No joy.  Return nil.
   */
  return (NXAtom)nil;
}

/*
 * These following methods are similar to loadNibFile:owner: and
 * loadNibFile:owner:withNames, except that fileName is passed to
 * to the findLanguageFile: method (above).
 */

- loadNibLanguageFile:(const char *)fileName owner:anOwner
{
  return [self loadNibLanguageFile:fileName owner:anOwner withNames:YES];
}

- loadNibLanguageFile:(const char *)fileName owner:anOwner
	withNames:(BOOL)aFlag
{
  const char *fullName;
  /*
   * Since fileName already has a .nib extension on it, we cheat a bit here
   * and pass a null type argument to findLanguageFile.
   */
  fullName = [self findLanguageFile:fileName type:(const char *)nil];
  if (fullName) {
    return [self loadNibFile:fullName owner:anOwner withNames:aFlag];
  } else {
    return nil;
  }
}

@end
