/* ====================================================================
   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.hmef;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LZWDecompresser;
import org.apache.poi.util.LittleEndian;


/**
 * Within a {@link HMEFMessage}, the content is often
 *  stored in as RTF, but LZW compressed. This class
 *  handles decompressing it for you.
 */
public final class CompressedRTF extends LZWDecompresser {
   public static final byte[] COMPRESSED_SIGNATURE =
      new byte[] { (byte)'L', (byte)'Z', (byte)'F', (byte)'u' };
   public static final byte[] UNCOMPRESSED_SIGNATURE =
      new byte[] { (byte)'M', (byte)'E', (byte)'L', (byte)'A' };
   public static final int COMPRESSED_SIGNATURE_INT =
      LittleEndian.getInt(COMPRESSED_SIGNATURE);
   public static final int UNCOMPRESSED_SIGNATURE_INT =
      LittleEndian.getInt(UNCOMPRESSED_SIGNATURE);
   
   // The 4096 byte LZW dictionary is pre-loaded with some common
   //  RTF fragments. These come from RTFLIB32.LIB, which ships
   //  with older versions of Visual Studio or the EDK
   public static final String LZW_RTF_PRELOAD = 
      "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss " +
      "\\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier" +
      "{\\colortbl\\red0\\green0\\blue0\n\r\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx";

   private int compressedSize;
   private int decompressedSize;
   
   public CompressedRTF() {
      // Out flag has the normal meaning
      // Length wise, we're 2 longer than we say, so the max len is 18
      // Endian wise, we're big endian, so 0x1234 is pos 0x123
      super(true, 2, true);
   }

   /**
    * Decompresses the whole of the compressed RTF
    *  stream, outputting the resulting RTF bytes.
    * Note - will decompress any padding at the end of
    *  the input, if present, use {@link #getDeCompressedSize()}
    *  if you need to know how much of the result is
    *  real. (Padding may be up to 7 bytes).
    */
   public void decompress(InputStream src, OutputStream res) throws IOException {
      // Validate the header on the front of the RTF
      compressedSize = LittleEndian.readInt(src);
      decompressedSize = LittleEndian.readInt(src);
      int compressionType = LittleEndian.readInt(src);
      /* int dataCRC = */ LittleEndian.readInt(src);
      
      // TODO - Handle CRC checking on the output side
      
      // Do we need to do anything?
      if(compressionType == UNCOMPRESSED_SIGNATURE_INT) {
         // Nope, nothing fancy to do
         IOUtils.copy(src, res);
      } else if(compressionType == COMPRESSED_SIGNATURE_INT) {
         // We need to decompress it below
      } else {
         throw new IllegalArgumentException("Invalid compression signature " + compressionType);
      }

      // Have it processed
      super.decompress(src, res);
   }
   
   /**
    * Returns how big the compressed version was.
    */
   public int getCompressedSize() {
      // Return the size less the header
      return compressedSize - 12;
   }
   
   /**
    * Returns how big the decompressed version was.
    */
   public int getDeCompressedSize() {
      return decompressedSize;
   }

   /**
    * We use regular dictionary offsets, so no
    *  need to change anything
    */
   @Override
   protected int adjustDictionaryOffset(int offset) {
      return offset;
   }

   @Override
   protected int populateDictionary(byte[] dict) {
     // Copy in the RTF constants 
     byte[] preload = LZW_RTF_PRELOAD.getBytes(Charset.forName("US-ASCII"));
     System.arraycopy(preload, 0, dict, 0, preload.length);
     
     // Start adding new codes after the constants
     return preload.length;
   }
}
