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

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.SummaryInformation;

/**
 * This is a dictionary which maps property ID values to property
 * ID strings.
 *
 * The methods {@link #getSummaryInformationProperties} and {@link
 * #getDocumentSummaryInformationProperties} return singleton {@link
 * PropertyIDMap}s. An application that wants to extend these maps
 * should treat them as unmodifiable, copy them and modify the
 * copies.
 *
 * Trying to modify the map directly will cause exceptions
 * {@link UnsupportedOperationException} to be thrown.
 */
public class PropertyIDMap implements Map<Long,String> {

    /*
     * The following definitions are for property IDs in the first
     * (and only) section of the Summary Information property set.
     */

    /** ID of the property that denotes the document's title */
    public static final int PID_TITLE = 2;

    /** ID of the property that denotes the document's subject */
    public static final int PID_SUBJECT = 3;

    /** ID of the property that denotes the document's author */
    public static final int PID_AUTHOR = 4;

    /** ID of the property that denotes the document's keywords */
    public static final int PID_KEYWORDS = 5;

    /** ID of the property that denotes the document's comments */
    public static final int PID_COMMENTS = 6;

    /** ID of the property that denotes the document's template */
    public static final int PID_TEMPLATE = 7;

    /** ID of the property that denotes the document's last author */
    public static final int PID_LASTAUTHOR = 8;

    /** ID of the property that denotes the document's revision number */
    public static final int PID_REVNUMBER = 9;

    /** ID of the property that denotes the document's edit time */
    public static final int PID_EDITTIME = 10;

    /** ID of the property that denotes the date and time the document was
     * last printed */
    public static final int PID_LASTPRINTED = 11;

    /** ID of the property that denotes the date and time the document was
     * created. */
    public static final int PID_CREATE_DTM = 12;

    /** ID of the property that denotes the date and time the document was
     * saved */
    public static final int PID_LASTSAVE_DTM = 13;

    /** ID of the property that denotes the number of pages in the
     * document */
    public static final int PID_PAGECOUNT = 14;

    /** ID of the property that denotes the number of words in the
     * document */
    public static final int PID_WORDCOUNT = 15;

    /** ID of the property that denotes the number of characters in the
     * document */
    public static final int PID_CHARCOUNT = 16;

    /** ID of the property that denotes the document's thumbnail */
    public static final int PID_THUMBNAIL = 17;

    /** ID of the property that denotes the application that created the
     * document */
    public static final int PID_APPNAME = 18;

    /** ID of the property that denotes whether read/write access to the
     * document is allowed or whether is should be opened as read-only. It can
     * have the following values:
     *
     * <table summary="">
     *  <tbody>
     *   <tr>
     *    <th>Value</th>
     *    <th>Description</th>
     *   </tr>
     *   <tr>
     *    <th>0</th>
     *    <th>No restriction</th>
     *   </tr>
     *   <tr>
     *    <th>2</th>
     *    <th>Read-only recommended</th>
     *   </tr>
     *   <tr>
     *    <th>4</th>
     *    <th>Read-only enforced</th>
     *   </tr>
     *  </tbody>
     * </table>
     */
    public static final int PID_SECURITY = 19;



    /*
     * The following definitions are for property IDs in the first
     * section of the Document Summary Information property set.
     */

    /**
     * The entry is a dictionary.
     */
    public static final int PID_DICTIONARY = 0;

    /**
     * The entry denotes a code page.
     */
    public static final int PID_CODEPAGE = 1;

    /**
     * The entry is a string denoting the category the file belongs
     * to, e.g. review, memo, etc. This is useful to find documents of
     * same type.
     */
    public static final int PID_CATEGORY = 2;

    /**
     * Target format for power point presentation, e.g. 35mm,
     * printer, video etc.
     */
    public static final int PID_PRESFORMAT = 3;

    /**
     * Number of bytes.
     */
    public static final int PID_BYTECOUNT = 4;

    /**
     * Number of lines.
     */
    public static final int PID_LINECOUNT = 5;

    /**
     * Number of paragraphs.
     */
    public static final int PID_PARCOUNT = 6;

    /**
     * Number of slides in a power point presentation.
     */
    public static final int PID_SLIDECOUNT = 7;

    /**
     * Number of slides with notes.
     */
    public static final int PID_NOTECOUNT = 8;

    /**
     * Number of hidden slides.
     */
    public static final int PID_HIDDENCOUNT = 9;

    /**
     * Number of multimedia clips, e.g. sound or video.
     */
    public static final int PID_MMCLIPCOUNT = 10;

    /**
     * This entry is set to -1 when scaling of the thumbnail is
     * desired. Otherwise the thumbnail should be cropped.
     */
    public static final int PID_SCALE = 11;

    /**
     * This entry denotes an internally used property. It is a
     * vector of variants consisting of pairs of a string (VT_LPSTR)
     * and a number (VT_I4). The string is a heading name, and the
     * number tells how many document parts are under that
     * heading.
     */
    public static final int PID_HEADINGPAIR = 12;

    /**
     * This entry contains the names of document parts (word: names
     * of the documents in the master document, excel: sheet names,
     * power point: slide titles, binder: document names).
     */
    public static final int PID_DOCPARTS = 13;

    /**
     * This entry contains the name of the project manager.
     */
    public static final int PID_MANAGER = 14;

    /**
     * This entry contains the company name.
     */
    public static final int PID_COMPANY = 15;

    /**
     * If this entry is -1 the links are dirty and should be
     * re-evaluated.
     */
    public static final int PID_LINKSDIRTY = 0x10;
    
    /**
     * The entry specifies an estimate of the number of characters 
     *  in the document, including whitespace, as an integer
     */
    public static final int PID_CCHWITHSPACES = 0x11;
    
    // 0x12 Unused
    // 0x13 GKPIDDSI_SHAREDDOC - Must be False
    // 0x14 GKPIDDSI_LINKBASE - Must not be written
    // 0x15 GKPIDDSI_HLINKS - Must not be written

    /**
     * This entry contains a boolean which marks if the User Defined
     *  Property Set has been updated outside of the Application, if so the
     *  hyperlinks should be updated on document load.
     */
    public static final int PID_HYPERLINKSCHANGED = 0x16;
    
    /**
     * This entry contains 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.
     */
    public static final int PID_VERSION = 0x17;
    
    /**
     * This entry contains the VBA digital signature for the VBA project 
     *  embedded in the document.
     */
    public static final int PID_DIGSIG = 0x18;
    
    // 0x19 Unused
    
    /**
     * This entry contains a string of the content type of the file.
     */
    public static final int PID_CONTENTTYPE = 0x1A;
    
    /**
     * This entry contains a string of the document status.
     */
    public static final int PID_CONTENTSTATUS = 0x1B;
    
    /**
     * This entry contains a string of the document language, but
     *  normally should be empty.
     */
    public static final int PID_LANGUAGE = 0x1C;
    
    /**
     * This entry contains a string of the document version, but
     *  normally should be empty
     */
    public static final int PID_DOCVERSION = 0x1D;
    
    /**
     * The highest well-known property ID. Applications are free to use 
     *  higher values for custom purposes. (This value is based on Office 12,
     *  earlier versions of Office had lower values)
     */
    public static final int PID_MAX = 0x1F;

    /**
     * The Locale property, if present, MUST have the property identifier 0x80000000,
     * MUST NOT have a property name, and MUST have type VT_UI4 (0x0013).
     * If present, its value MUST be a valid language code identifier as specified in [MS-LCID].
     * Its value is selected in an implementation-specific manner.
     */
    public static final int PID_LOCALE = 0x80000000;


    /**
     * The Behavior property, if present, MUST have the property identifier 0x80000003,
     * MUST NOT have a property name, and MUST have type VT_UI4 (0x0013).
     * A version 0 property set, indicated by the value 0x0000 for the Version field of
     * the PropertySetStream packet, MUST NOT have a Behavior property.
     * If the Behavior property is present, it MUST have one of the following values.
     * 
     * <ul>
     * <li>0x00000000 = Property names are case-insensitive (default)
     * <li>0x00000001 = Property names are case-sensitive.
     * </ul>
     */
    public static final int PID_BEHAVIOUR = 0x80000003;
    
    /**
     * A property without a known name is described by this string.
     */
    public static final String UNDEFINED = "[undefined]";
    
    /**
     * Contains the summary information property ID values and
     * associated strings. See the overall HPSF documentation for
     * details!
     */
    private static PropertyIDMap summaryInformationProperties;
    private static final Object[][] summaryInformationIdValues = {
        { (long)PID_TITLE, "PID_TITLE" },
        { (long)PID_SUBJECT, "PID_SUBJECT" },
        { (long)PID_AUTHOR, "PID_AUTHOR" },
        { (long)PID_KEYWORDS, "PID_KEYWORDS" },
        { (long)PID_COMMENTS, "PID_COMMENTS" },
        { (long)PID_TEMPLATE, "PID_TEMPLATE" },
        { (long)PID_LASTAUTHOR, "PID_LASTAUTHOR" },
        { (long)PID_REVNUMBER, "PID_REVNUMBER" },
        { (long)PID_EDITTIME, "PID_EDITTIME" },
        { (long)PID_LASTPRINTED, "PID_LASTPRINTED" },
        { (long)PID_CREATE_DTM, "PID_CREATE_DTM" },
        { (long)PID_LASTSAVE_DTM, "PID_LASTSAVE_DTM" },
        { (long)PID_PAGECOUNT, "PID_PAGECOUNT" },
        { (long)PID_WORDCOUNT, "PID_WORDCOUNT" },
        { (long)PID_CHARCOUNT, "PID_CHARCOUNT" },
        { (long)PID_THUMBNAIL, "PID_THUMBNAIL" },
        { (long)PID_APPNAME, "PID_APPNAME" },
        { (long)PID_SECURITY, "PID_SECURITY" },
    };

    /**
     * Contains the summary information property ID values and
     * associated strings. See the overall HPSF documentation for
     * details!
     */
    private static PropertyIDMap documentSummaryInformationProperties;
    private static final Object[][] documentSummaryInformationIdValues = {
        { (long)PID_DICTIONARY, "PID_DICTIONARY" },
        { (long)PID_CODEPAGE, "PID_CODEPAGE" },
        { (long)PID_CATEGORY, "PID_CATEGORY" },
        { (long)PID_PRESFORMAT, "PID_PRESFORMAT" },
        { (long)PID_BYTECOUNT, "PID_BYTECOUNT" },
        { (long)PID_LINECOUNT, "PID_LINECOUNT" },
        { (long)PID_PARCOUNT, "PID_PARCOUNT" },
        { (long)PID_SLIDECOUNT, "PID_SLIDECOUNT" },
        { (long)PID_NOTECOUNT, "PID_NOTECOUNT" },
        { (long)PID_HIDDENCOUNT, "PID_HIDDENCOUNT" },
        { (long)PID_MMCLIPCOUNT, "PID_MMCLIPCOUNT" },
        { (long)PID_SCALE, "PID_SCALE" },
        { (long)PID_HEADINGPAIR, "PID_HEADINGPAIR" },
        { (long)PID_DOCPARTS, "PID_DOCPARTS" },
        { (long)PID_MANAGER, "PID_MANAGER" },
        { (long)PID_COMPANY, "PID_COMPANY" },
        { (long)PID_LINKSDIRTY, "PID_LINKSDIRTY" },
    };
    
    
    /**
     * Contains the fallback property ID values and associated strings.
     * This is only used for lookups and not for initializing a property set
     */
    private static PropertyIDMap fallbackProperties;
    private static final Object[][] fallbackIdValues = {
        { (long)PID_DICTIONARY, "PID_DICTIONARY" },
        { (long)PID_CODEPAGE, "PID_CODEPAGE" },
        { (long)PID_CATEGORY, "PID_CATEGORY" },
        { (long)PID_PRESFORMAT, "PID_PRESFORMAT" },
        { (long)PID_BYTECOUNT, "PID_BYTECOUNT" },
        { (long)PID_LINECOUNT, "PID_LINECOUNT" },
        { (long)PID_PARCOUNT, "PID_PARCOUNT" },
        { (long)PID_SLIDECOUNT, "PID_SLIDECOUNT" },
        { (long)PID_NOTECOUNT, "PID_NOTECOUNT" },
        { (long)PID_HIDDENCOUNT, "PID_HIDDENCOUNT" },
        { (long)PID_MMCLIPCOUNT, "PID_MMCLIPCOUNT" },
        { (long)PID_SCALE, "PID_SCALE" },
        { (long)PID_HEADINGPAIR, "PID_HEADINGPAIR" },
        { (long)PID_DOCPARTS, "PID_DOCPARTS" },
        { (long)PID_MANAGER, "PID_MANAGER" },
        { (long)PID_COMPANY, "PID_COMPANY" },
        { (long)PID_LINKSDIRTY, "PID_LINKSDIRTY" },
        { (long)PID_CCHWITHSPACES, "PID_CCHWITHSPACES" },
  // 0x12 Unused
  // 0x13 GKPIDDSI_SHAREDDOC - Must be False
  // 0x14 GKPIDDSI_LINKBASE - Must not be written
  // 0x15 GKPIDDSI_HLINKS - Must not be written
        { (long)PID_HYPERLINKSCHANGED, "PID_HYPERLINKSCHANGED" },
        { (long)PID_VERSION, "PID_VERSION" },
        { (long)PID_DIGSIG, "PID_DIGSIG" },
  // 0x19 Unused
        { (long)PID_CONTENTTYPE, "PID_CONTENTTYPE" },
        { (long)PID_CONTENTSTATUS, "PID_CONTENTSTATUS" },
        { (long)PID_LANGUAGE, "PID_LANGUAGE" },
        { (long)PID_DOCVERSION, "PID_DOCVERSION" },
        { (long)PID_MAX, "PID_MAX" },
        { (long)PID_LOCALE, "PID_LOCALE" },
        { (long)PID_BEHAVIOUR, "PID_BEHAVIOUR" },
    };

    private final Map<Long,String> idMap;
    

    /**
     * Creates a {@link PropertyIDMap} backed by another map.
     *
     * @param idValues an array of key/value pairs via nested Object[2] arrays
     */
    private PropertyIDMap(Object[][] idValues) {
        Map<Long,String> m = new HashMap<>(idValues.length);
        for (Object[] idValue : idValues) {
            m.put((Long)idValue[0], (String)idValue[1]);
        }
        idMap = Collections.unmodifiableMap(m);
    }

    /**
     * @return the Summary Information properties singleton
     */
    public static synchronized PropertyIDMap getSummaryInformationProperties() {
        if (summaryInformationProperties == null) {
            summaryInformationProperties = new PropertyIDMap(summaryInformationIdValues);
        }
        return summaryInformationProperties;
    }

    /**
     * @return The Document Summary Information properties singleton.
     */
    public static synchronized PropertyIDMap getDocumentSummaryInformationProperties() {
        if (documentSummaryInformationProperties == null) {
            documentSummaryInformationProperties = new PropertyIDMap(documentSummaryInformationIdValues);
        }
        return documentSummaryInformationProperties;
    }

    /**
     * Returns a property map, which is only used as a fallback, i.e. if available, the correct map
     * for {@link DocumentSummaryInformation} or {@link SummaryInformation} should be used.
     *
     * @return the resulting property map
     */
    public static synchronized PropertyIDMap getFallbackProperties() {
        if (fallbackProperties == null) {
            fallbackProperties = new PropertyIDMap(fallbackIdValues);
        }
        return fallbackProperties;
    }
    
    @Override
    public int size() {
        return idMap.size();
    }

    @Override
    public boolean isEmpty() {
        return idMap.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return idMap.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return idMap.containsValue(value);
    }

    @Override
    public String get(Object key) {
        return idMap.get(key);
    }

    @Override
    public String put(Long key, String value) {
        //noinspection ConstantConditions
        return idMap.put(key, value);
    }

    @Override
    public String remove(Object key) {
        //noinspection ConstantConditions
        return idMap.remove(key);
    }

    @Override
    public void putAll(Map<? extends Long, ? extends String> m) {
        idMap.putAll(m);
    }

    @Override
    public void clear() {
        idMap.clear();
    }

    @Override
    public Set<Long> keySet() {
        return idMap.keySet();
    }

    @Override
    public Collection<String> values() {
        return idMap.values();
    }

    @Override
    public Set<Entry<Long, String>> entrySet() {
        return idMap.entrySet();
    }

    /**
     * For the most basic testing.
     *
     * @param args The command-line arguments
     */
    public static void main(final String[] args) {
        PropertyIDMap s1 = getSummaryInformationProperties();
        PropertyIDMap s2 = getDocumentSummaryInformationProperties();
        System.out.println("s1: " + s1);
        System.out.println("s2: " + s2);
    }
}
