//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
//
// Created: LGO 05/22/89 -- Initial design and implementation
//

#include <cool/String.h>
#include <cool/Package.h>

// Find the next symbol whose pname starts with name, starting after current
// position.  If found, return TRUE and set new current position.
Boolean completions(Package& pkg, const char* name, Boolean sensitive) {
  int len = strlen(name);
  if (sensitive)
    while (pkg.next()) {
      const char* entry = pkg.value()->name();
      if (strlen(entry) >= len &&
	  strncmp(entry, name, len) == 0)
	return TRUE;
    }
  else
    while (pkg.next()) {
      const char* entry = pkg.value()->name();
      if (strlen(entry) >= len &&
	  is_equal_n(entry, name, len, INSENSITIVE))
	return TRUE;
    }
  return FALSE;
}

// "emacs" style symbol name completion.
// Modifies name parameter; Returns count of possible matches
int complete(Package& pkg, String& name, Boolean sensitive) {
  pkg.reset();
  if (completions(pkg, name, sensitive)) {
    Symbol* best = pkg.value();
    const char* best_name = best->name();
    long name_len = strlen(name);
    long best_len = strlen(best_name);
    int count = 1;

    while(completions(pkg, name, sensitive)) {
      Symbol* next = pkg.value();
      const char* next_name = next->name();
      int next_len = strlen(next_name);
      if (best_len > next_len)
	best_len = next_len;
      for(long i = name_len; i < best_len; i++)
	if(best_name[i] != next_name[i]) {
	  best_len = i;
	  count++;
	  break;
	}
      if(best_len == next_len) {
	count = 1;
	best_name = next_name;
      }
    } // end while
    
    name = strndup(best_name, best_len);
    pkg.find(best_name);
    return count;
  }
  return 0;
}

// EXAMPLE: To loop through all possible matches do:
#ifdef examples
void print_completions(Package& pkg, char* name, ostream& os = cout) {
  String check = name;
  int n = complete(pkg, check);
  if (n == 0) {
    os << "<no matches>\n";
  } else if (n == 1) {
    os << check << "\n"; // one match, and name is it
  } else {
    pkg.reset();
    while(completions(pkg, check)) { // will loop n times
      Symbol* match = pkg.value(); // returns next match
      os << match->name() << "\n";
    }
  }
}
#endif
