package org.verapdf.model.impl.pb.cos;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSString;
import org.verapdf.model.baselayer.*;
import org.verapdf.model.baselayer.Object;
import org.verapdf.model.coslayer.CosIndirect;
import org.verapdf.model.coslayer.CosTrailer;

import java.util.ArrayList;
import java.util.List;

/**
 * Trailer of the document.
 *
 * @author Evgeniy Muravitskiy
 */
public class PBCosTrailer extends PBCosDict implements CosTrailer {

    private final String CATALOG = "Catalog";
    /** if document is linearized its must have dictionary of linearization
     */
    private COSDictionary linearizedDictionary = null;
    /** if document is linearized first trailer is differ from last
     */
    private CosTrailer firstTrailer = null;
    /** length of the document
     */
    private Long length = null;

    public PBCosTrailer(COSDictionary pdfBoxObject) {
        super(pdfBoxObject);
        setType("CosTrailer");
    }

    public PBCosTrailer(COSDictionary mainTrailer, COSDictionary firstTrailer, COSDictionary linearizedDictionary, Long length) {
        super(mainTrailer);
        this.firstTrailer = new PBCosTrailer(firstTrailer);
        this.linearizedDictionary = linearizedDictionary;
        this.length = length;
    }

    /**
     * @return first part of ID if its present
     */
    public String getid1() {
        return getPartOfID(0);
    }

    /**
     * @return second part of ID if its present
     */
    public String getid2() {
        return getPartOfID(1);
    }

    private String getPartOfID(int index) {
        COSArray ids = (COSArray) ((COSDictionary) baseObject).getItem("ID");

        if (ids != null && ids.size() > index) {
            if (ids.get(index) instanceof COSString) {
                return new String(((COSString) ids.get(index)).getBytes());
            } else {
                // TODO : discuss about this case
                throw new IllegalArgumentException("ID not conforming defined type for ID.");
            }
        } else {
            return null;
        }
    }

    /**
     * @return true if the current document is linearized
     */
    // TODO : need to support of this feature
    public Boolean getisLinearized() {
        return !(baseObject == firstTrailer || linearizedDictionary == null);
    }

    /**
     * @return true if the current document is encrypted
     */
    public Boolean getisEncrypted() {
        return ((COSDictionary) baseObject).getItem("Encrypt") != null;
    }

    /**
     * @return true if ID of first and last trailers are match
     */
    @Override
    public Boolean getdoFirstLastTrailerIDsMatch() {
        return getid1().equals(firstTrailer.getid1()) && getid2().equals(firstTrailer.getid2());
    }

    @Override
    public List<? extends Object> getLinkedObjects(String link) {
        List<? extends Object> list;
        switch (link) {
            case CATALOG:
                list = getCatalog();
                break;
            default:
                list = super.getLinkedObjects(link);
                break;
        }
        return list;
    }

    private List<CosIndirect> getCatalog() {
        List<CosIndirect> catalog = new ArrayList<>(1);
        catalog.add((CosIndirect) ((COSDictionary) baseObject).getItem(CATALOG));
        return catalog;
    }
}

@@ -72,16 +72,54 @@
 SArray;%0A
+import org.apache.pdfbox.cos.COSBase;%0A
 import o
@@ -834,25 +834,28 @@
 rivate C
-osTrailer
+OSDictionary
  firstTr
@@ -1251,25 +1251,8 @@
 r = 
-new PBCosTrailer(
 firs
@@ -1255,25 +1255,24 @@
 firstTrailer
-)
 ;%0A        th
@@ -1383,16 +1383,22 @@
 urn 
+ID of 
 first pa
 rt o
@@ -1393,39 +1393,26 @@
 first pa
-rt of ID if its present
+ge trailer
 %0A     */
@@ -1433,19 +1433,27 @@
 ring get
-id1
+firstPageID
 () %7B%0A   
@@ -1471,18 +1471,55 @@
  get
-PartOfID(0
+TrailerID((COSArray) firstTrailer.getItem(%22ID%22)
 );%0A 
@@ -1551,40 +1551,35 @@
 urn 
-second part of ID if its present
+ID of last document trailer
 %0A   
@@ -1601,22 +1601,22 @@
  String 
-getid2
+lastID
 () %7B%0A   
@@ -1634,95 +1634,18 @@
  get
-PartOfID(1);%0A    %7D%0A%0A    private String getPartOfID(int index) %7B%0A        COSArray ids = 
+TrailerID(
 (COS
@@ -1697,148 +1697,178 @@
 ID%22)
+)
 ;
-%0A
 %0A    
+%7D%0A%0A
     
-if (ids != null && ids.size() %3E index) %7B%0A            if (ids.get(index) instanceof COSString) %7B%0A                return new String
+private String getTrailerID(COSArray ids) %7B%0A        StringBuilder builder = new StringBuilder();%0A        for (COSBase id : ids) %7B%0A            builder.append
 (((C
@@ -1883,104 +1883,86 @@
 ) id
-s
+)
 .get
-(index)).getBytes());%0A            %7D else %7B%0A                // TODO : discuss about this cas
+ASCII()).append(' ');%0A        %7D%0A        // need to discard last whitespac
 e%0A  
@@ -1971,159 +1971,69 @@
     
-        throw new IllegalArgumentException(%22ID not conforming defined type for ID.%22);%0A            %7D%0A        %7D else %7B%0A            return null;%0A        %7D
+return builder.toString().substring(0, builder.length() - 2);
 %0A   
@@ -2474,258 +2474,8 @@
  %7D%0A%0A
-    /**%0A     * @return true if ID of first and last trailers are match%0A     */%0A    @Override%0A    public Boolean getdoFirstLastTrailerIDsMatch() %7B%0A        return getid1().equals(firstTrailer.getid1()) && getid2().equals(firstTrailer.getid2());%0A    %7D%0A%0A
     

Add support of new properties for CosTrailer