# PDTargetDirectory.java

    /*
     * Copyright 2018 The Apache Software Foundation.
     *
     * Licensed 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.pdfbox.pdmodel.interactive.action;

    import org.apache.pdfbox.cos.COSBase;
    import org.apache.pdfbox.cos.COSDictionary;
    import org.apache.pdfbox.cos.COSName;
    import org.apache.pdfbox.cos.COSString;
    import org.apache.pdfbox.pdmodel.common.COSObjectable;
    import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination;

    /**
     * A target dictionary specifying path information to the target document. Each target dictionary
     * specifies one element in the full path to the target and may have nested target dictionaries
     * specifying additional elements.
     *
     * @author Tilman Hausherr
     */
    public class PDTargetDirectory implements COSObjectable
    {
        private final COSDictionary dict;

        /**
         * Default constructor, creates target directory.
         */
        public PDTargetDirectory()
        {
            dict = new COSDictionary();
        }

        /**
         * Create a target directory from an existing dictionary.
         *
         * @param dictionary The existing graphics state.
         */
        public PDTargetDirectory(COSDictionary dictionary)
        {
            dict = dictionary;
        }

        /**
         * This will get the underlying dictionary that this class acts on.
         *
         * @return The underlying dictionary for this class.
         */
        @Override
        public COSDictionary getCOSObject()
        {
            return dict;
        }

        /**
         * Get the relationship between the current document and the target (which may be an
         * intermediate target).
         *
         * @return the relationship as a name. Valid values are P (the target is the parent of the
         * current document) and C (the target is a child of the current document). Invalid values or
         * null are also returned.
         */
        public COSName getRelationship()
        {
            return dict.getCOSName(COSName.R);
        }

        /**
         * Set the relationship between the current document and the target (which may be an
         * intermediate target).
         *
         * @param relationship Valid values are P (the target is the parent of the current document) and
         * C (the target is a child of the current document).
         *
         * throws IllegalArgumentException if the parameter is not P or C.
         */
        public void setRelationship(COSName relationship)
        {
            if (!COSName.P.equals(relationship) && !COSName.C.equals(relationship))
            {
                throw new IllegalArgumentException("The only valid are P or C, not " + relationship.getName());
            }
            dict.setItem(COSName.R, relationship);
        }

        /**
         * Get the name of the file as found in the EmbeddedFiles name tree. This is only to be used if
         * the target is a child of the current document.
         *
         * @return a filename or null if there is none.
         */
        public String getFilename()
        {
            return dict.getString(COSName.N);
        }

        /**
         * Sets the name of the file as found in the EmbeddedFiles name tree. This is only to be used if
         * the target is a child of the current document.
         *
         * @param filename a filename or null if the entry is to be deleted.
         */
        public void setFilename(String filename)
        {
            dict.setString(COSName.N, filename);
        }

        /**
         * Get the target directory. If this entry is absent, the current document is the target file
         * containing the destination.
         *
         * @return the target directory or null if the current document is the target file containing
         * the destination.
         */
        public PDTargetDirectory getTargetDirectory()
        {
            COSDictionary targetDict = dict.getCOSDictionary(COSName.T);
            return targetDict != null ? new PDTargetDirectory(targetDict) : null;
        }

        /**
         * Sets the target directory.
         *
         * @param targetDirectory the target directory or null if the current document is the target
         * file containing the destination.
         */
        public void setTargetDirectory(PDTargetDirectory targetDirectory)
        {
            dict.setItem(COSName.T, targetDirectory);
        }

        /**
         * If the value in the /P entry is an integer, this will get the page number (zero-based) in the
         * current document containing the file attachment annotation.
         *
         * @return the zero based page number or -1 if the /P entry value is missing or not a number.
         */
        public int getPageNumber()
        {
            return dict.getInt(COSName.P, -1);
        }

        /**
         * Set the page number (zero-based) in the current document containing the file attachment
         * annotation.
         *
         * @param pageNumber the zero based page number. If this is &lt; 0 then the entry is removed.
         */
        public void setPageNumber(int pageNumber)
        {
            if (pageNumber < 0)
            {
                dict.removeItem(COSName.P);
            }
            else
            {
                dict.setInt(COSName.P, pageNumber);
            }
        }

        /**
         * If the value in the /P entry is a string, this will get a named destination in the current
         * document that provides the page number of the file attachment annotation.
         *
         * @return a named destination or null if the /P entry value is missing or not a string.
         */
        public PDNamedDestination getNamedDestination()
        {
            COSBase base = dict.getDictionaryObject(COSName.P);
            if (base instanceof COSString)
            {
                return new PDNamedDestination((COSString) base);
            }
            return null;
        }

        /**
         * This will set a named destination in the current document that provides the page number of
         * the file attachment annotation.
         *
         * @param dest a named destination or null if the entry is to be removed.
         */
        public void setNamedDestination(PDNamedDestination dest)
        {
            if (dest == null)
            {
                dict.removeItem(COSName.P);
            }
            else
            {
                dict.setItem(COSName.P, dest);
            }
        }

        /**
         * If the value in the /A entry is an integer, this will get the index (zero-based) of the
         * annotation in the /Annots array of the page specified by the /P entry.
         *
         * @return the zero based page number or -1 if the /P entry value is missing or not a number.
         */
        public int getAnnotationIndex()
        {
            return dict.getInt(COSName.A, -1);
        }

        /**
         * This will set the index (zero-based) of the annotation in the /Annots array of the page
         * specified by the /P entry.
         *
         * @param index the zero based index. If this is &lt; 0 then the entry is removed.
         */
        public void setAnnotationIndex(int index)
        {
            if (index < 0)
            {
                dict.removeItem(COSName.A);
            }
            else
            {
                dict.setInt(COSName.A, index);
            }
        }

        /**
         * If the value in the /A entry is a string, this will get the value of the /NM entry in the
         * annotation dictionary.
         *
         * @return the /NM value of an annotation dictionary or null if the /A entry value is missing or
         * not a string.
         */
        public String getAnnotationName()
        {
            return dict.getString(COSName.A);
        }

        /**
         * This will get the value of the /NM entry in the annotation dictionary.
         *
         * @param name the /NM value of an annotation dictionary or null if the entry is to be removed.
         */
        public void setAnnotationName(String name)
        {
            dict.setString(COSName.A, name);
        }
    }