/* Generated by Together */

package org.mbari.seepsearch.grid;

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

/**
 * <p>Writes Grid data (from a <i>RasterGrid</i>) to an ascii raster format that
 * is compatible with many GIS tools.</p><hr><br>
 *
 * <p>29 Jan 2001 - Tested output to make sure that a round trip from File,
 * to a RasterGrid via AsciiRasterGridReader and back out to a file via
 * AsciiRasterGridWriter generate the same cooridnates. Used ArcGIS for testing
 * and had an excellent match. There is some difference in the xllcorner, yllcorner
 * and cellsize but it's so far down in the decimal places that it doesn't
 * effct the display in ArcView at all. These differences are probably due to
 * rounding errors cuased by machine precision limits.</p>
 *
 * <p>MBARI provides this documentation and code &quot;as is&quot;, with no
 * warranty, express or implied, of its quality or consistency. It is provided
 * without support and without obligation on the part of the Monterey Bay
 * Aquarium Research Institute to assist in its use, correction, modification,
 * or enhancement. This information should not be published or distributed to
 * third parties without specific written permission from MBARI.</p><br>
 *
 * Copyright 2002 MBARI.<br>
 * MBARI Proprietary Information. All rights reserved.<br><hr><br>
 *
 * $Log: AsciiRasterGridWriter.java,v $
 * Revision 1.7  2002/01/30 00:23:56  brian
 * Added comments to all classes and methods. Tested the accuracy of AsciiRasterGridReader and AsciiRasterGridWriter. Also checked the the GridUtil was populating the spatial grids correctly and accurately. The data files generated matched up perfectly with the orginal text files. Also implemented an RovAltitudeFilter class to encapsulate different filtering methods.
 *<br><hr><br>
 *
 * @author  : $Author: brian $
 * @version : $Revision: 1.7 $
 */
public class AsciiRasterGridWriter {

    public AsciiRasterGridWriter(File file) {
        this.file = file;
    }

    public AsciiRasterGridWriter(String filename) {
        this(new File(filename));
    }

    /**
     * @param grid The grid containing the data to write to an ascii file.
     * The dataPrecision default is 4 decimal places, while the axisPrecision
     * is 8 decimal places.
     */
    public void write(RasterGrid grid) throws IOException {
        write(grid, 4, 8);
    }

    /**
     * @param grid The grid containing the data to write to an ascii file
     * @param dataPrecision The number of fractional digits that the data will
     * contain. The axisPrecision will be set to this also.
     *
     */
    public void write(RasterGrid grid, int dataPrecision) throws IOException {
        write(grid, dataPrecision, dataPrecision);
    }


    /**
     * @param grid The grid containing the data to write to an ascii file
     * @param dataPrecision The number of fractional digits that the data will
     * contain
     * @param axisPrecision The number of fractional digits that the axis data
     * (xllcorner and yllcorner) should contain.
     */
    public void write(RasterGrid grid, int dataPrecision, int axisPrecision) throws IOException {
        if (file == null) {
            throw new IOException("Output file is null. Unable to create " +
                    file.getCanonicalFile());
        }

        if (grid == null) {
            throw new IllegalArgumentException("RasterGrid object is null. " +
                    "Unable to create " + file.getCanonicalFile());
        }

        final BufferedWriter out = new BufferedWriter(new FileWriter(file));


        final NumberFormat nfInt = new DecimalFormat();
        nfInt.setGroupingUsed(false);
        nfInt.setMaximumFractionDigits(0);
        nfInt.setMinimumIntegerDigits(1);

        out.write("ncols " + nfInt.format((double) grid.getX().length) + "\n");
        out.write("nrows " + nfInt.format((double) grid.getY().length) + "\n");

        final NumberFormat nfFloat = new DecimalFormat();
        nfFloat.setGroupingUsed(false);

        nfFloat.setMaximumFractionDigits(axisPrecision);
        nfFloat.setMinimumFractionDigits(axisPrecision);
        final double[] x = grid.getX();
        final double[] y = grid.getY();
        out.write("xllcorner " + nfFloat.format(x[0]) + "\n");
        out.write("yllcorner " + nfFloat.format(y[y.length - 1]) + "\n");
        nfFloat.setMaximumFractionDigits(dataPrecision);
        nfFloat.setMinimumFractionDigits(dataPrecision);

        double cellSize = (x[x.length - 1] - x[0])/(x.length - 1);
        out.write("cellsize " + cellSize + "\n");

        String noDataValue = "-9999";
        out.write("nodata_value " + noDataValue + "\n");

        float[][] z = grid.getZ();
        for (int r = 0; r < y.length; r++) {
            for (int c = 0; c < x.length; c++) {
                if (Float.isNaN(z[r][c])) {
                    out.write(noDataValue + " ");
                } else {
                    out.write(nfFloat.format(z[r][c]) + " ");
                }
            }
            out.newLine();
        }

        out.flush();
        out.close();

    }

    File file;
}
