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

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

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLanguage;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPrDefault;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrDefault;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;

/**
 * Holds details of built-in, default and user styles, which
 * apply to tables / paragraphs / lists etc.
 * Text within one of those with custom stylings has the style
 * information stored in the {@link XWPFRun}
 */
public class XWPFStyles extends POIXMLDocumentPart {
    private CTStyles ctStyles;
    private List<XWPFStyle> listStyle = new ArrayList<XWPFStyle>();

    private XWPFLatentStyles latentStyles;
    private XWPFDefaultRunStyle defaultRunStyle;
    private XWPFDefaultParagraphStyle defaultParaStyle;

    /**
     * Construct XWPFStyles from a package part
     *
     * @param part the package part holding the data of the styles,
     * 
     * @since POI 3.14-Beta1
     */
    public XWPFStyles(PackagePart part) throws IOException, OpenXML4JException {
        super(part);
    }

    /**
     * @deprecated in POI 3.14, scheduled for removal in POI 3.16
     */
    @Deprecated
    public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException {
        this(part);
    }
    
    /**
     * Construct XWPFStyles from scratch for a new document.
     */
    public XWPFStyles() {
    }

    /**
     * Read document
     */
    @Override
    protected void onDocumentRead() throws IOException {
        StylesDocument stylesDoc;
        InputStream is = getPackagePart().getInputStream();
        try {
            stylesDoc = StylesDocument.Factory.parse(is, DEFAULT_XML_OPTIONS);
            setStyles(stylesDoc.getStyles());
            latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this);
        } catch (XmlException e) {
            throw new POIXMLException("Unable to read styles", e);
        } finally {
            is.close();
        }
    }

    @Override
    protected void commit() throws IOException {
        if (ctStyles == null) {
            throw new IllegalStateException("Unable to write out styles that were never read in!");
        }

        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));
        PackagePart part = getPackagePart();
        OutputStream out = part.getOutputStream();
        ctStyles.save(out, xmlOptions);
        out.close();
    }

    protected void ensureDocDefaults() {
        if (!ctStyles.isSetDocDefaults()) {
            ctStyles.addNewDocDefaults();
        }

        CTDocDefaults docDefaults = ctStyles.getDocDefaults();
        if (!docDefaults.isSetPPrDefault())
            docDefaults.addNewPPrDefault();
        if (!docDefaults.isSetRPrDefault())
            docDefaults.addNewRPrDefault();

        CTPPrDefault pprd = docDefaults.getPPrDefault();
        CTRPrDefault rprd = docDefaults.getRPrDefault();
        if (!pprd.isSetPPr()) pprd.addNewPPr();
        if (!rprd.isSetRPr()) rprd.addNewRPr();

        defaultRunStyle = new XWPFDefaultRunStyle(rprd.getRPr());
        defaultParaStyle = new XWPFDefaultParagraphStyle(pprd.getPPr());
    }

    /**
     * Sets the ctStyles
     *
     * @param styles
     */
    public void setStyles(CTStyles styles) {
        ctStyles = styles;

        // Build up all the style objects
        for (CTStyle style : ctStyles.getStyleArray()) {
            listStyle.add(new XWPFStyle(style, this));
        }
        if (ctStyles.isSetDocDefaults()) {
            CTDocDefaults docDefaults = ctStyles.getDocDefaults();
            if (docDefaults.isSetRPrDefault() && docDefaults.getRPrDefault().isSetRPr()) {
                defaultRunStyle = new XWPFDefaultRunStyle(
                        docDefaults.getRPrDefault().getRPr());
            }
            if (docDefaults.isSetPPrDefault() && docDefaults.getPPrDefault().isSetPPr()) {
                defaultParaStyle = new XWPFDefaultParagraphStyle(
                        docDefaults.getPPrDefault().getPPr());
            }
        }
    }

    /**
     * checks whether style with styleID exist
     *
     * @param styleID styleID of the Style in the style-Document
     * @return true if style exist, false if style not exist
     */
    public boolean styleExist(String styleID) {
        for (XWPFStyle style : listStyle) {
            if (style.getStyleId().equals(styleID))
                return true;
        }
        return false;
    }

    /**
     * add a style to the document
     *
     * @param style
     * @throws IOException
     */
    public void addStyle(XWPFStyle style) {
        listStyle.add(style);
        ctStyles.addNewStyle();
        int pos = ctStyles.sizeOfStyleArray() - 1;
        ctStyles.setStyleArray(pos, style.getCTStyle());
    }

    /**
     * Get style by a styleID
     *
     * @param styleID styleID of the searched style
     * @return style
     */
    public XWPFStyle getStyle(String styleID) {
        for (XWPFStyle style : listStyle) {
            if (style.getStyleId().equals(styleID))
                return style;
        }
        return null;
    }

    public int getNumberOfStyles() {
        return listStyle.size();
    }

    /**
     * get the styles which are related to the parameter style and their relatives
     * this method can be used to copy all styles from one document to another document
     *
     * @param style
     * @return a list of all styles which were used by this method
     */
    public List<XWPFStyle> getUsedStyleList(XWPFStyle style) {
        List<XWPFStyle> usedStyleList = new ArrayList<XWPFStyle>();
        usedStyleList.add(style);
        return getUsedStyleList(style, usedStyleList);
    }

    /**
     * get the styles which are related to parameter style
     *
     * @param style
     * @return all Styles of the parameterList
     */
    private List<XWPFStyle> getUsedStyleList(XWPFStyle style, List<XWPFStyle> usedStyleList) {
        String basisStyleID = style.getBasisStyleID();
        XWPFStyle basisStyle = getStyle(basisStyleID);
        if ((basisStyle != null) && (!usedStyleList.contains(basisStyle))) {
            usedStyleList.add(basisStyle);
            getUsedStyleList(basisStyle, usedStyleList);
        }
        String linkStyleID = style.getLinkStyleID();
        XWPFStyle linkStyle = getStyle(linkStyleID);
        if ((linkStyle != null) && (!usedStyleList.contains(linkStyle))) {
            usedStyleList.add(linkStyle);
            getUsedStyleList(linkStyle, usedStyleList);
        }

        String nextStyleID = style.getNextStyleID();
        XWPFStyle nextStyle = getStyle(nextStyleID);
        if ((nextStyle != null) && (!usedStyleList.contains(nextStyle))) {
            usedStyleList.add(linkStyle);
            getUsedStyleList(linkStyle, usedStyleList);
        }
        return usedStyleList;
    }

    protected CTLanguage getCTLanguage() {
        ensureDocDefaults();

        CTLanguage lang = null;
        if (defaultRunStyle.getRPr().isSetLang()) {
            lang = defaultRunStyle.getRPr().getLang();
        } else {
            lang = defaultRunStyle.getRPr().addNewLang();
        }

        return lang;
    }

    /**
     * Sets the default spelling language on ctStyles DocDefaults parameter
     *
     * @param strSpellingLanguage
     */
    public void setSpellingLanguage(String strSpellingLanguage) {
        CTLanguage lang = getCTLanguage();
        lang.setVal(strSpellingLanguage);
        lang.setBidi(strSpellingLanguage);
    }

    /**
     * Sets the default East Asia spelling language on ctStyles DocDefaults parameter
     *
     * @param strEastAsia
     */
    public void setEastAsia(String strEastAsia) {
        CTLanguage lang = getCTLanguage();
        lang.setEastAsia(strEastAsia);
    }

    /**
     * Sets the default font on ctStyles DocDefaults parameter
     * TODO Replace this with specific setters for each type, possibly
     * on XWPFDefaultRunStyle
     */
    public void setDefaultFonts(CTFonts fonts) {
        ensureDocDefaults();

        CTRPr runProps = defaultRunStyle.getRPr();
        runProps.setRFonts(fonts);
    }

    /**
     * get the style with the same name
     * if this style is not existing, return null
     */
    public XWPFStyle getStyleWithSameName(XWPFStyle style) {
        for (XWPFStyle ownStyle : listStyle) {
            if (ownStyle.hasSameName(style)) {
                return ownStyle;
            }
        }
        return null;
    }

    /**
     * Get the default style which applies text runs in the document
     */
    public XWPFDefaultRunStyle getDefaultRunStyle() {
        ensureDocDefaults();
        return defaultRunStyle;
    }

    /**
     * Get the default paragraph style which applies to the document
     */
    public XWPFDefaultParagraphStyle getDefaultParagraphStyle() {
        ensureDocDefaults();
        return defaultParaStyle;
    }

    /**
     * Get the definition of all the Latent Styles
     */
    public XWPFLatentStyles getLatentStyles() {
        return latentStyles;
    }
}
