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

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherClientDataRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperty;
import org.apache.poi.ddf.EscherPropertyFactory;
import org.apache.poi.ddf.EscherPropertyTypes;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherRecordTypes;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hslf.model.MovieShape;
import org.apache.poi.hslf.record.ExObjRefAtom;
import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
import org.apache.poi.hslf.record.InteractiveInfo;
import org.apache.poi.hslf.record.InteractiveInfoAtom;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.ShapeType;

/**
 * Create a <code>Shape</code> object depending on its type
 */
public final class HSLFShapeFactory {
    // For logging
    private static final Logger LOG = LogManager.getLogger(HSLFShapeFactory.class);

    /**
     * Create a new shape from the data provided.
     */
    public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
        if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
            return createShapeGroup(spContainer, parent);
        }
        return createSimpleShape(spContainer, parent);
    }

    public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
        boolean isTable = false;
        EscherContainerRecord ecr = (EscherContainerRecord)spContainer.getChild(0);
        EscherRecord opt = HSLFShape.getEscherChild(ecr, EscherRecordTypes.USER_DEFINED);

        if (opt != null) {
            EscherPropertyFactory f = new EscherPropertyFactory();
            List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
            for (EscherProperty ep : props) {
                if (ep.getPropertyNumber() == EscherPropertyTypes.GROUPSHAPE__TABLEPROPERTIES.propNumber
                    && ep instanceof EscherSimpleProperty
                    && (((EscherSimpleProperty)ep).getPropertyValue() & 1) == 1) {
                    isTable = true;
                    break;
                }
            }
        }

        HSLFGroupShape group;
        if (isTable) {
            group = new HSLFTable(spContainer, parent);

        } else {
            group = new HSLFGroupShape(spContainer, parent);
        }

        return group;
     }

    public static HSLFShape createSimpleShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
        HSLFShape shape = null;
        EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);

        ShapeType type = ShapeType.forId(spRecord.getShapeType(), false);
        switch (type){
            case TEXT_BOX:
                shape = new HSLFTextBox(spContainer, parent);
                break;
            case HOST_CONTROL:
            case FRAME:
                shape = createFrame(spContainer, parent);
                break;
            case LINE:
                shape = new HSLFLine(spContainer, parent);
                break;
            case NOT_PRIMITIVE:
                shape = createNonPrimitive(spContainer, parent);
                break;
            default:
                if (parent instanceof HSLFTable) {
                    EscherTextboxRecord etr = spContainer.getChildById(EscherTextboxRecord.RECORD_ID);
                    if (etr == null) {
                        LOG.atWarn().log("invalid ppt - add EscherTextboxRecord to cell");
                        etr = new EscherTextboxRecord();
                        etr.setRecordId(EscherTextboxRecord.RECORD_ID);
                        etr.setOptions((short)15);
                        spContainer.addChildRecord(etr);
                    }
                    shape = new HSLFTableCell(spContainer, (HSLFTable)parent);
                } else {
                    shape = new HSLFAutoShape(spContainer, parent);
                }
                break;
        }
        return shape;
    }

    private static HSLFShape createFrame(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
        InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
        if(info != null && info.getInteractiveInfoAtom() != null){
            switch(info.getInteractiveInfoAtom().getAction()){
                case InteractiveInfoAtom.ACTION_OLE:
                    return new HSLFObjectShape(spContainer, parent);
                case InteractiveInfoAtom.ACTION_MEDIA:
                    return new MovieShape(spContainer, parent);
                default:
                    break;
            }
        }

        ExObjRefAtom oes = getClientDataRecord(spContainer, RecordTypes.ExObjRefAtom.typeID);
        return (oes != null)
            ? new HSLFObjectShape(spContainer, parent)
            : new HSLFPictureShape(spContainer, parent);
    }

    private static HSLFShape createNonPrimitive(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
        AbstractEscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
        EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherPropertyTypes.GEOMETRY__VERTICES);
        if(prop != null) {
            return new HSLFFreeformShape(spContainer, parent);
        }

        LOG.atInfo().log("Creating AutoShape for a NotPrimitive shape");
        return new HSLFAutoShape(spContainer, parent);
    }

    @SuppressWarnings("unchecked")
    protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
        HSLFEscherClientDataRecord cldata = spContainer.getChildById(EscherClientDataRecord.RECORD_ID);
        if (cldata != null) for (Record r : cldata.getHSLFChildRecords()) {
            if (r.getRecordType() == recordType) {
                return (T)r;
            }
        }
        return null;
    }

}
