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

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.poi.hpsf.wellknown.PropertyIDMap;
import org.apache.poi.hpsf.wellknown.SectionIDMap;
import org.apache.poi.util.CodePageUtil;

/**
 * Convenience class representing a DocumentSummary Information stream in a
 * Microsoft Office document.
 *
 * @see SummaryInformation
 */
public class DocumentSummaryInformation extends SpecialPropertySet {
    /**
     * The document name a document summary information stream
     * usually has in a POIFS filesystem.
     */
    public static final String DEFAULT_STREAM_NAME =
        "\005DocumentSummaryInformation";

    @Override
    public PropertyIDMap getPropertySetIDMap() {
    	return PropertyIDMap.getDocumentSummaryInformationProperties();
    }


    /**
     * Creates an empty {@link DocumentSummaryInformation}.
     */
    public DocumentSummaryInformation() {
        getFirstSection().setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
    }

    
    /**
     * Creates a {@link DocumentSummaryInformation} from a given
     * {@link PropertySet}.
     *
     * @param ps A property set which should be created from a
     * document summary information stream.
     * @throws UnexpectedPropertySetTypeException if {@code ps}
     * does not contain a document summary information stream.
     */
    public DocumentSummaryInformation(final PropertySet ps)
    throws UnexpectedPropertySetTypeException {
        super(ps);
        if (!isDocumentSummaryInformation()) {
            throw new UnexpectedPropertySetTypeException("Not a " + getClass().getName());
        }
    }

    
    /**
     * Returns the category (or {@code null}).
     *
     * @return The category value
     */
    public String getCategory() {
        return getPropertyStringValue(PropertyIDMap.PID_CATEGORY);
    }

    /**
     * Sets the category.
     *
     * @param category The category to set.
     */
    public void setCategory(final String category) {
        getFirstSection().setProperty(PropertyIDMap.PID_CATEGORY, category);
    }

    /**
     * Removes the category.
     */
    public void removeCategory() {
        remove1stProperty(PropertyIDMap.PID_CATEGORY);
    }



    /**
     * Returns the presentation format (or
     * {@code null}).
     *
     * @return The presentation format value
     */
    public String getPresentationFormat() {
        return getPropertyStringValue(PropertyIDMap.PID_PRESFORMAT);
    }

    /**
     * Sets the presentation format.
     *
     * @param presentationFormat The presentation format to set.
     */
    public void setPresentationFormat(final String presentationFormat) {
        getFirstSection().setProperty(PropertyIDMap.PID_PRESFORMAT, presentationFormat);
    }

    /**
     * Removes the presentation format.
     */
    public void removePresentationFormat() {
        remove1stProperty(PropertyIDMap.PID_PRESFORMAT);
    }



    /**
     * Returns the byte count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a byte count.
     *
     * @return The byteCount value
     */
    public int getByteCount() {
        return getPropertyIntValue(PropertyIDMap.PID_BYTECOUNT);
    }

    /**
     * Sets the byte count.
     *
     * @param byteCount The byte count to set.
     */
    public void setByteCount(final int byteCount) {
        set1stProperty(PropertyIDMap.PID_BYTECOUNT, byteCount);
    }

    /**
     * Removes the byte count.
     */
    public void removeByteCount() {
        remove1stProperty(PropertyIDMap.PID_BYTECOUNT);
    }



    /**
     * Returns the line count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a line count.
     *
     * @return The line count value
     */
    public int getLineCount() {
        return getPropertyIntValue(PropertyIDMap.PID_LINECOUNT);
    }

    /**
     * Sets the line count.
     *
     * @param lineCount The line count to set.
     */
    public void setLineCount(final int lineCount) {
        set1stProperty(PropertyIDMap.PID_LINECOUNT, lineCount);
    }

    /**
     * Removes the line count.
     */
    public void removeLineCount() {
        remove1stProperty(PropertyIDMap.PID_LINECOUNT);
    }



    /**
     * Returns the par count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a par count.
     *
     * @return The par count value
     */
    public int getParCount() {
        return getPropertyIntValue(PropertyIDMap.PID_PARCOUNT);
    }

    /**
     * Sets the par count.
     *
     * @param parCount The par count to set.
     */
    public void setParCount(final int parCount) {
        set1stProperty(PropertyIDMap.PID_PARCOUNT, parCount);
    }

    /**
     * Removes the par count.
     */
    public void removeParCount() {
        remove1stProperty(PropertyIDMap.PID_PARCOUNT);
    }



    /**
     * Returns the slide count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a slide count.
     *
     * @return The slide count value
     */
    public int getSlideCount() {
        return getPropertyIntValue(PropertyIDMap.PID_SLIDECOUNT);
    }

    /**
     * Sets the slideCount.
     *
     * @param slideCount The slide count to set.
     */
    public void setSlideCount(final int slideCount) {
        set1stProperty(PropertyIDMap.PID_SLIDECOUNT, slideCount);
    }

    /**
     * Removes the slide count.
     */
    public void removeSlideCount() {
        remove1stProperty(PropertyIDMap.PID_SLIDECOUNT);
    }



    /**
     * Returns the note count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a note count.
     *
     * @return The note count value
     */
    public int getNoteCount() {
        return getPropertyIntValue(PropertyIDMap.PID_NOTECOUNT);
    }

    /**
     * Sets the note count.
     *
     * @param noteCount The note count to set.
     */
    public void setNoteCount(final int noteCount) {
        set1stProperty(PropertyIDMap.PID_NOTECOUNT, noteCount);
    }

    /**
     * Removes the noteCount.
     */
    public void removeNoteCount() {
        remove1stProperty(PropertyIDMap.PID_NOTECOUNT);
    }



    /**
     * Returns the hidden count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a hidden
     * count.
     *
     * @return The hidden count value
     */
    public int getHiddenCount() {
        return getPropertyIntValue(PropertyIDMap.PID_HIDDENCOUNT);
    }

    /**
     * Sets the hidden count.
     *
     * @param hiddenCount The hidden count to set.
     */
    public void setHiddenCount(final int hiddenCount) {
        set1stProperty(PropertyIDMap.PID_HIDDENCOUNT, hiddenCount);
    }

    /**
     * Removes the hidden count.
     */
    public void removeHiddenCount() {
        remove1stProperty(PropertyIDMap.PID_HIDDENCOUNT);
    }



    /**
     * Returns the mmclip count or 0 if the {@link
     * DocumentSummaryInformation} does not contain a mmclip
     * count.
     *
     * @return The mmclip count value
     */
    public int getMMClipCount() {
        return getPropertyIntValue(PropertyIDMap.PID_MMCLIPCOUNT);
    }

    /**
     * Sets the mmclip count.
     *
     * @param mmClipCount The mmclip count to set.
     */
    public void setMMClipCount(final int mmClipCount) {
        set1stProperty(PropertyIDMap.PID_MMCLIPCOUNT, mmClipCount);
    }

    /**
     * Removes the mmclip count.
     */
    public void removeMMClipCount() {
        remove1stProperty(PropertyIDMap.PID_MMCLIPCOUNT);
    }



    /**
     * Returns {@code true} when scaling of the thumbnail is
     * desired, {@code false} if cropping is desired.
     *
     * @return The scale value
     */
    public boolean getScale() {
        return getPropertyBooleanValue(PropertyIDMap.PID_SCALE);
    }

    /**
     * Sets the scale.
     *
     * @param scale The scale to set.
     */
    public void setScale(final boolean scale) {
        set1stProperty(PropertyIDMap.PID_SCALE, scale);
    }

    /**
     * Removes the scale.
     */
    public void removeScale() {
        remove1stProperty(PropertyIDMap.PID_SCALE);
    }



    /**
     * <p>Returns the heading pair (or {@code null})
     * <strong>when this method is implemented. Please note that the
     * return type is likely to change!</strong>
     *
     * @return The heading pair value
     */
    public byte[] getHeadingPair() {
        notYetImplemented("Reading byte arrays ");
        return (byte[]) getProperty(PropertyIDMap.PID_HEADINGPAIR);
    }

    /**
     * Sets the heading pair.
     *
     * @param headingPair The heading pair to set.
     */
    public void setHeadingPair(final byte[] headingPair) {
        notYetImplemented("Writing byte arrays ");
    }

    /**
     * Removes the heading pair.
     */
    public void removeHeadingPair() {
        remove1stProperty(PropertyIDMap.PID_HEADINGPAIR);
    }



    /**
     * <p>Returns the doc parts (or {@code null})
     * <strong>when this method is implemented. Please note that the
     * return type is likely to change!</strong>
     *
     * @return The doc parts value
     */
    public byte[] getDocparts() {
        notYetImplemented("Reading byte arrays");
        return (byte[]) getProperty(PropertyIDMap.PID_DOCPARTS);
    }



    /**
     * Sets the doc parts.
     *
     * @param docparts The doc parts to set.
     */
    public void setDocparts(final byte[] docparts) {
        notYetImplemented("Writing byte arrays");
    }

    /**
     * Removes the doc parts.
     */
    public void removeDocparts() {
        remove1stProperty(PropertyIDMap.PID_DOCPARTS);
    }



    /**
     * Returns the manager (or {@code null}).
     *
     * @return The manager value
     */
    public String getManager() {
        return getPropertyStringValue(PropertyIDMap.PID_MANAGER);
    }

    /**
     * Sets the manager.
     *
     * @param manager The manager to set.
     */
    public void setManager(final String manager) {
        set1stProperty(PropertyIDMap.PID_MANAGER, manager);
    }

    /**
     * Removes the manager.
     */
    public void removeManager() {
        remove1stProperty(PropertyIDMap.PID_MANAGER);
    }



    /**
     * Returns the company (or {@code null}).
     *
     * @return The company value
     */
    public String getCompany() {
        return getPropertyStringValue(PropertyIDMap.PID_COMPANY);
    }

    /**
     * Sets the company.
     *
     * @param company The company to set.
     */
    public void setCompany(final String company) {
        set1stProperty(PropertyIDMap.PID_COMPANY, company);
    }

    /**
     * Removes the company.
     */
    public void removeCompany() {
        remove1stProperty(PropertyIDMap.PID_COMPANY);
    }


    /**
     * Returns {@code true} if the custom links are dirty. <p>
     *
     * @return The links dirty value
     */
    public boolean getLinksDirty() {
        return getPropertyBooleanValue(PropertyIDMap.PID_LINKSDIRTY);
    }

    /**
     * Sets the linksDirty.
     *
     * @param linksDirty The links dirty value to set.
     */
    public void setLinksDirty(final boolean linksDirty) {
        set1stProperty(PropertyIDMap.PID_LINKSDIRTY, linksDirty);
    }

    /**
     * Removes the links dirty.
     */
    public void removeLinksDirty() {
        remove1stProperty(PropertyIDMap.PID_LINKSDIRTY);
    }
    
    
    /**
     * Returns the character count including whitespace, or 0 if the 
     *  {@link DocumentSummaryInformation} does not contain this char count.
     * <p>This is the whitespace-including version of {@link SummaryInformation#getCharCount()}
     *
     * @return The character count or {@code null}
     */
    public int getCharCountWithSpaces() {
        return getPropertyIntValue(PropertyIDMap.PID_CCHWITHSPACES);
    }

    /**
     * Sets the character count including whitespace
     * 
     * @param count The character count to set.
     */
    public void setCharCountWithSpaces(int count) {
        set1stProperty(PropertyIDMap.PID_CCHWITHSPACES, count);
    }
    
    /**
     * Removes the character count
     */
    public void removeCharCountWithSpaces() {
        remove1stProperty(PropertyIDMap.PID_CCHWITHSPACES);
    }
    
    
    /**
     * Get if the User Defined Property Set has been updated outside of the 
     * Application.<p>
     * If it has (true), the hyperlinks should be updated on document load.
     * 
     * @return true, if the hyperlinks should be updated on document load
     */
    public boolean getHyperlinksChanged() {
        return getPropertyBooleanValue(PropertyIDMap.PID_HYPERLINKSCHANGED);
    }
    
    /**
     * Set the flag for if the User Defined Property Set has been updated outside 
     *  of the Application.
     *  
     * @param changed true, if the User Defined Property Set has been updated
     */
    public void setHyperlinksChanged(boolean changed) {
        set1stProperty(PropertyIDMap.PID_HYPERLINKSCHANGED, changed);
    }
    
    /**
     * Removes the flag for if the User Defined Property Set has been updated
     *  outside of the Application.
     */
    public void removeHyperlinksChanged() {
        remove1stProperty(PropertyIDMap.PID_HYPERLINKSCHANGED);
    }

    
    /**
     * Gets the version of the Application which wrote the
     *  Property set, stored with the two high order bytes having the major
     *  version number, and the two low order bytes the minor version number.<p>
     * This will be 0 if no version is set.
     * 
     * @return the Application version
     */
    public int getApplicationVersion() {
        return getPropertyIntValue(PropertyIDMap.PID_VERSION);
    }
    
    /**
     * Sets the Application version, which must be a 4 byte int with
     *  the  two high order bytes having the major version number, and the 
     *  two low order bytes the minor version number.
     *  
     * @param version the Application version
     */
    public void setApplicationVersion(int version) {
        set1stProperty(PropertyIDMap.PID_VERSION, version);
    }
    
    /**
     * Removes the Application Version
     */
    public void removeApplicationVersion() {
        remove1stProperty(PropertyIDMap.PID_VERSION);
    }

    
    /**
     * Returns the VBA digital signature for the VBA project 
     * embedded in the document (or {@code null}).
     * 
     * @return the VBA digital signature
     */
    public byte[] getVBADigitalSignature() {
        Object value = getProperty(PropertyIDMap.PID_DIGSIG);
        if (value != null && value instanceof byte[]) {
            return (byte[])value;
        }
        return null;
    }
    
    /**
     * Sets the VBA digital signature for the VBA project 
     *  embedded in the document.
     *  
     * @param signature VBA Digital Signature for the project
     */
    public void setVBADigitalSignature(byte[] signature) {
        set1stProperty(PropertyIDMap.PID_DIGSIG, signature);
    }
    
    /**
     * Removes the VBA Digital Signature
     */
    public void removeVBADigitalSignature() {
        remove1stProperty(PropertyIDMap.PID_DIGSIG);
    }

    
    /**
     * Gets the content type of the file (or {@code null}).
     * 
     * @return the content type of the file
     */
    public String getContentType() {
        return getPropertyStringValue(PropertyIDMap.PID_CONTENTTYPE);
    }
    
    /**
     * Sets the content type of the file
     * 
     * @param type the content type of the file
     */
    public void setContentType(String type) {
        set1stProperty(PropertyIDMap.PID_CONTENTTYPE, type);
    }
    
    /**
     * Removes the content type of the file
     */
    public void removeContentType() {
        remove1stProperty(PropertyIDMap.PID_CONTENTTYPE);
    }

    
    /**
     * Gets the content status of the file (or {@code null}).
     * 
     * @return the content status of the file
     */
    public String getContentStatus() {
        return getPropertyStringValue(PropertyIDMap.PID_CONTENTSTATUS);
    }
    
    /**
     * Sets the content status of the file
     * 
     * @param status the content status of the file
     */
    public void setContentStatus(String status) {
        set1stProperty(PropertyIDMap.PID_CONTENTSTATUS, status);
    }
    
    /**
     * Removes the content status of the file
     */
    public void removeContentStatus() {
        remove1stProperty(PropertyIDMap.PID_CONTENTSTATUS);
    }

    
    /**
     * Gets the document language, which is normally unset and empty (or {@code null}).
     * 
     * @return the document language
     */
    public String getLanguage() {
        return getPropertyStringValue(PropertyIDMap.PID_LANGUAGE);
    }
    
    /**
     * Set the document language
     * 
     * @param language the document language
     */
    public void setLanguage(String language) {
        set1stProperty(PropertyIDMap.PID_LANGUAGE, language);
    }
    
    /**
     * Removes the document language
     */
    public void removeLanguage() {
        remove1stProperty(PropertyIDMap.PID_LANGUAGE);
    }

    
    /**
     * Gets the document version as a string, which is normally unset and empty
     *  (or {@code null}).
     *  
     *  @return the document verion
     */
    public String getDocumentVersion() {
        return getPropertyStringValue(PropertyIDMap.PID_DOCVERSION);
    }
    
    /**
     * Sets the document version string
     * 
     * @param version the document version string
     */
    public void setDocumentVersion(String version) {
        set1stProperty(PropertyIDMap.PID_DOCVERSION, version);
    }
    
    /**
     * Removes the document version string
     */
    public void removeDocumentVersion() {
        remove1stProperty(PropertyIDMap.PID_DOCVERSION);
    }

    
    /**
     * Gets the custom properties.
     *
     * @return The custom properties.
     */
    public CustomProperties getCustomProperties() {
        CustomProperties cps = null;
        if (getSectionCount() >= 2) {
            cps = new CustomProperties();
            final Section section = getSections().get(1);
            final Map<Long,String> dictionary = section.getDictionary();
            final Property[] properties = section.getProperties();
            int propertyCount = 0;
            for (int i = 0; i < properties.length; i++) {
                final Property p = properties[i];
                final long id = p.getID();
                if (id != 0 && id != 1) {
                    propertyCount++;
                    final CustomProperty cp = new CustomProperty(p,
                            dictionary.get(Long.valueOf(id)));
                    cps.put(cp.getName(), cp);
                }
            }
            if (cps.size() != propertyCount) {
                cps.setPure(false);
            }
        }
        return cps;
    }

    /**
     * Sets the custom properties.
     *
     * @param customProperties The custom properties
     */
    public void setCustomProperties(final CustomProperties customProperties) {
        ensureSection2();
        final Section section = getSections().get(1);
        final Map<Long,String> dictionary = customProperties.getDictionary();
        section.clear();

        /* Set the codepage. If both custom properties and section have a
         * codepage, the codepage from the custom properties wins, else take the
         * one that is defined. If none is defined, take Unicode. */
        int cpCodepage = customProperties.getCodepage();
        if (cpCodepage < 0) {
            cpCodepage = section.getCodepage();
        }
        if (cpCodepage < 0) {
            cpCodepage = CodePageUtil.CP_UNICODE;
        }
        customProperties.setCodepage(cpCodepage);
        section.setCodepage(cpCodepage);
        section.setDictionary(dictionary);
        for (CustomProperty p : customProperties.values()) {
            section.setProperty(p);
        }
    }

    /**
     * Creates section 2 if it is not already present.
     */
    private void ensureSection2() {
        if (getSectionCount() < 2) {
            Section s2 = new MutableSection();
            s2.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[1]);
            addSection(s2);
        }
    }

    /**
     * Removes the custom properties.
     */
    public void removeCustomProperties() {
        if (getSectionCount() < 2) {
            throw new HPSFRuntimeException("Illegal internal format of Document SummaryInformation stream: second section is missing.");
        }

        List<Section> l = new LinkedList<Section>(getSections());
        clearSections();
        int idx = 0;
        for (Section s : l) {
            if (idx++ != 1) {
                addSection(s);
            }
        }
    }
    
    /**
     * Throws an {@link UnsupportedOperationException} with a message text
     * telling which functionality is not yet implemented.
     *
     * @param msg text telling was leaves to be implemented, e.g.
     * "Reading byte arrays".
     */
    private void notYetImplemented(final String msg) {
        throw new UnsupportedOperationException(msg + " is not yet implemented.");
    }
}
