/* ====================================================================
   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.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDgRecord;
import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.HeadersFooters;
import org.apache.poi.hslf.record.CString;
import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.record.HeadersFootersContainer;
import org.apache.poi.hslf.record.PPDrawing;
import org.apache.poi.hslf.record.RecordContainer;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.hslf.record.SheetContainer;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.Sheet;
import org.apache.poi.util.Internal;

/**
 * This class defines the common format of "Sheets" in a powerpoint
 * document. Such sheets could be Slides, Notes, Master etc
 */

public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,HSLFTextParagraph> {
    /**
     * The {@code SlideShow} we belong to
     */
    private HSLFSlideShow _slideShow;

    /**
     * Sheet background
     */
    private HSLFBackground _background;

    /**
     * Record container that holds sheet data.
     * For slides it is org.apache.poi.hslf.record.Slide,
     * for notes it is org.apache.poi.hslf.record.Notes,
     * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
     */
    private final SheetContainer _container;

    private final int _sheetNo;

    public HSLFSheet(SheetContainer container, int sheetNo) {
        _container = container;
        _sheetNo = sheetNo;
    }

    /**
     * Returns an array of all the TextRuns in the sheet.
     */
    public abstract List<List<HSLFTextParagraph>> getTextParagraphs();

    /**
     * Returns the (internal, RefID based) sheet number, as used
     * to in PersistPtr stuff.
     */
    public int _getSheetRefId() {
        return _container.getSheetId();
    }

    /**
     * Returns the (internal, SlideIdentifier based) sheet number, as used
     * to reference this sheet from other records.
     */
    public int _getSheetNumber() {
        return _sheetNo;
    }

    /**
     * Fetch the PPDrawing from the underlying record
     */
    public PPDrawing getPPDrawing() {
        return _container.getPPDrawing();
    }

    /**
     * Fetch the SlideShow we're attached to
     */
    @Override
    public HSLFSlideShow getSlideShow() {
        return _slideShow;
    }

    /**
     * Return record container for this sheet
     */
    public SheetContainer getSheetContainer() {
        return _container;
    }

    /**
     * Set the SlideShow we're attached to.
     * Also passes it on to our child text paragraphs
     */
    @Internal
    protected void setSlideShow(HSLFSlideShow ss) {
        if (_slideShow != null) {
            throw new HSLFException("Can't change existing slideshow reference");
        }

        _slideShow = ss;
        List<List<HSLFTextParagraph>> trs = getTextParagraphs();
        if (trs == null) {
            return;
        }
        for (List<HSLFTextParagraph> ltp : trs) {
            HSLFTextParagraph.supplySheet(ltp, this);
            HSLFTextParagraph.applyHyperlinks(ltp);
        }
    }


    /**
     * Returns all shapes contained in this Sheet
     *
     * @return all shapes contained in this Sheet (Slide or Notes)
     */
    @Override
    public List<HSLFShape> getShapes() {
        PPDrawing ppdrawing = getPPDrawing();

        EscherContainerRecord dg = ppdrawing.getDgContainer();
        EscherContainerRecord spgr = null;

        for (EscherRecord rec : dg) {
            if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
                spgr = (EscherContainerRecord) rec;
                break;
            }
        }
        if (spgr == null) {
            throw new IllegalStateException("spgr not found");
        }

        List<HSLFShape> shapeList = new ArrayList<>();
        boolean isFirst = true;
        for (EscherRecord r : spgr) {
            if (isFirst) {
                // skip first item
                isFirst = false;
                continue;
            }

            EscherContainerRecord sp = (EscherContainerRecord)r;
            HSLFShape sh = HSLFShapeFactory.createShape(sp, null);
            sh.setSheet(this);

            if (sh instanceof HSLFSimpleShape) {
                HSLFHyperlink link = HSLFHyperlink.find(sh);
                if (link != null) {
                    ((HSLFSimpleShape)sh).setHyperlink(link);
                }
            }

            shapeList.add(sh);
        }

        return shapeList;
    }

    /**
     * Add a new Shape to this Slide
     *
     * @param shape - the Shape to add
     */
    @Override
    public void addShape(HSLFShape shape) {
        PPDrawing ppdrawing = getPPDrawing();

        EscherContainerRecord dgContainer = ppdrawing.getDgContainer();
        EscherContainerRecord spgr = HSLFShape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
        spgr.addChildRecord(shape.getSpContainer());

        shape.setSheet(this);
        shape.setShapeId(allocateShapeId());
        shape.afterInsert(this);
    }

    /**
     * Allocates new shape id for the new drawing group id.
     *
     * @return a new shape id.
     */
    public int allocateShapeId() {
        EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
        EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord();
        return dgg.allocateShapeId(dg, false);
    }

    /**
     * Removes the specified shape from this sheet.
     *
     * @param shape shape to be removed from this sheet, if present.
     * @return {@code true} if the shape was deleted.
     */
    @Override
    public boolean removeShape(HSLFShape shape) {
        PPDrawing ppdrawing = getPPDrawing();

        EscherContainerRecord dg = ppdrawing.getDgContainer();
        EscherContainerRecord spgr = dg.getChildById(EscherContainerRecord.SPGR_CONTAINER);
        if(spgr == null) {
            return false;
        }

        return spgr.removeChildRecord(shape.getSpContainer());
    }

    /**
     * Called by SlideShow ater a new sheet is created
     */
    public void onCreate(){

    }

    /**
     * Return the master sheet .
     */
    @Override
    public abstract HSLFMasterSheet getMasterSheet();

    /**
     * Color scheme for this sheet.
     */
    public ColorSchemeAtom getColorScheme() {
        return _container.getColorScheme();
    }

    /**
     * Returns the background shape for this sheet.
     *
     * @return the background shape for this sheet.
     */
    @Override
    public HSLFBackground getBackground() {
        if (_background == null) {
            PPDrawing ppdrawing = getPPDrawing();

            EscherContainerRecord dg = ppdrawing.getDgContainer();
            EscherContainerRecord spContainer = dg.getChildById(EscherContainerRecord.SP_CONTAINER);
            _background = new HSLFBackground(spContainer, null);
            _background.setSheet(this);
        }
        return _background;
    }

    @Override
    public void draw(Graphics2D graphics) {
        DrawFactory drawFact = DrawFactory.getInstance(graphics);
        Drawable draw = drawFact.getDrawable(this);
        draw.draw(graphics);
    }

    /**
     * Subclasses should call this method and update the array of text runs
     * when a text shape is added
     */
    protected void onAddTextShape(HSLFTextShape shape) {
    }

    /**
     * Return placeholder by text type
     *
     * @param type  type of text, See {@link org.apache.poi.hslf.record.TextHeaderAtom}
     * @return  {@code TextShape} or {@code null}
     */
    public HSLFTextShape getPlaceholderByTextType(int type){
        for (HSLFShape shape : getShapes()) {
            if(shape instanceof HSLFTextShape){
                HSLFTextShape tx = (HSLFTextShape)shape;
                if (tx.getRunType() == type) {
                    return tx;
                }
            }
        }
        return null;
    }

    /**
     * Search placeholder by its type
     *
     * @param type  type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom}
     * @return  {@code SimpleShape} or {@code null}
     */
    public HSLFSimpleShape getPlaceholder(Placeholder type){
        for (HSLFShape shape : getShapes()) {
            if (shape instanceof HSLFSimpleShape) {
                HSLFSimpleShape ss = (HSLFSimpleShape)shape;
                if (type == ss.getPlaceholder()) {
                    return ss;
                }
            }
        }
        return null;
    }

    /**
     * Return programmable tag associated with this sheet, e.g. {@code ___PPT12}.
     *
     * @return programmable tag associated with this sheet.
     */
    public String getProgrammableTag(){
        String tag = null;
        RecordContainer progTags = (RecordContainer)
                getSheetContainer().findFirstOfType(
                            RecordTypes.ProgTags.typeID
        );
        if(progTags != null) {
            RecordContainer progBinaryTag = (RecordContainer)
                progTags.findFirstOfType(
                        RecordTypes.ProgBinaryTag.typeID
            );
            if(progBinaryTag != null) {
                CString binaryTag = (CString)
                    progBinaryTag.findFirstOfType(
                            RecordTypes.CString.typeID
                );
                if(binaryTag != null) {
                    tag = binaryTag.getText();
                }
            }
        }

        return tag;

    }

    @Override
    public Iterator<HSLFShape> iterator() {
        return getShapes().iterator();
    }


    /**
     * @return whether shapes on the master sheet should be shown. By default master graphics is turned off.
     * Sheets that support the notion of master (slide, slideLayout) should override it and
     * check this setting
     */
    @Override
    public boolean getFollowMasterGraphics() {
        return false;
    }


    @Override
    public HSLFTextBox createTextBox() {
        HSLFTextBox s = new HSLFTextBox();
        s.setHorizontalCentered(true);
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    @Override
    public HSLFAutoShape createAutoShape() {
        HSLFAutoShape s = new HSLFAutoShape(ShapeType.RECT);
        s.setHorizontalCentered(true);
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    @Override
    public HSLFFreeformShape createFreeform() {
        HSLFFreeformShape s = new HSLFFreeformShape();
        s.setHorizontalCentered(true);
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    @Override
    public HSLFConnectorShape createConnector() {
        HSLFConnectorShape s = new HSLFConnectorShape();
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    @Override
    public HSLFGroupShape createGroup() {
        HSLFGroupShape s = new HSLFGroupShape();
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    @Override
    public HSLFPictureShape createPicture(PictureData pictureData) {
        if (!(pictureData instanceof HSLFPictureData)) {
            throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData");
        }
        HSLFPictureShape s = new HSLFPictureShape((HSLFPictureData)pictureData);
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    @Override
    public HSLFTable createTable(int numRows, int numCols) {
        if (numRows < 1 || numCols < 1) {
            throw new IllegalArgumentException("numRows and numCols must be greater than 0");
        }
        HSLFTable s = new HSLFTable(numRows,numCols);
        // anchor is set in constructor based on numRows/numCols
        addShape(s);
        return s;
    }

    @Override
    public HSLFObjectShape createOleShape(PictureData pictureData) {
        if (!(pictureData instanceof HSLFPictureData)) {
            throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData");
        }
        HSLFObjectShape s = new HSLFObjectShape((HSLFPictureData)pictureData);
        s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
        addShape(s);
        return s;
    }

    /**
     * Header / Footer settings for this slide.
     *
     * @return Header / Footer settings for this slide
     */
    public HeadersFooters getHeadersFooters() {
        return new HeadersFooters(this, HeadersFootersContainer.SlideHeadersFootersContainer);
    }


    @Override
    public HSLFPlaceholderDetails getPlaceholderDetails(Placeholder placeholder) {
        final HSLFSimpleShape ph = getPlaceholder(placeholder);
        return (ph == null) ? null : new HSLFShapePlaceholderDetails(ph);
    }
}
