/*
 * Note: These examples use the old version 1 Java netCDF interface,
 * which we do not recommend for new development. Instead, please use
 * NetCDF Java Library (Version 2), which is more efficient, simpler,
 * and provides better support for remote access using HTTP or
 * DODS. Similar examples are available in the NetCDF Java (version 2)
 * User's Manual.
 */

package ucar.demo;

import ucar.netcdf.NetcdfFile;
import ucar.netcdf.Netcdf;
import ucar.netcdf.Variable;
import ucar.netcdf.VariableIterator;

import java.io.IOException;
import ucar.multiarray.*;

/** 
 * Simple example to print contents of an existing netCDF file of
 * unknown structure, much like ncdump.  A difference is the nesting of
 * multidimensional array data is represented by nested brackets, so the
 * output is not legal CDL that can be used as input for ncgen.
 *
 * @author: Russ Rew
 * @version: $Id: DumpNetcdf.java,v 1.9 1998/07/17 15:24:32 russ Exp $ */
public class DumpNetcdf {

    static String fileName;

    /** 
     * Prints schema (structure) of an existing netCDF file with a
     * specified file name.
     *
     * @param args name of netCDF file to be read.  */
    public static void main(String[] args) {
	
	if (args.length == 1)
	    fileName = args[0];
	else {
	    System.err.println("no netCDF file name specified, exiting ...");
	    System.exit(-1);
	}

	try {
	    Netcdf nc = new NetcdfFile(fileName, true); // open it readonly
	    System.out.println(nc); // output schema in CDL form (like ncdump)
	    System.out.println("data:");
	    VariableIterator vi = nc.iterator();
	    while(vi.hasNext()) {
		Variable var = vi.next();
		MultiArray varMa =
		var.copyout(new int[var.getRank()],
			    var.getLengths());
		System.out.print(var.getName() + " =");
		System.out.println(MultiArrayToString(var));		
	    }

	} catch (java.io.IOException e) {
	    e.printStackTrace();
	}

    }


    public static String
    MultiArrayToString(MultiArray ma) {
	StringBuffer buf = new StringBuffer();
	try {
	    buf.append(MultiArrayToStringHelper(ma, new IndentLevel()));
	} catch (java.io.IOException e) {
	    e.printStackTrace();
	}
	return buf.toString();
    }

    /**
     * Maintains indentation level for printing nested structures.
     */
    static class IndentLevel {
	private int level = 0;
	private int indentation;
	private StringBuffer indent;
	private StringBuffer blanks;

	public IndentLevel() {
	    this(4);
	}
    
	public IndentLevel(int indentation) {
	    if (indentation > 0)
		this.indentation = indentation;
	    indent = new StringBuffer();
	    blanks = new StringBuffer();
	    for (int i=0; i < indentation; i++)
		blanks.append(" ");
	}

	public void incr() {
	    level += indentation;
	    indent.append(blanks);
	}

	public void decr() {
	    level -= indentation;
	    indent.setLength(level);
	}
    
	public String getIndent() {
	    return indent.toString();
	}
    }

    private static String
    MultiArrayToStringHelper(MultiArray ma, IndentLevel ilev)
	throws java.io.IOException{ // no I/O here, so this won't really happen
	
	final int rank = ma.getRank();
	if (rank == 0) {
	    try {
		return ma.get((int[])null).toString();
	    } catch (IOException ee) {
	    }
	}
	StringBuffer buf = new StringBuffer();
	buf.append("\n" + ilev.getIndent() + "{");
	ilev.incr();
	final int [] dims = ma.getLengths();
	final int last = dims[0];
	for(int ii = 0; ii < last; ii++)
	{
	    final MultiArray inner =
		new MultiArrayProxy(ma, new SliceMap(0, ii));
	    buf.append(MultiArrayToStringHelper(inner, ilev));
	    if(ii != last - 1)
		buf.append(", ");
	}
	ilev.decr();
	if (rank > 1) {
	    buf.append("\n" + ilev.getIndent());
	}
	buf.append("}");
	
	return buf.toString();
    }    
}
