//: FileReaderDemo.java

////////////////////////////////////////////////////////////////////////////////
// Author: Miroslava Kaloper
// Overview: Reads specified file and looks for parents and children of a node
// Modifications:
// July/15/99 - Mira - Created
// June/21/01 - Kane Tse - modified to work with the GOTree data structure,
//                         this modification significantly decreases
//                         the number of file accesses
///////////////////////////////////////////////////////////////////////////////

package goview;
  
import java.io.*;
import java.util.Vector;
import java.util.Enumeration;

class FileReaderDemo {

     static boolean commandLine = false;
     static DataInputStream in = new DataInputStream(System.in);
     static final int pageSize = 30; // Number of elements displayed per screen

/*************************************************************************
 *
 * Method:     main()
 * Purpose:    Executes the goview program, either in interactive or
 *               non-interactive (command-line) mode
 * Parameters: String fileNm - name of the GO file to lookup
 *             String lkstring - name of the GO term to lookup in fileNm
 *             (If no command-line parameters are specified, the file
 *               will revert to an interactive mode)
 * Returns:    None.  Output is sent directly to standard out
 *
 ************************************************************************/
     public static void main(String args[]) throws Exception {
 
	  String fileNm = new String();
	  String lkstring = new String();
	  
	  // when arguments are given from command line 
	  if (args.length > 0) { 
	       if ((args.length == 1) || (args.length > 2)) {
		    // DEBUGGING SHORT-CUT
		    //   (Some default parameters for lazy programmers)

		    // args = new String[2];
		    // args[0] = new String("goview/component.ontology");
 		    // args[1] = new String("collagen"); 
		    
		    System.out.println("Error.");
		    System.out.println("Program should be called as:");
		    System.out.println("FileReaderDemo");
		    System.out.println("FileReaderDemo file string");
		    return;
	       }
	       else {
		    fileNm = args[0];
		    //System.out.println("fileNm" + fileNm);
		    lkstring = args[1];
		    //System.out.println("lkstring" + lkstring);  
		    commandLine = true;
	       }
	  }

	  // prompt for a GO File name in interactive mode
	  if (!commandLine) { 
	       System.out.print ("Enter file name: ");
	       fileNm = in.readLine();
	  }
 

	  File fl = new File(fileNm);
	  if (! fl.exists()) {
	       System.out.println("Unable to locate the specified file \"" 
				  + fileNm + "\"");
	       return;
	  }

	  // read the file and create a tree structure for the GO terms
	  FileReader fr = new FileReader(fl);
	  GOTree goTree = null;
	  try {
	       goTree = new GOTree(fr);
	  }
	  catch (Exception exc) {
	       System.err.println("An error occurred while trying to "
				  + "create GOTree");
	       exc.printStackTrace();
	       System.err.println("\nNote: This is a controlled exit from an "
				  + "non-coding, runtime error that requires\n"
				  + "human intervention to correct.\n"
				  + "It is probably due to a directory name "
				  + "specified in place of an .ontology "
				  + "file.\n"
				  + "For reference, this was passed as the "
				  + "filename: \"" 
				  + fileNm + "\"");
	       return;
	  }
     
	  do { // repeat this loop while in interactive mode

	       String lookup = new String();

	       if (!commandLine) { // prompt the user for a GO term to locate
		    System.out.println(); 
		    System.out.println("Enter string to search for or quit to exit:"); 
		    lookup = in.readLine();
		    System.out.println();
	       }
	       else {
		    lookup = lkstring;
	       }
	       
	       if (lookup.trim().length() == 0) {
		    System.out.println("string to search for must be nonempty");
		    continue; 
	       }   
	       Vector processedNodes = new Vector();

	       BufferedReader br = new BufferedReader(fr);
	       String s;
	       char ch;

	       // check for a quit signal from the user
	       if (lookup.equalsIgnoreCase("quit")) {
		    break;
	       } 

	       // number of lines printer on the screen
	       //   obsolete variable?
	       int printNo = 0;

	       // parse the string for regular expressions
	       Postfix pslookup = new Postfix (lookup);

	       String output = new String();
	       output = retrieveNodesOld(output, pslookup, goTree);	  
	       System.out.print(output);
      
	  } while(true && !commandLine);
	  fr.close();
     } // end main()

/*************************************************************************
 *
 * Method:     cleanLine()
 * Purpose:    Removes parents and anything else that is on the line
 *              retrieved from the flat file.  Thus, when displayed
 *              the user will see the GO entry only
 * Parameters: String line - a from the GO flat-text file
 * Returns:    String - the cleaned out line
 *
 ************************************************************************/
public static String cleanLine(String line) {

     String trimS = new String();

     trimS = line.trim();
     int ind1 = trimS.indexOf(" < ");
     int ind2 = trimS.indexOf(" % ");

     // locate < or & symbol within the string, and remove all contents
     //   starting from that point to the end of the line
     if ((ind1 != -1) && (ind2 != -1)) {
	  if (ind1 <= ind2) {
	       trimS = new String(trimS.substring(0,ind1));
	  }
	  else {
	       trimS = new String(trimS.substring(0,ind2));
	  }
     }
     else {
	  if ((ind1 != -1) && (ind2 == -1)){
	       trimS = new String(trimS.substring(0,ind1)); 
	  } 
	  else {
	       if ((ind2 != -1)  && (ind1 == -1)){
		    trimS = new String(trimS.substring(0,ind2));
	       }
	  }
     }
     return trimS;
}

/*************************************************************************
 *
 * Method:     retrieveNodesOld()
 * Purpose:    Retrieves nodes from the GO Tree according to the specified
 *             lookup string.
 * Parameters: String output - previous String containing output (this
 *               method will append to it and send the information back
 *               to the calling class
 *             Postfix pslookup - a regular expression representation of
 *               the lookup string specified by the user; accounts of
 *               compound queries (operators such as "AND", "NOT" and "OR")
 *             GOTree - the tree containing the GO tree structure as created
 *               from the flat file.
 * Returns:    String - same as input String output parameter, but with
 *               new node data appended to the end of it
 *
 ************************************************************************/

  public static String retrieveNodesOld(String output,
					Postfix pslookup,
					GOTree goTree) {
       Vector processedNodes = new Vector();
       
       // real variables
       int printNo = 0; // number of lines printed on the screen so far
       Enumeration nodeKeys = goTree.getAllNodeKeys();

       // iteration through the list of all nodes
  read:
       while (nodeKeys.hasMoreElements() ) {
	    
	    String nodeKey = (String) nodeKeys.nextElement();
	    
	    // remove parents from the line .... 
	    Node prt = goTree.getNode(nodeKey);
	    String trimS = cleanLine(prt.getFlatFileLine());
       
	    // check if lookup is in this line 
	    if (pslookup.getPostfixValue(trimS)) {

		 if (processedNodes.contains(trimS) ) {
		      continue read;
		 }
	    
		 // output += "  Adding node " + prt.getDesc() + "\n";
		 processedNodes.addElement(prt.getDesc());
		 
		 if (!commandLine) {
		      if (printNo < pageSize) {
		      } // END if (printNo < pageSize)
		      else {
			   System.out.println(output);
			   output = new String();
			   // hit return to get more info
			   System.out.print("Hit return to continue or q " + 
					    "to quit display:"); 
			   try {
				String entry = in.readLine();
				if (entry.equals("q"))
				     break read;		      
			   }
			   catch (java.io.IOException ioExc) {
				System.err.println("IOException encountered in FileReaderDemo::retrieveNodesOld\n");
				ioExc.printStackTrace();
			   }

			   printNo = 0; 
		      } // END else (printNo < pageSize)
		      output += goTree.getParentsString(prt);
		      output += goTree.getPartOfString(prt);
		      output += goTree.getNodeDescString(prt);
		      output += goTree.getChildrenString(prt);
		      output += goTree.getPartsString(prt);
		      
		      printNo += (prt.getParentCount() 
				  + prt.getPartsCount()
				  + 1
				  + prt.getChildrenCount()
				  + prt.getPartsCount());

		 } // END if (!commandLine)
		 else {
		      output += goTree.getParentsString(prt);
		      output += goTree.getPartOfString(prt);
		      output += goTree.getNodeDescString(prt);
		      output += goTree.getChildrenString(prt);
		      output += goTree.getPartsString(prt);

		 } // END else (!commandLine)

		 output += "\n";
		 printNo++;	    
	    } //  END if (pslookup.getPostfixValue(trimS)) 	    
       } // END while ((s=br.readLine()) != null && (!s.equals("$")))	

       return output;

   } // END public static String retrieveNodesOld()
} // END public class FileReaderDemo