package de.lmu.ifi.dbs.elki.result;

import java.io.File;
import java.io.IOException;
import java.util.List;

import de.lmu.ifi.dbs.elki.data.DatabaseObject;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.normalization.Normalization;
import de.lmu.ifi.dbs.elki.result.textwriter.MultipleFilesOutput;
import de.lmu.ifi.dbs.elki.result.textwriter.SingleStreamOutput;
import de.lmu.ifi.dbs.elki.result.textwriter.StreamFactory;
import de.lmu.ifi.dbs.elki.result.textwriter.TextWriter;
import de.lmu.ifi.dbs.elki.utilities.UnableToComplyException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AttributeSettings;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;

/**
 * Result handler that feeds the data into a TextWriter
 * 
 * @author Erich Schubert
 * 
 * @param <O> Object type
 */
public class ResultWriter<O extends DatabaseObject> extends AbstractParameterizable implements ResultHandler<O, Result> {
  /**
   * Optional Parameter to specify the file to write the obtained results in. If
   * this parameter is omitted, per default the output will sequentially be
   * given to STDOUT.
   * <p>
   * Key: {@code -out}
   * </p>
   */
  private final FileParameter OUTPUT_PARAM = new FileParameter(OptionID.OUTPUT, FileParameter.FileType.OUTPUT_FILE, true);

  /**
   * GZIP compression flag
   */
  private final OptionID GZIP_OUTPUT = OptionID.getOrCreateOptionID("out.gzip", "Flag to enable gzip compression of output files.");
  
  /**
   * Flag to control GZIP compression.
   */
  private final Flag GZIP_FLAG = new Flag(GZIP_OUTPUT);
  
  /**
   * Holds the file to print results to.
   */
  private File out;

  /**
   * Normalization to use.
   */
  private Normalization<O> normalization;
  
  /**
   * Whether or not to do gzip compression on output.
   */
  private boolean gzip = false;

  /**
   * Constructor.
   */
  public ResultWriter() {
    super();
    // parameter output file
    addOption(OUTPUT_PARAM);
    addOption(GZIP_FLAG);
  }

  @Override
  public String[] setParameters(String[] args) throws ParameterException {
    String[] remainingParameters = super.setParameters(args);

    // output
    if(OUTPUT_PARAM.isSet()) {
      out = OUTPUT_PARAM.getValue();
    }
    gzip = GZIP_FLAG.isSet();
    setParameters(args, remainingParameters);
    return remainingParameters;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * de.lmu.ifi.dbs.elki.result.ResultHandler#processResult(de.lmu.ifi.dbs.elki
   * .database.Database, de.lmu.ifi.dbs.elki.result.Result, java.util.List)
   */
  public void processResult(Database<O> db, Result result, List<AttributeSettings> settings) {
    TextWriter<O> writer = new TextWriter<O>();
    if(normalization != null) {
      writer.setNormalization(normalization);
    }

    StreamFactory output;
    try {
      if(out == null) {
        output = new SingleStreamOutput(gzip);
      }
      else if(out.exists()) {
        if(out.isDirectory()) {
          if(out.listFiles().length > 0) {
            logger.warning("Output directory specified is not empty. Files will be overwritten and old files may be left over.");
          }
          output = new MultipleFilesOutput(out, gzip);
        }
        else {
          logger.warning("Output file exists and will be overwritten!");
          output = new SingleStreamOutput(out, gzip);
        }
      }
      else {
        // If it doesn't exist yet, make a MultipleFilesOutput.
        output = new MultipleFilesOutput(out, gzip);
      }
    }
    catch(IOException e) {
      throw new IllegalStateException("Error opening output.", e);
    }
    try {
      writer.output(db, result, output, settings);
    }
    catch(IOException e) {
      throw new IllegalStateException("Input/Output error while writing result.", e);
    }
    catch(UnableToComplyException e) {
      throw new IllegalStateException("Unable to comply while writing result.", e);
    }
    output.closeAllStreams();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * de.lmu.ifi.dbs.elki.result.ResultHandler#setNormalization(de.lmu.ifi.dbs
   * .elki.normalization.Normalization)
   */
  public void setNormalization(Normalization<O> normalization) {
    this.normalization = normalization;
  }

  /**
   * Getter for normalization
   * 
   * @return normalization object
   */
  public Normalization<O> getNormalization() {
    return normalization;
  }

}
@@ -1861,24 +1861,334 @@
 );%0A  %0A  /**%0A
+   * Suppress overwrite warning%0A   */%0A  private final OptionID OVERWRITE_OPTION = OptionID.getOrCreateOptionID(%22out.silentoverwrite%22, %22Flag to silently overwrite output files.%22);%0A  %0A  /**%0A   * Flag to suppress overwrite warning.%0A   */%0A  private final Flag OVERWRITE_FLAG = new Flag(OVERWRITE_OPTION);%0A  %0A  /**%0A
    * Holds t
@@ -2216,16 +2216,16 @@
 lts to.%0A
-
    */%0A  
@@ -2424,16 +2424,112 @@
 = false;
+%0A  %0A  /**%0A   * Whether or not to warn on overwrite%0A   */%0A  private boolean warnoverwrite = true;
 %0A%0A  /**%0A
@@ -2675,16 +2675,47 @@
 _FLAG);%0A
+    addOption(OVERWRITE_FLAG);%0A
   %7D%0A%0A  @
@@ -2975,24 +2975,89 @@
 AG.isSet();%0A
+    warnoverwrite = OVERWRITE_FLAG.isSet() != true; // inversed!%0A
     setParam
@@ -3743,24 +3743,41 @@
          if(
+warnoverwrite && 
 out.listFile
@@ -4008,32 +4008,65 @@
 %0A        else %7B%0A
+          if (warnoverwrite) %7B%0A  
           logger
@@ -4118,24 +4118,36 @@
 written!%22);%0A
+          %7D%0A
           ou

Add an option to not warn on overwriting.