// "Search"
// This macro searches for text in files contained in a directory.
// TF, 2011.02 Added support for scripts; Recordable.

  str = "";
  contents = true;
  ignore = false;
  search = "Macros";
  firstLine = true;
  arg = getArgument;
  if (arg!="") {
      args = split(arg, "|");
      if (args.length==4) {
          str = args[0];
          contents = parseInt(args[1]);
          ignore = parseInt(args[2]);
          search = args[3];
       }
  }
  extensions = newArray(".java", ".txt", ".ijm", ".js", ".py", ".rb", ".clj", ".bsh", ".html");
  IJdir = getDirectory("imagej");

  Dialog.create("Search");
  Dialog.addString("_", str, 20);
  items = newArray("Macros", "Scripts", "Java", "ImageJ folder", "Choose...");
  Dialog.setInsets(2,20,0);
  Dialog.addRadioButtonGroup("Search:", items, 5, 1, search);
  Dialog.setInsets(0, 20, 0);
  Dialog.addCheckbox("Search_contents", contents);
  Dialog.addCheckbox("Ignore case", ignore);
  Dialog.setInsets(10, 0, 0);
  Dialog.addMessage("In the Log window, to open a file,\ndouble-click on its file path.");
  Dialog.show();
  str = Dialog.getString();
  contents = Dialog.getCheckbox();
  ignore = Dialog.getCheckbox();
  search = Dialog.getRadioButton();
  if (str=="")
     exit("Search string is empty");

  sourceExists = File.exists(IJdir+"source");
  searchNames = false;
  dir1=""; dir2=""; dir3="";
  if (search=="Scripts") {
      dir1 = getDirectory("macros");   
      dir2 = getDirectory("plugins");     
      dir3 = IJdir+"scripts/";
      extensions = newArray(".js", ".py", ".rb", ".clj", ".bsh");
  } else if (search=="Java") {
      dir1 = getDirectory("plugins"); 
      if (sourceExists)
         dir2 = IJdir+"source"+"/";
      extensions = newArray(".java");
  } else if (search=="ImageJ folder") {
      dir1 = getDirectory("imagej");
      searchNames = true;
  } else if (search=="Choose...") {
      dir1 = getDirectory("Choose a Directory");
      searchNames = true;
  } else {
      dir1 = getDirectory("macros");   
      dir2 = getDirectory("plugins");     
      extensions = newArray(".txt", ".ijm");
  }
  if (ignore)
      str = toLowerCase(str);
  count = 0;
  if (dir1!="") find(dir1);
  if (dir2!="") find(dir2);
  if (dir3!="") find(dir3);
  if (indexOf(str, "|")==-1)
      return ""+str+"|"+contents+"|"+ignore+"|"+search;
  exit; 

  function find(dir) {
      list = getFileList(dir);
      for (i=0; i<list.length; i++) {
          showProgress(i, list.length);
          if (endsWith(list[i], "/"))
              find(""+dir+list[i]);
          else if (contents && valid(list[i])) {
              s = File.openAsString(dir+list[i]);
              s2 = s;
              if (ignore)
                  s2 = toLowerCase(s);
              if (indexOf(s2,str)!=-1) {
                  count++;
                  if (firstLine)
                      showMessageInHeader();
                  print("");
                  print(dir+list[i]);
                  lines = split(s, "\n");
                  n = 0;
                  for (j=0; j<lines.length; j++) {
                      line = lines[j];
                      line2 = line;
                      if (ignore) line2 = toLowerCase(line);
                      if (indexOf(line2,str)!=-1 && n<8) {
                          print((j+1)+": "+line);
                          n++;
                      }
                 } // for
              } else
                  searchName(list[i]);
          } else if (searchNames || valid(list[i]))
              searchName(list[i]);
      }
      if (count==1)
          showStatus("1 match");
      else
          showStatus(count+" matches");
  }

  function searchName(name) {
      name2 = name;
      if (ignore)
          name2 = toLowerCase(name2);
      if (indexOf(name2,str)!=-1) {
          if (firstLine)
              showMessageInHeader();
          print("");
          print(dir+name);
          count++;
      }
  }

  function valid(name) {
      for (i=0; i<extensions.length; i++) {
         if (endsWith(name, extensions[i]))
             return true;
      }
      return false;
  }
  
  function showMessageInHeader() {
      print("\\Heading: Double-click on a file name to open it");
      firstLine = false;
  }

