/*
 * 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.
 */

/* $Id$ */
package org.apache.fop.render.pdf.pdfbox;

import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;

import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFDictionary;

public final class PDFBoxAdapterUtil {
    private PDFBoxAdapterUtil() {
    }

    private static Integer getStreamHash(COSStream o) throws IOException {
        for (COSBase x : o.getValues()) {
            if (x instanceof COSObject || x instanceof COSDictionary) {
                return null;
            }
        }
        InputStream stream = o.getFilteredStream();
        byte[] b = IOUtils.toByteArray(stream);
        return Arrays.deepHashCode(new Object[]{b, o.toString()});
    }

    private static String getDictionaryHash(COSBase base) throws IOException {
        return getDictionaryHash(base, new ArrayList<COSBase>());
    }

    private static String getDictionaryHash(COSBase base, List<COSBase> objs) throws IOException {
        if (base == null) {
            return "null";
        }
        if (objs.contains(base)) {
            return String.valueOf(base.hashCode());
        }
        objs.add(base);
        if (base instanceof COSDictionary) {
            StringBuilder sb = new StringBuilder();
            sb.append("COSDictionary{");
            for (Map.Entry<COSName, COSBase> x : ((COSDictionary) base).entrySet()) {
                sb.append(x.getKey());
                sb.append(":");
                sb.append(getDictionaryHash(x.getValue(), objs));
                sb.append(";");
            }
            sb.append("}");
            if (base instanceof COSStream) {
                InputStream stream = ((COSStream)base).getFilteredStream();
                byte[] b = IOUtils.toByteArray(stream);
                sb.append("COSStream{").append(Arrays.hashCode(b)).append("}");
            }
            return sb.toString();
        } else if (base instanceof COSObject) {
            COSObject obj = (COSObject) base;
            return "COSObject{" + getDictionaryHash(obj.getObject(), objs) + "}";
        } else {
            return base.toString();
        }
    }

    protected static Object getBaseKey(Object base) throws IOException {
        if (base instanceof COSObject) {
            COSObject obj = (COSObject)base;
            COSBase o = obj.getObject();
            if (o instanceof COSStream) {
                Integer hash = PDFBoxAdapterUtil.getStreamHash((COSStream) o);
                if (hash != null) {
                    return hash;
                }
            }
            return obj.getObjectNumber() + " " + obj.getGenerationNumber();
        }
        if (base instanceof COSDictionary) {
            String dict = PDFBoxAdapterUtil.getDictionaryHash((COSBase) base);
            return String.valueOf(dict.hashCode());
        }
        return null;
    }

    protected static void rotate(int rotation, PDRectangle viewBox, AffineTransform atdoc) {
        float x = viewBox.getWidth() + viewBox.getLowerLeftX();
        float y = viewBox.getHeight() + viewBox.getLowerLeftY();
        switch (rotation) {
            case 90:
                atdoc.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
                atdoc.translate(0, viewBox.getWidth());
                atdoc.rotate(-Math.PI / 2.0);
                atdoc.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
                break;
            case 180:
                atdoc.translate(x, y);
                atdoc.rotate(-Math.PI);
                atdoc.translate(-viewBox.getLowerLeftX(), -viewBox.getLowerLeftY());
                break;
            case 270:
                atdoc.translate(viewBox.getLowerLeftX(), y);
                atdoc.rotate(Math.toRadians(270 + 180));
                atdoc.translate(-x, -y);
                break;
            default:
                //no additional transformations necessary
                break;
        }
    }

    protected static void updateAnnotationLink(PDFDictionary clonedAnnot) {
        Object a = clonedAnnot.get("A");
        if (a instanceof PDFDictionary) {
            PDFDictionary annot = (PDFDictionary) a;
            Object oldarrayObj = annot.get("D");
            if (oldarrayObj instanceof PDFArray) {
                PDFArray oldarray = (PDFArray) oldarrayObj;
                Object newarrayObj = oldarray.get(0);
                if (newarrayObj instanceof PDFArray) {
                    PDFArray newarray = (PDFArray) newarrayObj;
                    for (int i = 1; i < oldarray.length(); i++) {
                        newarray.add(oldarray.get(i));
                    }
                    annot.put("D", oldarray.get(0));
                }
            }
        }
    }

    protected static void moveAnnotations(PDPage page, List pageAnnotations, AffineTransform at) {
        PDRectangle mediaBox = page.getMediaBox();
        PDRectangle cropBox = page.getCropBox();
        PDRectangle viewBox = cropBox != null ? cropBox : mediaBox;
        for (Object obj : pageAnnotations) {
            PDAnnotation annot = (PDAnnotation)obj;
            PDRectangle rect = annot.getRectangle();
            float translateX = (float) (at.getTranslateX() - viewBox.getLowerLeftX());
            float translateY = (float) (at.getTranslateY() - viewBox.getLowerLeftY());
            if (rect != null) {
                rect.setUpperRightX(rect.getUpperRightX() + translateX);
                rect.setLowerLeftX(rect.getLowerLeftX() + translateX);
                rect.setUpperRightY(rect.getUpperRightY() + translateY);
                rect.setLowerLeftY(rect.getLowerLeftY() + translateY);
                annot.setRectangle(rect);
            }
//            COSArray vertices = (COSArray) annot.getCOSObject().getDictionaryObject("Vertices");
//            if (vertices != null) {
//                Iterator iter = vertices.iterator();
//                while (iter.hasNext()) {
//                    COSFloat x = (COSFloat) iter.next();
//                    COSFloat y = (COSFloat) iter.next();
//                    x.setValue(x.floatValue() + translateX);
//                    y.setValue(y.floatValue() + translateY);
//                }
//            }
        }
    }
}
