/*
 * 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.fop.render.pdf.pdfbox;

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.pdfbox.contentstream.operator.Operator;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSBoolean;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.pdfparser.PDFStreamParser;
import org.apache.pdfbox.pdmodel.common.PDStream;


public class PDFWriter {
    protected StringBuilder s = new StringBuilder();
    protected UniqueName key;
    private int currentMCID;

    public PDFWriter(UniqueName key, int currentMCID) {
        this.key = key;
        this.currentMCID = currentMCID;
    }

    public String writeText(PDStream pdStream) throws IOException {
        PDFStreamParser pdfStreamParser = new PDFStreamParser(pdStream);
        pdfStreamParser.parse();
        List<Object> it = pdfStreamParser.getTokens();
        List<COSBase> arguments = new ArrayList<COSBase>();
        for (Object o : it) {
            if (o instanceof Operator) {
                Operator op = (Operator)o;
                readPDFArguments(op, arguments);
                s.append(op.getName() + "\n");
                arguments.clear();
                if (op.getImageParameters() != null) {
                    for (Map.Entry<COSName, COSBase> cn : op.getImageParameters().entrySet()) {
                        arguments.add(cn.getKey());
                        arguments.add(cn.getValue());
                    }
                    readPDFArguments(op, arguments);
                    s.append("ID " + new String(op.getImageData(), "ISO-8859-1"));
                    arguments.clear();
                    s.append("EI\n");
                }
            } else {
                arguments.add((COSBase)o);
            }
        }
        return s.toString();
    }

    protected void readPDFArguments(Operator op, Collection<COSBase> arguments) throws IOException {
        for (COSBase c : arguments) {
            processArg(op, c);
        }
    }

    protected void processArg(Operator op, COSBase c) throws IOException {
        if (c instanceof COSInteger) {
            s.append(((COSInteger) c).intValue());
            s.append(" ");
        } else if (c instanceof COSFloat) {
            float f = ((COSFloat) c).floatValue();
            s.append(new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.US)).format(f));
            s.append(" ");
        } else if (c instanceof COSName) {
            COSName cn = (COSName)c;
            s.append("/" + key.getName(cn));
            s.append(" ");
        } else if (c instanceof COSString) {
            s.append("<" + ((COSString) c).toHexString() + ">");
        } else if (c instanceof COSArray) {
            s.append("[");
            readPDFArguments(op, (Collection<COSBase>) ((COSArray) c).toList());
            s.append("] ");
        } else if (c instanceof COSDictionary) {
            Collection<COSBase> dictArgs = new ArrayList<COSBase>();
            if (currentMCID != 0 && op.getName().equals("BDC")) {
                for (Map.Entry<COSName, COSBase> cn : ((COSDictionary)c).entrySet()) {
                    if (cn.getKey().getName().equals("MCID")) {
                        updateMCID(cn, dictArgs);
                    } else {
                        dictArgs.add(cn.getKey());
                        dictArgs.add(cn.getValue());
                    }
                }
            } else {
                for (Map.Entry<COSName, COSBase> cn : ((COSDictionary)c).entrySet()) {
                    dictArgs.add(cn.getKey());
                    dictArgs.add(cn.getValue());
                }
            }
            s.append("<<");
            readPDFArguments(op, dictArgs);
            s.append(">>");
        } else if (c instanceof COSBoolean) {
            s.append(((COSBoolean) c).getValue());
        } else {
            throw new IOException(c + " not supported");
        }
    }

    private void updateMCID(Map.Entry<COSName, COSBase> cn, Collection<COSBase> dictArgs) {
        COSBase cosMCID = cn.getValue();
        assert cosMCID instanceof COSInteger;
        COSInteger mcid = (COSInteger) cosMCID;
        COSInteger updatedID = COSInteger.get(mcid.intValue() + currentMCID);
        dictArgs.add(cn.getKey());
        dictArgs.add(updatedID);
    }

    protected int getCurrentMCID() {
        return currentMCID;
    }
}
