package org.verapdf.model.impl.pb.operator.inlineimage;

import org.apache.log4j.Logger;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDResources;
import org.verapdf.model.baselayer.Object;
import org.verapdf.model.impl.pb.pd.images.PBoxPDInlineImage;
import org.verapdf.model.operator.Op_EI;
import org.verapdf.model.pdlayer.PDInlineImage;
import org.verapdf.model.tools.resources.PDExtendedResources;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Evgeniy Muravitskiy
 */
public class PBOp_EI extends PBOpInlineImage implements Op_EI {

	private static final Logger LOGGER = Logger.getLogger(PBOp_EI.class);

	public static final String OP_EI_TYPE = "Op_EI";

	public static final String INLINE_IMAGE = "inlineImage";

	private final byte[] imageData;
	private final PDResources resources;

	public PBOp_EI(List<COSBase> arguments, byte[] imageData,
				   PDExtendedResources resources) {
		super(arguments, OP_EI_TYPE);
		this.imageData = imageData;
		this.resources = this.getResources(resources);
	}

	@Override
	public List<? extends Object> getLinkedObjects(String link) {
		if (INLINE_IMAGE.equals(link)) {
			return this.getInlineImage();
		}

		return super.getLinkedObjects(link);
	}

	private List<PDInlineImage> getInlineImage() {
		try {
			COSBase parameters = this.arguments.get(0);
			org.apache.pdfbox.pdmodel.graphics.image.PDInlineImage inlineImage =
					new org.apache.pdfbox.pdmodel.graphics.image.PDInlineImage(
							(COSDictionary) parameters,
							this.imageData,
							this.resources);

			List<PDInlineImage> inlineImages = new ArrayList<>(MAX_NUMBER_OF_ELEMENTS);
			inlineImages.add(new PBoxPDInlineImage(inlineImage));
			return Collections.unmodifiableList(inlineImages);
		} catch (IOException e) {
			LOGGER.error(e);
		}
		return Collections.emptyList();
	}

	private PDResources getResources(PDExtendedResources resources) {
		PDResources currRes = resources.getCurrentResources();
		COSDictionary dictionary = resources.getPageResources().getCOSObject();
		PDResources pageRes = new PDResources(new COSDictionary(dictionary));

		this.putProperties(currRes, pageRes, COSName.FONT, currRes.getFontNames());
		this.putProperties(currRes, pageRes, COSName.COLORSPACE, currRes.getColorSpaceNames());
		this.putProperties(currRes, pageRes, COSName.EXT_G_STATE, currRes.getExtGStateNames());
		this.putProperties(currRes, pageRes, COSName.SHADING, currRes.getShadingNames());
		this.putProperties(currRes, pageRes, COSName.PATTERN, currRes.getPatternNames());
		this.putProperties(currRes, pageRes, COSName.XOBJECT, currRes.getXObjectNames());

		return pageRes;
	}

	private void putProperties(PDResources currentResources, PDResources pageResources,
							   COSName kind, Iterable<COSName> names) {
		for (COSName name : names) {
			pageResources.put(kind, name, currentResources.get(kind, name));
		}
	}
}

@@ -2257,142 +2257,27 @@
 %0A%0A%09%09
-this.putProperties(currRes, pageRes, COSName.FONT, currRes.getFontNames());%0A%09%09this.putProperties(currRes, pageRes, COSName.COLORSPACE,
+for (COSName name :
  cur
@@ -2306,68 +2306,40 @@
 s())
-;%0A%09%09this.putProperties(currRes, pageRes, COSName.EXT_G_STATE
+ %7B%0A%09%09%09try %7B%0A%09%09%09%09pageRes.put(name
 , cu
@@ -2351,542 +2351,142 @@
 .get
-ExtGStateN
+ColorSpace(n
 ame
-s(
 ));%0A%09%09
-this.putProperties(currRes, pageRes, COSName.SHADING, currRes.getShadingNames());%0A%09%09this.putProperties(currRes, pageRes, COSName.PATTERN, currRes.getPatternNames());%0A%09%09this.putProperties(currRes, pageRes, COSName.XOBJECT, currRes.getXObjectNames());%0A%0A%09%09return pageRes;%0A%09%7D%0A%0A%09private void putProperties(PDResour
+%09%7D catch (IOException e) %7B%0A%09%09%09%09LOGGER.warn(%22Problem with color spa
 ce
-s
  c
-urrentResources, PDResources pageResources,%0A%09%09%09%09%09%09%09   COSName kind, Iterable%3CCOSName%3E names) %7B%0A%09%09for (COSName name : names) %7B%0A%09%09%09pageResources.put(kind, name, currentResources.get(kind, name))
+oping.%22, e);%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09return pageRes
 ;%0A
-%09
 %09%7D%0A
-%09%7D
 %0A%7D%0A

Optimize resource coping