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

import java.util.ArrayList;
import java.util.List;

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

/**
 * Plex of CPs stored in File (PLCF)
 * <p>
 * common data structure in a Word file. Contains an array of 4 byte ints in the
 * front that relate to an array of arbitrary data structures in the back.
 * <p>
 * See page 184 of official documentation for details
 */
public final class PlexOfCps {
    private int _iMac;
    private int _cbStruct;
    private List<GenericPropertyNode> _props;

    public PlexOfCps(int sizeOfStruct) {
        _props = new ArrayList<GenericPropertyNode>();
        _cbStruct = sizeOfStruct;
    }

    /**
     * Constructor
     *
     * @param cb       The size of PLCF in bytes
     * @param cbStruct The size of the data structure type stored in this PlexOfCps.
     */
    public PlexOfCps(byte[] buf, int start, int cb, int cbStruct) {
        // Figure out the number we hold
        _iMac = (cb - 4) / (4 + cbStruct);

        _cbStruct = cbStruct;
        _props = new ArrayList<GenericPropertyNode>(_iMac);

        for (int x = 0; x < _iMac; x++) {
            _props.add(getProperty(x, buf, start));
        }
    }

    @Internal
    void adjust(int startCp, int shift) {
        for (GenericPropertyNode node : _props) {
            if (node.getStart() > startCp) {
                if (node.getStart() + shift < startCp) {
                    node.setStart(startCp);
                } else {
                    node.setStart(node.getStart() + shift);
                }
            }
            if (node.getEnd() >= startCp) {
                if (node.getEnd() + shift < startCp) {
                    node.setEnd(startCp);
                } else {
                    node.setEnd(node.getEnd() + shift);
                }
            }
        }
    }

    public GenericPropertyNode getProperty(int index) {
        return _props.get(index);
    }

    public void addProperty(GenericPropertyNode node) {
        _props.add(node);
        _iMac++;
    }

    void remove(int index) {
        _props.remove(index);
        _iMac--;
    }

    public byte[] toByteArray() {
        int size = _props.size();
        int cpBufSize = ((size + 1) * LittleEndian.INT_SIZE);
        int structBufSize = +(_cbStruct * size);
        int bufSize = cpBufSize + structBufSize;

        byte[] buf = new byte[bufSize];

        int nodeEnd = 0;
        for (int x = 0; x < size; x++) {
            GenericPropertyNode node = _props.get(x);
            nodeEnd = node.getEnd();
            
            // put the starting offset of the property into the plcf.
            LittleEndian.putInt(buf, (LittleEndian.INT_SIZE * x), node.getStart());

            // put the struct into the plcf
            System.arraycopy(node.getBytes(), 0, buf, cpBufSize + (x * _cbStruct), _cbStruct);
        }
        // put the ending offset of the last property into the plcf.
        LittleEndian.putInt(buf, LittleEndian.INT_SIZE * size, nodeEnd);

        return buf;
    }

    private GenericPropertyNode getProperty(int index, byte[] buf, int offset) {
        int start = LittleEndian.getInt(buf, offset + getIntOffset(index));
        int end = LittleEndian.getInt(buf, offset + getIntOffset(index + 1));

        byte[] struct = new byte[_cbStruct];
        System.arraycopy(buf, offset + getStructOffset(index), struct, 0,
                _cbStruct);

        return new GenericPropertyNode(start, end, struct);
    }

    private int getIntOffset(int index) {
        return index * 4;
    }

    /**
     * returns the number of data structures in this PlexofCps.
     *
     * @return The number of data structures in this PlexofCps
     */
    public int length() {
        return _iMac;
    }

    /**
     * Returns the offset, in bytes, from the beginning if this PlexOfCps to the
     * data structure at index.
     *
     * @param index The index of the data structure.
     * @return The offset, in bytes, from the beginning if this PlexOfCps to the
     * data structure at index.
     */
    private int getStructOffset(int index) {
        return (4 * (_iMac + 1)) + (_cbStruct * index);
    }

    GenericPropertyNode[] toPropertiesArray() {
        if (_props == null || _props.isEmpty())
            return new GenericPropertyNode[0];

        return _props.toArray(new GenericPropertyNode[_props.size()]);
    }

    @Override
    public String toString() {
        return "PLCF (cbStruct: " + _cbStruct + "; iMac: " + _iMac + ")";
    }
}
