/* ExternalApplication.java
 *
 * created: Mon Jul 17 2000
 *
 * This file is part of Artemis
 *
 * Copyright (C) 2000  Genome Research Limited
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /nfs/disk222/yeastpub/Repository/powmap/diana/ExternalApplication.java,v 1.1 2000/07/24 13:44:00 kmr Exp $
 */

package diana;

import java.io.*;
import java.text.*;

import uk.ac.sanger.pathogens.*;

import uk.ac.sanger.pathogens.embl.EntryInformationException;

/**
 *  An ExternalProgram that launches an application, giving it a feature and
 *  the sequence of the feature.
 *
 *  @author Kim Rutherford <kmr@sanger.ac.uk>
 *  @version $Id: ExternalApplication.java,v 1.1 2000/07/24 13:44:00 kmr Exp $
 **/

public class ExternalApplication extends ExternalProgram {
  /**
   *  Create a ExternalApplication with the given name.
   **/
  public ExternalApplication (final String name) {
    super (name);
  }

  /**
   *  Run the program for each of the given features.
   *  @param features The program will be run for each of these features.
   *  @return The Process object that is running the search or null if there
   *    is nothing to be done (for example if the FeatureVector is empty).
   *  @exception IOException Thrown if an IO error occur while trying to run
   *    the program (eg the program could not be found).
   *  @exception ExternalProgramException Thrown if there is a non-IO error
   *    while attempting to run the program.
   **/
  public Process run (final FeatureVector features)
      throws IOException, ExternalProgramException, EntryInformationException {

    try {
      if (features.size () == 0) {
        return null;
      }

      makeDirectory (new File (getName ()));

      final StringVector sequence_file_names = new StringVector ();

      final NumberFormat number_format = NumberFormat.getNumberInstance ();

      number_format.setMaximumIntegerDigits (5);
      number_format.setMinimumIntegerDigits (5);
      number_format.setGroupingUsed (false);

      // The number to use to for the first sequence file name
      final int old_file_number = getFileNumber ();

      setFileNumber (old_file_number + features.size ());

      // write the features
      for (int i = 0 ; i < features.size () ; ++i) {
        final Feature feature = features.elementAt (i);

        final String entry_name;

        {
          final String test_name = feature.getEntry ().getName ();
          if (test_name == null) {
            entry_name = "no_name";
          } else {
            entry_name = test_name;
          }
        }

        final String new_file_name =
          getName () + File.separatorChar + entry_name + ".seq." +
          number_format.format (old_file_number + i);

        sequence_file_names.add (new_file_name);

        final Writer writer = new FileWriter (new File (new_file_name));

        feature.writeNative (writer);

        writer.close ();
      }

      // write the feature file names to a file and then run the program with
      // that file as an argument
      final String file_of_filenames_name = getName () + File.separatorChar +
        "file_of_filenames." + old_file_number;

      final Writer filenames_writer = new FileWriter (file_of_filenames_name);

      final PrintWriter filenames_printwriter =
        new PrintWriter (filenames_writer);

      for (int i = 0 ; i < sequence_file_names.size () ; ++i) {
        filenames_printwriter.println (sequence_file_names.elementAt (i));
      }

      filenames_printwriter.close ();
      filenames_writer.close ();

      final String [] arguments = {
        file_of_filenames_name
      };

      final Process process =
        startProgram ("run_" + getName (), arguments);

      return process;
    } catch (SecurityException e) {
      // re-throw as an ExternalProgramException
      throw new ExternalProgramException ("SecurityException while running " +
                                          getName () + ": " + e.getMessage ());
    }
  }
}
