/*
 * This file is part of Nuts Framework.
 * Copyright (C) 2009 Nuts Develop Team.
 *
 * Nuts Framework 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 3 of the License any later version.
 * 
 * Nuts Framework 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 Nuts Framework. If not, see <http://www.gnu.org/licenses/>.
 */
package nuts.exts.vfs.ndfs;

import java.io.IOException;
import java.io.OutputStream;

/**
 * OutputStream to a RamFile
 */
public class NdfsFileOutputStream extends OutputStream {

	/**
	 * File
	 */
	protected NdfsFileObject file;

	/**
	 * buffer1
	 */
	protected byte[] buffer1 = new byte[1];

	protected boolean dirty;
	protected boolean closed;

	private IOException error;

	/**
	 * @param file file object
	 * @param append append mode
	 */
	public NdfsFileOutputStream(NdfsFileObject file, boolean append) {
		super();

		this.file = file;
		
		closed = false;
		if (append) {
			dirty = false;
		}
		else {
			file.getFile().setData(new byte[0]);
			file.getFile().setLength(0L);
			dirty = true;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.io.DataOutput#write(byte[], int, int)
	 */
	public void write(byte[] b, int off, int len) throws IOException {
		int size = file.getFile().getLength().intValue();
		int newSize = size + len;
		// Store the Exception in order to notify the client again on close()
		try {
			file.resize(newSize);
		}
		catch (Throwable e) {
			error = new IOException(e);
			throw error;
		}
		System.arraycopy(b, off, file.getFile().getData(), size, len);
		dirty = true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.io.DataOutput#write(int)
	 */
	public void write(int b) throws IOException {
		buffer1[0] = (byte)b;
		write(buffer1);
	}

	public void flush() throws IOException {
	}

	public void close() throws IOException {
		if (closed) {
			return;
		}
		// Notify on close that there was an IOException while writing
		if (error != null) {
			throw error;
		}
		try {
			closed = true;
			// Close the
			file.saveData(dirty);
		}
		catch (Exception e) {
			throw new IOException(e);
		}
	}

}
