/* ====================================================================
   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.hwmf.record;

import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;

public class HwmfPalette {

    public static class PaletteEntry {
        private static final BitField PC_RESERVED   = BitFieldFactory.getInstance(0x01);
        private static final BitField PC_EXPLICIT   = BitFieldFactory.getInstance(0x02);
        private static final BitField PC_NOCOLLAPSE = BitFieldFactory.getInstance(0x04);

        private int values;
        private Color colorRef;

        private PaletteEntry() {
            this.values = PC_RESERVED.set(0);
            this.colorRef = Color.BLACK;
        }

        private PaletteEntry(PaletteEntry other) {
            this.values = other.values;
            this.colorRef = other.colorRef;
        }

        public int init(LittleEndianInputStream leis) throws IOException {
            // Values (1 byte):  An 8-bit unsigned integer that defines how the palette entry is to be used.
            // The Values field MUST be 0x00 or one of the values in the PaletteEntryFlag Enumeration table.
            values = leis.readUByte();
            // Blue (1 byte): An 8-bit unsigned integer that defines the blue intensity value for the palette entry.
            int blue = leis.readUByte();
            // Green (1 byte): An 8-bit unsigned integer that defines the green intensity value for the palette entry.
            int green = leis.readUByte();
            // Red (1 byte): An 8-bit unsigned integer that defines the red intensity value for the palette entry.
            int red = leis.readUByte();
            colorRef = new Color(red, green, blue);

            return 4*LittleEndianConsts.BYTE_SIZE;
        }

        /**
         * Specifies that the logical palette entry be used for palette animation. This value
         * prevents other windows from matching colors to the palette entry because the color frequently
         * changes. If an unused system-palette entry is available, the color is placed in that entry.
         * Otherwise, the color is not available for animation.
         */
        public boolean isReserved() {
            return PC_RESERVED.isSet(values);
        }

        /**
         * Specifies that the low-order word of the logical palette entry designates a hardware
         * palette index. This value allows the application to show the contents of the display device palette.
         */
        public boolean isExplicit() {
            return PC_EXPLICIT.isSet(values);
        }

        /**
         * Specifies that the color be placed in an unused entry in the system palette
         * instead of being matched to an existing color in the system palette. If there are no unused entries
         * in the system palette, the color is matched normally. Once this color is in the system palette,
         * colors in other logical palettes can be matched to this color.
         */
        public boolean isNoCollapse() {
            return PC_NOCOLLAPSE.isSet(values);
        }
    }

    public static abstract class WmfPaletteParent implements HwmfRecord, HwmfObjectTableEntry  {

        /**
         * Start (2 bytes):  A 16-bit unsigned integer that defines the offset into the Palette Object when
         * used with the META_SETPALENTRIES and META_ANIMATEPALETTE record types.
         * When used with META_CREATEPALETTE, it MUST be 0x0300
         */
        private int start;

        private List<PaletteEntry> palette = new ArrayList<PaletteEntry>();

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            start = leis.readUShort();
            /**
             * NumberOfEntries (2 bytes):  A 16-bit unsigned integer that defines the number of objects in
             * aPaletteEntries.
             */
            int numberOfEntries = leis.readUShort();
            int size = 2*LittleEndianConsts.SHORT_SIZE;
            for (int i=0; i<numberOfEntries; i++) {
                PaletteEntry pe = new PaletteEntry();
                size += pe.init(leis);
                palette.add(pe);
            }
            return size;
        }

        @Override
        public final void draw(HwmfGraphics ctx) {
            ctx.addObjectTableEntry(this);
        }
        
        protected List<PaletteEntry> getPaletteCopy() {
            List<PaletteEntry> newPalette = new ArrayList<PaletteEntry>();
            for (PaletteEntry et : palette) {
                newPalette.add(new PaletteEntry(et));
            }
            return newPalette;
        }

        protected int getPaletteStart() {
            return start;
        }
    }

    /**
     * The META_CREATEPALETTE record creates a Palette Object
     */
    public static class WmfCreatePalette extends WmfPaletteParent implements HwmfObjectTableEntry {
        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.createPalette;
        }

        @Override
        public void applyObject(HwmfGraphics ctx) {
            ctx.getProperties().setPalette(getPaletteCopy());
        }
    }

    /**
     * The META_SETPALENTRIES record defines RGB color values in a range of entries in the logical
     * palette that is defined in the playback device context.
     */
    public static class WmfSetPaletteEntries extends WmfPaletteParent {
        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.setPalEntries;
        }

        @Override
        public void applyObject(HwmfGraphics ctx) {
            HwmfDrawProperties props = ctx.getProperties();
            List<PaletteEntry> palette = props.getPalette();
            if (palette == null) {
                palette = new ArrayList<PaletteEntry>();
            }
            int start = getPaletteStart();
            for (int i=palette.size(); i<start; i++) {
                palette.add(new PaletteEntry());
            }
            int index = start;
            for (PaletteEntry palCopy : getPaletteCopy()) {
                if (palette.size() <= index) {
                    palette.add(palCopy);
                } else {
                    palette.set(index, palCopy);
                }
                index++;
            }
            props.setPalette(palette);
        }
    }

    /**
     * The META_RESIZEPALETTE record redefines the size of the logical palette that is defined in the
     * playback device context.
     */
    public static class WmfResizePalette implements HwmfRecord, HwmfObjectTableEntry {
        /**
         * A 16-bit unsigned integer that defines the number of entries in
         * the logical palette.
         */
        int numberOfEntries;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.resizePalette;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            numberOfEntries = leis.readUShort();
            return LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.addObjectTableEntry(this);
        }
        
        @Override
        public void applyObject(HwmfGraphics ctx) {
            HwmfDrawProperties props = ctx.getProperties();
            List<PaletteEntry> palette = props.getPalette();
            if (palette == null) {
                palette = new ArrayList<PaletteEntry>();
            }
            for (int i=palette.size(); i<numberOfEntries; i++) {
                palette.add(new PaletteEntry());
            }
            palette = palette.subList(0, numberOfEntries);
            props.setPalette(palette);
        }
    }

    /**
     * The META_SELECTPALETTE record defines the current logical palette with a specified Palette Object.
     */
    public static class WmfSelectPalette implements HwmfRecord {
        /**
         * A 16-bit unsigned integer used to index into the WMF Object Table to get
         * the Palette Object to be selected.
         */
        private int paletteIndex;

        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.selectPalette;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            paletteIndex = leis.readUShort();
            return LittleEndianConsts.SHORT_SIZE;
        }

        @Override
        public void draw(HwmfGraphics ctx) {
            ctx.applyObjectTableEntry(paletteIndex);
        }
    }

    /**
     * The META_REALIZEPALETTE record maps entries from the logical palette that
     * is defined in the playback device context to the system palette.
     */
    public static class WmfRealizePalette implements HwmfRecord {
        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.realizePalette;
        }

        @Override
        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
            return 0;
        }

        @Override
        public void draw(HwmfGraphics ctx) {

        }
    }

    /**
     * The META_ANIMATEPALETTE record redefines entries in the logical palette that
     * is defined in the playback device context with the specified Palette object
     *
     * The logical palette that is specified by the Palette object in this record is the
     * source of the palette changes, and the logical palette that is currently selected
     * into the playback device context is the destination. Entries in the destination
     * palette with the PC_RESERVED PaletteEntryFlag set SHOULD be modified by this record,
     * and entries with that flag clear SHOULD NOT be modified.
     * If none of the entries in the destination palette have the PC_RESERVED flag set, then
     * this record SHOULD have no effect.
     */
    public static class WmfAnimatePalette extends WmfPaletteParent {
        @Override
        public HwmfRecordType getRecordType() {
            return HwmfRecordType.animatePalette;
        }

        @Override
        public void applyObject(HwmfGraphics ctx) {
            HwmfDrawProperties props = ctx.getProperties();
            List<PaletteEntry> dest = props.getPalette();
            List<PaletteEntry> src = getPaletteCopy();
            int start = getPaletteStart();
            if (dest == null) {
                dest = new ArrayList<PaletteEntry>();
            }
            for (int i=dest.size(); i<start; i++) {
                dest.add(new PaletteEntry());
            }
            for (int i=0; i<src.size(); i++) {
                PaletteEntry pe = src.get(i);
                if (dest.size() <= start+i) {
                    dest.add(pe);
                } else {
                    PaletteEntry peDst = dest.get(start+i);
                    if (peDst.isReserved()) {
                        dest.set(start+i, pe);
                    }
                }
            }
            props.setPalette(dest);
        }
    }
}
