/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hssf.record.cont;

import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.util.DelayableLittleEndianOutput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;

/**
 * An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s.
 * This class keeps track of how much remaining space is available in the current BIFF record and
 * can start new {@link ContinueRecord}s as required.
 */
public final class ContinuableRecordOutput implements LittleEndianOutput {

	private final LittleEndianOutput _out;
	private UnknownLengthRecordOutput _ulrOutput;
	private int _totalPreviousRecordsSize;

	public ContinuableRecordOutput(LittleEndianOutput out, int sid) {
		_ulrOutput = new UnknownLengthRecordOutput(out, sid);
		_out = out;
		_totalPreviousRecordsSize = 0;
	}

	public static ContinuableRecordOutput createForCountingOnly() {
		return new ContinuableRecordOutput(NOPOutput, -777); // fake sid
	}

	/**
	 * @return total number of bytes written so far (including all BIFF headers)
	 */
	public int getTotalSize() {
		return _totalPreviousRecordsSize + _ulrOutput.getTotalSize();
	}
	/**
	 * Terminates the last record (also updates its 'ushort size' field)
	 */
	void terminate() {
		_ulrOutput.terminate();
	}
	/**
	 * @return number of remaining bytes of space in current record
	 */
	public int getAvailableSpace() {
		return _ulrOutput.getAvailableSpace();
	}

	/**
	 * Terminates the current record and starts a new {@link ContinueRecord} (regardless
	 * of how much space is still available in the current record).
	 */
	public void writeContinue() {
		_ulrOutput.terminate();
		_totalPreviousRecordsSize += _ulrOutput.getTotalSize();
		_ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid);
	}
	/**
	 * Will terminate the current record and start a new {@link ContinueRecord}
	 *  if there isn't space for the requested number of bytes
	 * @param requiredContinuousSize The number of bytes that need to be written
	 */
	public void writeContinueIfRequired(int requiredContinuousSize) {
		if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) {
			writeContinue();
		}
	}

	/**
	 * Writes the 'optionFlags' byte and encoded character data of a unicode string.  This includes:
	 * <ul>
	 * <li>byte optionFlags</li>
	 * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
	 * </ul>
	 *
	 * Notes:
	 * <ul>
	 * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
	 * of <tt>text</tt></li>
	 * <li>The string options flag is never separated (by a {@link ContinueRecord}) from the
	 * first chunk of character data it refers to.</li>
	 * <li>The 'ushort length' field is assumed to have been explicitly written earlier.  Hence,
	 * there may be an intervening {@link ContinueRecord}</li>
	 * </ul>
	 */
	public void writeStringData(String text) {
		boolean is16bitEncoded = StringUtil.hasMultibyte(text);
		// calculate total size of the header and first encoded char
		int keepTogetherSize = 1 + 1; // ushort len, at least one character byte
		int optionFlags = 0x00;
		if (is16bitEncoded) {
			optionFlags |= 0x01;
			keepTogetherSize += 1; // one extra byte for first char
		}
		writeContinueIfRequired(keepTogetherSize);
		writeByte(optionFlags);
		writeCharacterData(text, is16bitEncoded);
	}
	/**
	 * Writes a unicode string complete with header and character data.  This includes:
	 * <ul>
	 * <li>ushort length</li>
	 * <li>byte optionFlags</li>
	 * <li>ushort numberOfRichTextRuns (optional)</li>
	 * <li>ushort extendedDataSize (optional)</li>
	 * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
	 * </ul>
	 *
	 * The following bits of the 'optionFlags' byte will be set as appropriate:
	 * <table border='1'>
	 * <tr><th>Mask</th><th>Description</th></tr>
	 * <tr><td>0x01</td><td>is16bitEncoded</td></tr>
	 * <tr><td>0x04</td><td>hasExtendedData</td></tr>
	 * <tr><td>0x08</td><td>isRichText</td></tr>
	 * </table>
	 * Notes:
	 * <ul>
	 * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
	 * of <tt>text</tt></li>
	 * <li>The string header fields are never separated (by a {@link ContinueRecord}) from the
	 * first chunk of character data (i.e. the first character is always encoded in the same
	 * record as the string header).</li>
	 * </ul>
	 */
	public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) {
		boolean is16bitEncoded = StringUtil.hasMultibyte(text);
		// calculate total size of the header and first encoded char
		int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte
		int optionFlags = 0x00;
		if (is16bitEncoded) {
			optionFlags |= 0x01;
			keepTogetherSize += 1; // one extra byte for first char
		}
		if (numberOfRichTextRuns > 0) {
			optionFlags |= 0x08;
			keepTogetherSize += 2;
		}
		if (extendedDataSize > 0) {
			optionFlags |= 0x04;
			keepTogetherSize += 4;
		}
		writeContinueIfRequired(keepTogetherSize);
		writeShort(text.length());
		writeByte(optionFlags);
		if (numberOfRichTextRuns > 0) {
			writeShort(numberOfRichTextRuns);
		}
		if (extendedDataSize > 0) {
			writeInt(extendedDataSize);
		}
		writeCharacterData(text, is16bitEncoded);
	}


	private void writeCharacterData(String text, boolean is16bitEncoded) {
		int nChars = text.length();
		int i=0;
		if (is16bitEncoded) {
			while(true) {
				int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2);
				for ( ; nWritableChars > 0; nWritableChars--) {
					_ulrOutput.writeShort(text.charAt(i++));
				}
				if (i >= nChars) {
					break;
				}
				writeContinue();
				writeByte(0x01);
			}
		} else {
			while(true) {
				int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1);
				for ( ; nWritableChars > 0; nWritableChars--) {
					_ulrOutput.writeByte(text.charAt(i++));
				}
				if (i >= nChars) {
					break;
				}
				writeContinue();
				writeByte(0x00);
			}
		}
	}

	public void write(byte[] b) {
		writeContinueIfRequired(b.length);
		_ulrOutput.write(b);
	}

	public void write(byte[] b, int offset, int len) {

        int i=0;
        while(true) {
            int nWritableChars = Math.min(len - i, _ulrOutput.getAvailableSpace() / 1);
            for ( ; nWritableChars > 0; nWritableChars--) {
                _ulrOutput.writeByte(b[offset + i++]);
            }
            if (i >= len) {
                break;
            }
            writeContinue();
        }
	}

	public void writeByte(int v) {
		writeContinueIfRequired(1);
		_ulrOutput.writeByte(v);
	}
	public void writeDouble(double v) {
		writeContinueIfRequired(8);
		_ulrOutput.writeDouble(v);
	}
	public void writeInt(int v) {
		writeContinueIfRequired(4);
		_ulrOutput.writeInt(v);
	}
	public void writeLong(long v) {
		writeContinueIfRequired(8);
		_ulrOutput.writeLong(v);
	}
	public void writeShort(int v) {
		writeContinueIfRequired(2);
		_ulrOutput.writeShort(v);
	}

	/**
	 * Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only.
	 */
	private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() {

		public LittleEndianOutput createDelayedOutput(int size) {
			return this;
		}
		public void write(byte[] b) {
			// does nothing
		}
		public void write(byte[] b, int offset, int len) {
			// does nothing
		}
		public void writeByte(int v) {
			// does nothing
		}
		public void writeDouble(double v) {
			// does nothing
		}
		public void writeInt(int v) {
			// does nothing
		}
		public void writeLong(long v) {
			// does nothing
		}
		public void writeShort(int v) {
			// does nothing
		}
	};
}
