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

import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
import org.openxmlformats.schemas.presentationml.x2006.main.CmLstDocument;
import org.openxmlformats.schemas.presentationml.x2006.main.NotesDocument;
import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument;
import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;

/**
 * Experimental class to do low level processing of pptx files.
 *
 * Most users should use the higher level {@link XMLSlideShow} instead.
 *
 * If you are using these low level classes, then you
 *  will almost certainly need to refer to the OOXML
 *  specifications from
 *  http://www.ecma-international.org/publications/standards/Ecma-376.htm
 *
 * WARNING - APIs expected to change rapidly
 */
public class XSLFSlideShow extends POIXMLDocument {

    private final PresentationDocument presentationDoc;
    /**
     * The embedded OLE2 files in the OPC package
     */
    private final List<PackagePart> embedds;

    public XSLFSlideShow(OPCPackage container) throws OpenXML4JException, IOException, XmlException {
        super(container);

        if(getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) {
            rebase(getPackage());
        }

        presentationDoc =
            PresentationDocument.Factory.parse(getCorePart().getInputStream(), DEFAULT_XML_OPTIONS);

        embedds = new LinkedList<>();
        for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdArray()) {
            PackagePart corePart = getCorePart();
            PackagePart slidePart = corePart.getRelatedPart(corePart.getRelationship(ctSlide.getId2()));

            for(PackageRelationship rel : slidePart.getRelationshipsByType(OLE_OBJECT_REL_TYPE)) {
                if (TargetMode.EXTERNAL == rel.getTargetMode()) {
                    continue;
                }
                // TODO: Add this reference to each slide as well
                embedds.add(slidePart.getRelatedPart(rel));
            }

            for (PackageRelationship rel : slidePart.getRelationshipsByType(PACK_OBJECT_REL_TYPE)) {
                embedds.add(slidePart.getRelatedPart(rel));
            }
        }
    }
    public XSLFSlideShow(String file) throws OpenXML4JException, IOException, XmlException {
        this(openPackage(file));
    }

    /**
     * Returns the low level presentation base object
     */
    @Internal
    public CTPresentation getPresentation() {
        return presentationDoc.getPresentation();
    }

    /**
     * Returns the references from the presentation to its
     *  slides.
     * You'll need these to figure out the slide ordering,
     *  and to get at the actual slides themselves
     */
    @Internal
    public CTSlideIdList getSlideReferences() {
        if(! getPresentation().isSetSldIdLst()) {
            getPresentation().setSldIdLst(CTSlideIdList.Factory.newInstance());
        }
        return getPresentation().getSldIdLst();
    }

    /**
     * Returns the references from the presentation to its
     *  slide masters.
     * You'll need these to get at the actual slide
     *  masters themselves
     */
    @Internal
    public CTSlideMasterIdList getSlideMasterReferences() {
        return getPresentation().getSldMasterIdLst();
    }

    public PackagePart getSlideMasterPart(CTSlideMasterIdListEntry master) throws IOException, XmlException {
        try {
           PackagePart corePart = getCorePart();
            return corePart.getRelatedPart(
                corePart.getRelationship(master.getId2())
            );
        } catch(InvalidFormatException e) {
            throw new XmlException(e);
        }
    }
    /**
     * Returns the low level slide master object from
     *  the supplied slide master reference
     */
    @Internal
    public CTSlideMaster getSlideMaster(CTSlideMasterIdListEntry master) throws IOException, XmlException {
        PackagePart masterPart = getSlideMasterPart(master);
        SldMasterDocument masterDoc =
            SldMasterDocument.Factory.parse(masterPart.getInputStream(), DEFAULT_XML_OPTIONS);
        return masterDoc.getSldMaster();
    }

    public PackagePart getSlidePart(CTSlideIdListEntry slide) throws IOException, XmlException {
        try {
            PackagePart corePart = getCorePart();
            return corePart.getRelatedPart(corePart.getRelationship(slide.getId2()));
        } catch(InvalidFormatException e) {
            throw new XmlException(e);
        }
    }
    /**
     * Returns the low level slide object from
     *  the supplied slide reference
     */
    @Internal
    public CTSlide getSlide(CTSlideIdListEntry slide) throws IOException, XmlException {
        PackagePart slidePart = getSlidePart(slide);
        SldDocument slideDoc =
            SldDocument.Factory.parse(slidePart.getInputStream(), DEFAULT_XML_OPTIONS);
        return slideDoc.getSld();
    }

    /**
     * Gets the PackagePart of the notes for the
     *  given slide, or null if there isn't one.
     */
    public PackagePart getNodesPart(CTSlideIdListEntry parentSlide) throws IOException, XmlException {
        PackageRelationshipCollection notes;
        PackagePart slidePart = getSlidePart(parentSlide);

        try {
            notes = slidePart.getRelationshipsByType(XSLFRelation.NOTES.getRelation());
        } catch(InvalidFormatException e) {
            throw new IllegalStateException(e);
        }

        if(notes.size() == 0) {
            // No notes for this slide
            return null;
        }
        if(notes.size() > 1) {
            throw new IllegalStateException("Expecting 0 or 1 notes for a slide, but found " + notes.size());
        }

        try {
            return slidePart.getRelatedPart(notes.getRelationship(0));
        } catch(InvalidFormatException e) {
            throw new IllegalStateException(e);
        }
    }
    /**
     * Returns the low level notes object for the given
     *  slide, as found from the supplied slide reference
     */
    @Internal
    public CTNotesSlide getNotes(CTSlideIdListEntry slide) throws IOException, XmlException {
        PackagePart notesPart = getNodesPart(slide);
        if(notesPart == null)
            return null;

        NotesDocument notesDoc =
            NotesDocument.Factory.parse(notesPart.getInputStream(), DEFAULT_XML_OPTIONS);

        return notesDoc.getNotes();
    }

    /**
     * Returns all the comments for the given slide
     */
    @Internal
    public CTCommentList getSlideComments(CTSlideIdListEntry slide) throws IOException, XmlException {
        PackageRelationshipCollection commentRels;
        PackagePart slidePart = getSlidePart(slide);

        try {
            commentRels = slidePart.getRelationshipsByType(XSLFRelation.COMMENTS.getRelation());
        } catch(InvalidFormatException e) {
            throw new IllegalStateException(e);
        }

        if(commentRels.size() == 0) {
            // No comments for this slide
            return null;
        }
        if(commentRels.size() > 1) {
            throw new IllegalStateException("Expecting 0 or 1 comments for a slide, but found " + commentRels.size());
        }

        try {
            PackagePart cPart = slidePart.getRelatedPart(
                    commentRels.getRelationship(0)
            );
            CmLstDocument commDoc =
                CmLstDocument.Factory.parse(cPart.getInputStream(), DEFAULT_XML_OPTIONS);
            return commDoc.getCmLst();
        } catch(InvalidFormatException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * Get the document's embedded files.
     */
    @Override
    public List<PackagePart> getAllEmbeddedParts() throws OpenXML4JException {
        return embedds;
    }

}
