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

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.util.LittleEndian;

/**
 * Generates escher records when provided the byte array containing those records.
 *
 * @author Glen Stampoultzis
 * @author Nick Burch   (nick at torchbox . com)
 *
 * @see EscherRecordFactory
 */
public class DefaultEscherRecordFactory implements EscherRecordFactory {
    private static Class<?>[] escherRecordClasses = { EscherBSERecord.class,
            EscherOptRecord.class, EscherTertiaryOptRecord.class,
            EscherClientAnchorRecord.class, EscherDgRecord.class,
            EscherSpgrRecord.class, EscherSpRecord.class,
            EscherClientDataRecord.class, EscherDggRecord.class,
            EscherSplitMenuColorsRecord.class, EscherChildAnchorRecord.class,
            EscherTextboxRecord.class };
    private static Map<Short, Constructor<? extends EscherRecord>> recordsMap = recordsToMap( escherRecordClasses );

    /**
     * Creates an instance of the escher record factory
     */
    public DefaultEscherRecordFactory() {
        // no instance initialisation
    }

    /**
     * Generates an escher record including the any children contained under that record.
     * An exception is thrown if the record could not be generated.
     *
     * @param data   The byte array containing the records
     * @param offset The starting offset into the byte array
     * @return The generated escher record
     */
    public EscherRecord createRecord(byte[] data, int offset) {
        short options = LittleEndian.getShort( data, offset );
        short recordId = LittleEndian.getShort( data, offset + 2 );
        // int remainingBytes = LittleEndian.getInt( data, offset + 4 );

        // Options of 0x000F means container record
        // However, EscherTextboxRecord are containers of records for the
        //  host application, not of other Escher records, so treat them
        //  differently
        if (isContainer(options, recordId)) {
            EscherContainerRecord r = new EscherContainerRecord();
            r.setRecordId( recordId );
            r.setOptions( options );
            return r;
        }

        if (recordId >= EscherBlipRecord.RECORD_ID_START
                && recordId <= EscherBlipRecord.RECORD_ID_END) {
            EscherBlipRecord r;
            if (recordId == EscherBitmapBlip.RECORD_ID_DIB ||
                    recordId == EscherBitmapBlip.RECORD_ID_JPEG ||
                    recordId == EscherBitmapBlip.RECORD_ID_PNG)
            {
                r = new EscherBitmapBlip();
            }
            else if (recordId == EscherMetafileBlip.RECORD_ID_EMF ||
                    recordId == EscherMetafileBlip.RECORD_ID_WMF ||
                    recordId == EscherMetafileBlip.RECORD_ID_PICT)
            {
                r = new EscherMetafileBlip();
            } else {
                r = new EscherBlipRecord();
            }
            r.setRecordId( recordId );
            r.setOptions( options );
            return r;
        }

        Constructor<? extends EscherRecord> recordConstructor = recordsMap.get(Short.valueOf(recordId));
        EscherRecord escherRecord = null;
        if (recordConstructor == null) {
            return new UnknownEscherRecord();
        }
        try {
            escherRecord = recordConstructor.newInstance(new Object[] {});
        } catch (Exception e) {
            return new UnknownEscherRecord();
        }
        escherRecord.setRecordId(recordId);
        escherRecord.setOptions(options);
        return escherRecord;
    }

    /**
     * Converts from a list of classes into a map that contains the record id as the key and
     * the Constructor in the value part of the map.  It does this by using reflection to look up
     * the RECORD_ID field then using reflection again to find a reference to the constructor.
     *
     * @param recClasses The records to convert
     * @return The map containing the id/constructor pairs.
     */
    private static Map<Short, Constructor<? extends EscherRecord>> recordsToMap(Class<?>[] recClasses) {
        Map<Short, Constructor<? extends EscherRecord>> result = new HashMap<Short, Constructor<? extends EscherRecord>>();
        final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];

        for (int i = 0; i < recClasses.length; i++) {
            @SuppressWarnings("unchecked")
            Class<? extends EscherRecord> recCls = (Class<? extends EscherRecord>) recClasses[i];
            short sid;
            try {
                sid = recCls.getField("RECORD_ID").getShort(null);
            } catch (IllegalArgumentException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
            Constructor<? extends EscherRecord> constructor;
            try {
                constructor = recCls.getConstructor( EMPTY_CLASS_ARRAY );
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
            result.put(Short.valueOf(sid), constructor);
        }
        return result;
    }

    public static boolean isContainer(short options, short recordId){
        if(recordId >= EscherContainerRecord.DGG_CONTAINER &&  recordId
                <= EscherContainerRecord.SOLVER_CONTAINER){
            return true;
        } else {
            if (recordId == EscherTextboxRecord.RECORD_ID) {
                return false;
            } else {
                return ( options & (short) 0x000F ) == (short) 0x000F;
            }
        }
    }
}
