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


import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.RecordFormatException;

/**
 * Container class for four subtypes of HemfCommentPublic: BeginGroup, EndGroup, MultiFormats
 * and Windows Metafile.
 */
@Internal
public class HemfCommentPublic  {

    /**
     * Stub, to be implemented
     */
    public static class BeginGroup extends AbstractHemfComment {

        public BeginGroup(byte[] rawBytes) {
            super(rawBytes);
        }

    }

    /**
     * Stub, to be implemented
     */
    public static class EndGroup extends AbstractHemfComment {

        public EndGroup(byte[] rawBytes) {
            super(rawBytes);
        }
    }

    public static class MultiFormats extends AbstractHemfComment {

        public MultiFormats(byte[] rawBytes) {
            super(rawBytes);
        }

        /**
         *
         * @return a list of HemfMultFormatsData
         */
        public List<HemfMultiFormatsData> getData() {

            byte[] rawBytes = getRawBytes();
            //note that raw bytes includes the public comment identifier
            int currentOffset = 4 + 16;//4 public comment identifier, 16 for outputrect
            long countFormats = LittleEndian.getUInt(rawBytes, currentOffset);
            currentOffset += LittleEndian.INT_SIZE;
            List<EmrFormat> emrFormatList = new ArrayList<EmrFormat>();
            for (long i = 0; i < countFormats; i++) {
                emrFormatList.add(new EmrFormat(rawBytes, currentOffset));
                currentOffset += 4 * LittleEndian.INT_SIZE;
            }
            List<HemfMultiFormatsData> list = new ArrayList<HemfMultiFormatsData>();
            for (EmrFormat emrFormat : emrFormatList) {
                byte[] data = new byte[emrFormat.size];
                System.arraycopy(rawBytes, emrFormat.offset-4, data, 0, emrFormat.size);
                list.add(new HemfMultiFormatsData(emrFormat.signature, emrFormat.version, data));
            }
            return list;
        }

        private class EmrFormat {
            long signature;
            long version;
            int size;
            int offset;

            public EmrFormat(byte[] rawBytes, int currentOffset) {
                signature = LittleEndian.getUInt(rawBytes, currentOffset); currentOffset += LittleEndian.INT_SIZE;
                version = LittleEndian.getUInt(rawBytes, currentOffset); currentOffset += LittleEndian.INT_SIZE;
                //spec says this must be a 32bit "aligned" typo for "signed"?
                //realistically, this has to be an int...
                size = LittleEndian.getInt(rawBytes, currentOffset); currentOffset += LittleEndian.INT_SIZE;
                //y, can be long, but realistically?
                offset = LittleEndian.getInt(rawBytes, currentOffset); currentOffset += LittleEndian.INT_SIZE;
                if (size < 0) {
                    throw new RecordFormatException("size for emrformat must be > 0");
                }
                if (offset < 0) {
                    throw new RecordFormatException("offset for emrformat must be > 0");
                }
            }
        }
    }

    /**
     * Stub, to be implemented
     */
    public static class WindowsMetafile extends AbstractHemfComment {

        private final byte[] wmfBytes;
        public WindowsMetafile(byte[] rawBytes) {
            super(rawBytes);
            int offset = LittleEndian.INT_SIZE;//public comment identifier
            int version = LittleEndian.getUShort(rawBytes, offset); offset += LittleEndian.SHORT_SIZE;
            int reserved = LittleEndian.getUShort(rawBytes, offset); offset += LittleEndian.SHORT_SIZE;
            offset += LittleEndian.INT_SIZE; //checksum
            offset += LittleEndian.INT_SIZE; //flags
            long winMetafileSizeLong = LittleEndian.getUInt(rawBytes, offset); offset += LittleEndian.INT_SIZE;
            if (winMetafileSizeLong == 0L) {
                wmfBytes = new byte[0];
                return;
            }
            if (winMetafileSizeLong > Integer.MAX_VALUE) {
                throw new RecordFormatException("Metafile record length can't be > Integer.MAX_VALUE");
            }
            int winMetafileSize = (int)winMetafileSizeLong;
            wmfBytes = new byte[winMetafileSize];
            System.arraycopy(rawBytes, offset, wmfBytes, 0, winMetafileSize);
        }

        /**
         *
         * @return an InputStream for the embedded WMF file
         */
        public InputStream getWmfInputStream() {
            return new ByteArrayInputStream(wmfBytes);
        }
    }

    /**
     * This encapulates a single record stored within
     * a HemfCommentPublic.MultiFormats record.
     */
    public static class HemfMultiFormatsData {

        long signature;
        long version;
        byte[] data;

        public HemfMultiFormatsData(long signature, long version, byte[] data) {
            this.signature = signature;
            this.version = version;
            this.data = data;
        }

        public long getSignature() {
            return signature;
        }

        public long getVersion() {
            return version;
        }

        public byte[] getData() {
            return data;
        }
    }
}
