/*
 * 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.
 */

/* $Id$ */

package org.apache.fop.render.pdf.pdfbox;

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

import org.apache.commons.io.output.CountingOutputStream;

import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFObject;
import org.apache.fop.pdf.PDFText;

/**
 * Special PDF object for strings that goes beyond FOP's {@link PDFText} class.
 */
public class PDFString extends PDFObject {

    private String text;
    private byte[] binary;

    /**
     * Creates a new String.
     * @param text the text
     */
    public PDFString(String text) {
        this.text = text;
    }

    /**
     * Creates a new String.
     * @param data the text data as byte array
     */
    public PDFString(byte[] data) {
        this.binary = data;
    }

    /**
     * Returns the string as a Unicode string.
     * @return the string
     */
    public String getString() {
        if (this.text == null) {
            String encoding = "ISO-8859-1";
            int start = 0;
            if (this.binary.length > 2) {
                if (this.binary[0] == (byte)0xFF && this.binary[1] == (byte)0xFE) {
                    encoding = "UTF-16LE";
                    start = 2;
                } else if (this.binary[0] == (byte)0xFE && this.binary[1] == (byte)0xFF) {
                    encoding = "UTF-16BE";
                    start = 2;
                }
            }
            try {
                this.text = new String(this.binary, start, this.binary.length - start, encoding);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("Incompatible JVM: " + e.getMessage());
            }
        }
        return this.text;
    }

    /**
     * Returns the string as binary data.
     * @return the binary representation
     */
    public byte[] getBinary() {
        if (this.binary == null) {
            boolean unicode16 = false;
            char[] chars = this.text.toCharArray();
            int length = chars.length;
            for (int i = 0; i < length; i++) {
                if (chars[i] > 255) {
                    unicode16 = true;
                    break;
                }
            }
            try {
                byte[] binary;
                if (unicode16) {
                    byte[] data = this.text.getBytes("UTF-16BE");
                    binary = new byte[data.length + 2];
                    binary[0] = (byte)0xFE;
                    binary[1] = (byte)0xFF;
                    System.arraycopy(data, 0, binary, 2, data.length);
                } else {
                    byte[] data = this.text.getBytes("ISO-8859-1");
                    binary = new byte[data.length];
                    System.arraycopy(data, 0, binary, 0, data.length);
                }
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("Incompatible JVM: " + e.getMessage());
            }
        }
        return this.binary;
    }

    @Override
    public int output(OutputStream stream) throws IOException {
        CountingOutputStream cout = new CountingOutputStream(stream);
        PDFDocument.flushTextBuffer(new StringBuilder(PDFText.escapeText(getString())), cout);
        return cout.getCount();
    }

    /**
     * Indicates whether the given binary data contains only US-ASCII characters.
     * @param data the binary data
     * @return true if only US-ASCII data is found
     */
    public static boolean isUSASCII(byte[] data) {
        for (int i = 0, c = data.length; i < c; i++) {
            if ((data[i] & 0xFF) >= 128) {
                return false;
            }
        }
        return true;
    }
}
