Index: gli/trunk/src/org/greenstone/gatherer/collection/CollectionManager.java
===================================================================
--- gli/trunk/src/org/greenstone/gatherer/collection/CollectionManager.java	(revision 16130)
+++ gli/trunk/src/org/greenstone/gatherer/collection/CollectionManager.java	(revision 16132)
@@ -76,5 +76,5 @@
 import org.w3c.dom.*;
 
-/** This class manages many aspects of the collection, from its creation via scripts, data access via methods and its importing and building into the final collection. It is also resposible for firing appropriate event when significant changes have occured within the collection, and for creating a new metadata set manager as necessary.
+/** This class manages many aspects of the collection, from its creation via scripts, data access via methods and its importing and building into the final collection. It is also responsible for firing appropriate event when significant changes have occured within the collection, and for creating a new metadata set manager as necessary.
  * @author John Thompson
  * @version 2.3
@@ -87,4 +87,6 @@
     /** Are we currently in the process of importing? */
     static private boolean importing = false;
+    /** Are we currently in the process of scheduling? */ 
+    static private boolean scheduling = false; 
     /** The objects listening for CollectionContentsChanged events. */
     static private ArrayList collection_contents_changed_listeners = new ArrayList();
@@ -97,8 +99,10 @@
     /** An inner class listener responsible for noting tree changes and resetting saved when they occur. */
     static private FMTreeModelListener fm_tree_model_listener = null;
-    /** The monitor resposible for parsing the build process. */
+    /** The monitor responsible for parsing the build process. */
     static private GShellProgressMonitor build_monitor = null;
-    /** The monitor resposible for parsing the import process. */
+    /** The monitor responsible for parsing the import process. */
     static private GShellProgressMonitor import_monitor = null;
+    /** The monitor responsible for parsing the scheduler process. */ 
+    static private GShellProgressMonitor schedule_monitor = null; 
 
     /** The name of the standard lock file. */
@@ -109,4 +113,6 @@
     /** Used to indicate the source of the message is the building methods. */
     static final public int BUILDING  = 5;
+    /** Used to indicate the source of the message is in the scheduling methods...?  */ 
+    static final public int SCHEDULING = 7; 
 
   
@@ -116,4 +122,5 @@
 	this.building = false;
 	this.importing = false;
+	this.scheduling = false; 
 	this.collection = null;
 
@@ -209,4 +216,104 @@
     }
 
+    /*probably repeating alot of work, but I want to keep this separate... wendy*/
+    public void scheduleBuild(boolean incremental_build)
+    {
+
+	DebugStream.println("In CollectionManager.scheduleBuild(), incremental_build: " + incremental_build); 
+	DebugStream.println("Is event dispatch threa: " + SwingUtilities.isEventDispatchThread()); 
+
+	ArrayList sched_list = new ArrayList(); 
+	if ((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
+	    sched_list.add(Configuration.perl_path);
+	    sched_list.add("-S");
+	}
+	sched_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "schedule.pl"); 
+	sched_list.add("-colname"); 
+	sched_list.add(collection.getName()); 
+	sched_list.add("-gli"); 
+
+	// First, generate the import.pl command, also converting to a string
+	// Generate the import.pl command
+	ArrayList import_list = new ArrayList();
+	if ((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
+	    import_list.add(Configuration.perl_path);
+	    import_list.add("-S");
+	}
+        import_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "import.pl");
+	import_list.add("-language");
+	import_list.add(Configuration.getLanguage());
+	import_list.add("-collectdir");
+	import_list.add(getCollectDirectory());
+
+	String[] import_options = collection.import_options.getValues();
+	int i = 0; 
+	for (i = 0; i < import_options.length; i++) {
+	    import_list.add(import_options[i]);
+	}
+
+	import_list.add(collection.getName());	
+
+	String[] import_parts = (String[]) import_list.toArray(new String[0]); 
+	String command = "";
+	i = 0; 
+	for (i = 0; i < import_parts.length-1; i++) {
+	    command = command + import_parts[i] + " "; 
+	} 
+	command = command + import_parts[i]; 
+
+	sched_list.add("-import"); 
+	sched_list.add("\"" + command + "\""); 
+
+	// Generate the buildcol.pl command, also converting to a string
+	ArrayList build_list = new ArrayList();
+
+	// i'm not doing this in schedule.pl right now - should i be? 
+	if ((Utility.isWindows()) && (!Gatherer.isGsdlRemote)) {
+	    build_list.add(Configuration.perl_path);
+	    build_list.add("-S");
+	}
+	build_list.add(LocalGreenstone.getBinScriptDirectoryPath() + "buildcol.pl");
+	build_list.add("-language");
+	build_list.add(Configuration.getLanguage());
+	build_list.add("-collectdir");
+	build_list.add(getCollectDirectory());
+
+	// If the user hasn't manually specified "-keepold" or "-removeold" then pick one based on incremental_build
+	if (!collection.build_options.getValueEnabled("keepold") && !collection.build_options.getValueEnabled("removeold")) {
+	    build_list.add(incremental_build ? "-keepold" : "-removeold");
+	}
+
+	String[] build_options = collection.build_options.getValues();
+	for (i = 0; i < build_options.length; i++) {
+	    build_list.add(build_options[i]);
+	}
+
+	build_list.add(collection.getName());
+	
+	//build actual string
+	String[] build_parts = (String[]) build_list.toArray(new String[0]);
+	String command2 = "";
+        for(i = 0; i < build_parts.length-1; i++) {
+            command2 = command2 + build_parts[i] + " ";
+        }
+	command2 = command2 + build_parts[i]; 
+
+	sched_list.add("-build"); 
+	sched_list.add("\"" + command2 + "\""); 
+	
+	//next, the scheduling frequency goes here
+	String[] schedule_options = collection.schedule_options.getValues();  
+	for(i = 0; i < schedule_options.length; i++) { 
+	    sched_list.add(schedule_options[i]); 
+	}
+
+	//now, hope it will run. ;) 
+	String[] sched_parts = (String[]) sched_list.toArray(new String[0]); 
+
+    	GShell shell = new GShell(sched_parts, GShell.SCHEDULE, SCHEDULING, this, schedule_monitor, GShell.GSHELL_SCHEDULE);
+	shell.addGShellListener(Gatherer.g_man.create_pane);
+	shell.addGShellListener(Gatherer.g_man.format_pane);
+	shell.start();
+    }
 
     /** Used to determine whether the currently active collection has been built.
@@ -450,4 +557,58 @@
 	    collection.import_options.setValue("removeold", true, null);
 
+	    //try to obtain email address of collection owner if it exists... 
+	    String stmp = Configuration.getEmail(); 
+	    if(stmp != null) {
+		collection.schedule_options.setValue("toaddr", false, Configuration.getEmail());
+	    }
+
+	    //try to obtain email address of Greenstone installation webmaster for - used to indicate "sender". 
+	    File mcfg = new File(LocalGreenstone.getDirectoryPath()+"etc" + File.separator + "main.cfg");
+	    BufferedReader maincfg = new BufferedReader(new FileReader(mcfg)); 	    
+	    stmp = "";
+	    String fromaddr = ""; 
+	    while((stmp = maincfg.readLine()) != null) { 
+		if(stmp.startsWith("maintainer")) {
+		       fromaddr = stmp.substring(10); //length of MailServer 
+		   fromaddr = fromaddr.trim();  
+		   break; 
+		}
+	    }
+	    maincfg.close(); 
+	    if(!fromaddr.equals("NULL") && !fromaddr.equals("null")) {
+		collection.schedule_options.setValue("fromaddr", false, fromaddr);	    
+	    }
+
+	    //try to obtain an smtp server address from main.cfg. If that fails,
+	    //try mail.server if an email address exists. If that fails,
+	    //maybe a message to set attribute in main.cfg? 
+	    //i'm pretty sure there exists functionality to do this, but 
+	    //i'll finish this faster if I just wrote it
+
+
+	    maincfg = new BufferedReader(new FileReader(mcfg)); 	  
+	    String smtptmp = "NULL";
+	    while((stmp = maincfg.readLine()) != null) { 
+		if(stmp.startsWith("MailServer")) {
+		       smtptmp = stmp.substring(10); //length of MailServer 
+		   smtptmp = smtptmp.trim(); 
+		   break; 
+		}
+	    }
+            maincfg.close();
+
+            //try if lookup failes
+            if(smtptmp.equals("NULL") || smtptmp.equals("null")) {
+		String email2=fromaddr; 
+		if(!email2.equals("NULL") && !email2.equals("null")) {
+		    int loc = email2.indexOf('@'); 
+		    email2 = email2.substring(loc+1); 
+		    smtptmp = "mail."+email2;
+	        }
+            }
+	    if(!smtptmp.equals("NULL") && !smtptmp.equals("null")) { 
+		collection.schedule_options.setValue("smtp", false, smtptmp);
+	    }
+
 	    MetadataSetManager.clearMetadataSets();
 	    MetadataXMLFileManager.clearMetadataXMLFiles();
@@ -1038,4 +1199,62 @@
 	    }
 
+	    //THIS LOOKS LIKE THE BEST PLACE TO TRY AND UPDATE .col FILES FOR EXISTING COLLECTIONS...Wendy
+ 
+	    //First, see if "Schedule" exists in the XMl File... 
+	    BufferedReader bir = new BufferedReader(new FileReader(collection_file)); 
+	    boolean flag = false; 
+	    try {
+		String stmp = new String(); 
+	       
+		while((stmp = bir.readLine()) != null) {
+		    stmp = stmp.trim();  
+		    if(stmp.equals("<Schedule>") || stmp.equals("<Schedule/>")) {
+		       flag = true; 
+		       break; 
+		    }
+		}
+		bir.close(); 
+
+	    } catch (IOException ioe) {
+		//do something here
+	    }
+
+	    //modify if old .col (i.e. no Schedule exists in XML file)
+	    if(!flag) {
+		File new_collection_file = new File(collection_directory.getAbsolutePath() + "/tmp.col");
+
+
+		BufferedWriter bor = new BufferedWriter(new FileWriter(new_collection_file)); 
+		bir = new BufferedReader(new FileReader(collection_file)); 
+
+		try { 
+		    String stmp = new String(); 
+		    while((stmp = bir.readLine()) != null) {
+			String stmp2 = stmp.trim(); 
+			if(stmp2.startsWith("<!ELEMENT Argument")) {
+			    bor.write("  <!ELEMENT Schedule          (Arguments*)>\n"); 			   
+		        }
+                        else if(stmp2.equals("</BuildConfig>")) {
+                               bor.write("      <Schedule/>\n"); 
+                        }
+
+                        bor.write(stmp + "\n"); 
+
+		    }
+                    bir.close(); 
+                    bor.close();
+                } catch (IOException ioe) {  
+                  //do something here
+                }  
+
+		//copy over tmp.col to replace 
+		try { 
+		collection_file.delete();
+		new_collection_file.renameTo(collection_file); 
+		} catch (Exception e) { 
+		    //do something here 
+		} 
+	    }
+
 	    // Open the collection file
 	    this.collection = new Collection(collection_file);
@@ -1048,4 +1267,66 @@
 		throw(new Exception(Dictionary.get("CollectionManager.Missing_Config"))); // this error message does not agree with the error
 	    }
+
+
+	    //try to obtain email address of collection owner if it exists... 
+	    String stmp = Configuration.getEmail(); 
+	    if(stmp != null) {
+		collection.schedule_options.setValue("toaddr", false, Configuration.getEmail());
+	    }
+
+
+
+	    //The next few items deal with updating the SMTP server, and the to: and from: addresses
+	    //from main.cfg and the collection configuration. if no changes are made, or the 
+	    //values are result to NULL, any existing values are kept. 
+
+	    //try to obtain email address of Greenstone installation webmaster for - used to indicate "sender". 
+	    File mcfg = new File(LocalGreenstone.getDirectoryPath()+"etc" + File.separator + "main.cfg");
+	    BufferedReader maincfg = new BufferedReader(new FileReader(mcfg)); 	    
+	    stmp = "";
+	    String fromaddr = ""; 
+	    while((stmp = maincfg.readLine()) != null) { 
+		if(stmp.startsWith("maintainer")) {
+		       fromaddr = stmp.substring(10); //length of MailServer 
+		   fromaddr = fromaddr.trim();  
+		   break; 
+		}
+	    }
+	    maincfg.close(); 
+	    if(!fromaddr.equals("NULL") && !fromaddr.equals("null")) {
+		collection.schedule_options.setValue("fromaddr", false, fromaddr);	    
+	    }
+
+	    //try to obtain an smtp server address from main.cfg. If that fails,
+	    //try mail.server if an email address exists. If that fails,
+	    //maybe a message to set attribute in main.cfg? 
+	    //i'm pretty sure there exists functionality to do this, but 
+	    //i'll finish this faster if I just wrote it
+
+
+	    maincfg = new BufferedReader(new FileReader(mcfg)); 	  
+	    String smtptmp = "NULL";
+	    while((stmp = maincfg.readLine()) != null) { 
+		if(stmp.startsWith("MailServer")) {
+		       smtptmp = stmp.substring(10); //length of MailServer 
+		   smtptmp = smtptmp.trim(); 
+		   break; 
+		}
+	    }
+            maincfg.close();
+
+            //try if lookup failes
+            if(smtptmp.equals("NULL") || smtptmp.equals("null")) {
+		String email2=fromaddr; 
+		if(!email2.equals("NULL") && !email2.equals("null")) {
+		    int loc = email2.indexOf('@'); 
+		    email2 = email2.substring(loc+1); 
+		    smtptmp = "mail."+email2;
+	        }
+            }
+	    if(!smtptmp.equals("NULL") && !smtptmp.equals("null")) { 
+		collection.schedule_options.setValue("smtp", false, smtptmp);
+	    }
+
 
             MetadataSetManager.clearMetadataSets();
@@ -1203,4 +1484,12 @@
 	    buildCollection(false);
 	}
+	else if(event.getType() == GShell.SCHEDULE && event.getStatus() == GShell.OK ) {
+
+	   	WarningDialog collection_built_warning_dialog = new WarningDialog("warning.ScheduleBuilt", Dictionary.get("ScheduleBuilt.Title"), Dictionary.get("ScheduleBuilt.Message"), null, false);
+  		collection_built_warning_dialog.setMessageOnly(true); // Not a warning
+  		collection_built_warning_dialog.display();
+  		collection_built_warning_dialog.dispose();
+  		collection_built_warning_dialog = null;   
+	} 
 	// If we were running a build, now is when we move files across.
 	else if(event.getType() == GShell.BUILD && event.getStatus() == GShell.OK) {
@@ -1257,4 +1546,7 @@
 	      JOptionPane.showMessageDialog(Gatherer.g_man, errMsg, Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
 	    } 
+	    else if(event.getType() == GShell.SCHEDULE) { 
+		JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Schedule_Failed"), Dictionary.get("CollectionManager.Schedule_Ready_Title"), JOptionPane.ERROR_MESSAGE);
+	    }
 	    else {
 		JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CollectionManager.Preview_Ready_Failed"), Dictionary.get("CollectionManager.Preview_Ready_Title"), JOptionPane.ERROR_MESSAGE);
@@ -1291,4 +1583,8 @@
     public void registerImportMonitor(GShellProgressMonitor monitor) {
 	import_monitor = monitor;
+    }
+
+    public void registerScheduleMonitor(GShellProgressMonitor monitor) { 
+	schedule_monitor = monitor; 
     }
 
