package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.io.SaveDialog;
import java.io.*;
import java.util.*;
import java.awt.image.*;

/**
 * This plugin saves grayscale images in PGM (portable graymap) format 
 * and RGB images in PPM (portable pixmap) format. 
 * <p/>
 * These formats, along with PBM (portable bitmap), are collectively known as
 * the PNM format. More information can be found at
 * "http://en.wikipedia.org/wiki/Portable_Pixmap_file_format".
 *
 * @author Johannes Schindelin
 *
 * <p/>
 * Spencer Olson (olsonse.at.umich.edu) January 2007:
 * Extended support to stacks within PNM files.  These are simple
 * concatenations of one slice after another, where each slice is a fully
 * formatted PNM file.
 */
public class PNM_Writer implements PlugIn {

	public void run(String path) {
		ImagePlus img=IJ.getImage();
		boolean isGray = false;
		String extension = null;
		ImageProcessor ip = img.getProcessor();
		if (img.getBitDepth()==24)
			extension = ".pnm";
		else {
			if (img.getBitDepth()==8&& ip.isInvertedLut()) {
				ip = ip.duplicate();
				ip.invert();
			}
			ip = ip.convertToByte(true);
			isGray = true;
			extension = ".pgm";
		}
		String title=img.getTitle();
		int length=title.length();
		for(int i=2;i<5;i++)
			if(length>i+1 && title.charAt(length-i)=='.') {
				title=title.substring(0,length-i);
				break;
			}

		if (path==null || path.equals("")) {
			SaveDialog od = new SaveDialog("PNM Writer", title, extension);
			String dir=od.getDirectory();
			String name=od.getFileName();
			if(name==null)
				return;
			path = dir + name;
		}

		try {
			IJ.showStatus("Writing PNM "+path+"...");
			OutputStream fileOutput =
				new FileOutputStream(path);
			DataOutputStream output =
				new DataOutputStream(fileOutput);

			int w = img.getWidth(), h = img.getHeight();
                        /* BEGIN CHANGES
                         * author:  Spencer Olson
                         * to enable stacks to be written to pnm format (in a
			 * single file)
                         */
                        ImageStack stack = img.getStack();
                        int nSlices = stack.getSize();

                        for (int slice = 1; slice <= nSlices; slice++) {
				if (nSlices > 1) {
					IJ.showStatus("writing: "+slice+"/"+nSlices);
					IJ.showProgress((double)slice/nSlices);
				}

				ImageProcessor sip = stack.getProcessor(slice);
				String label = stack.getSliceLabel(slice);
                                label = (label == null ? "" : label );
				output.writeBytes((isGray ? "P5" : "P6")
						+ "\n# Label : " + label
						+ "\n# Written by ImageJ PNM Writer\n"
						+ w + " " + h + "\n255\n");
				if (isGray)
					output.write(
						(byte[])sip.getPixels(),
						0, w * h);
				else {
					byte[] pixels = new byte[w * h * 3];
					ColorProcessor proc =
						(ColorProcessor)sip;
					for (int j = 0; j < h; j++)
						for (int i = 0; i < w; i++) {
							int c = proc.getPixel(i, j);
							pixels[3 * (i + w * j) + 0] =
								(byte)((c & 0xff0000) >> 16);
							pixels[3 * (i + w * j) + 1] =
								(byte)((c & 0xff00) >> 8);
							pixels[3 * (i + w * j) + 2] =
								(byte)(c & 0xff);
						}
					output.write(pixels, 0, pixels.length);
				}
			}
        		/* END CHANGES by Spencer Olson */
			output.flush();
		} catch(IOException e) {
			e.printStackTrace();
			IJ.error("Error writing file");
		}
		IJ.showStatus("");
	}

};