package io.lumify.core.model.artifactThumbnails;

import com.altamiracorp.bigtable.model.ModelSession;
import com.altamiracorp.bigtable.model.Repository;
import com.altamiracorp.bigtable.model.Row;
import io.lumify.core.config.Configuration;
import io.lumify.core.exception.LumifyResourceNotFoundException;
import io.lumify.core.user.User;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;

import org.securegraph.Vertex;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public abstract class ArtifactThumbnailRepository extends Repository<BigTableArtifactThumbnail> {
    private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(ArtifactThumbnailRepository.class);
    public static int FRAMES_PER_PREVIEW = 20;
    public static int PREVIEW_FRAME_WIDTH = 360;
    public static int PREVIEW_FRAME_HEIGHT = 240;
    private final String yAxisFlipNeededPropertyIri;
    private final String cwRotationNeededPropertyIri;

    public ArtifactThumbnailRepository(ModelSession modelSession, final Configuration configuration) {
        super(modelSession);
        this.yAxisFlipNeededPropertyIri = configuration.get("ontology.iri.yAxisFlipNeeded", null);
        this.cwRotationNeededPropertyIri = configuration.get("ontology.iri.cwRotationNeeded", null);
        LOGGER.info("The yAxisFlipNeededPropertyIri is (From Constructor):" + yAxisFlipNeededPropertyIri );
        LOGGER.info("The cwRotationNeededPropertyIri is (From Constructor):" + cwRotationNeededPropertyIri );
    }

    public abstract BigTableArtifactThumbnail fromRow(Row row);

    public abstract Row toRow(BigTableArtifactThumbnail artifactThumbnail);

    public abstract String getTableName();

    public abstract ArtifactThumbnail getThumbnail(Object artifactVertexId, String thumbnailType, int width, int height, User user);

    public abstract byte[] getThumbnailData(Object artifactVertexId, String thumbnailType, int width, int height, User user);

    public abstract ArtifactThumbnail createThumbnail(Vertex artifactVertex, String thumbnailType, InputStream in, int[] boundaryDims, User user) throws IOException;

    public ArtifactThumbnail generateThumbnail(Vertex artifactVertex, InputStream in, int[] boundaryDims) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        String format;
        int type;
        try {

            BufferedImage originalImage = ImageIO.read(in);
            type = ImageUtils.thumbnailType(originalImage);
            format = ImageUtils.thumbnailFormat(originalImage);

            //Flip and Rotate the original image, to create the transformed image. Only supports rotate. Not flip.
            LOGGER.info("The cwRotationNeededPropertyIri is (From Constructor):" + cwRotationNeededPropertyIri );
            BufferedImage transformedImage = originalImage;
            if (cwRotationNeededPropertyIri != null) {
                Integer cwRotationNeeded = (Integer) artifactVertex.getPropertyValue(cwRotationNeededPropertyIri);
                Boolean yAxisFlipNeeded = (Boolean) artifactVertex.getPropertyValue(yAxisFlipNeededPropertyIri);
                LOGGER.info("cwRotationNeeded: " + cwRotationNeeded);
                LOGGER.info("yAxisFlipNeeded: " + yAxisFlipNeeded);

                if (cwRotationNeeded % 360 != 0) {
                    transformedImage = ImageUtils.tilt(originalImage, cwRotationNeeded );
                    LOGGER.info("cwRotationNeeded. rotating the image. inside the if statement. ");
                }
                else {
                    LOGGER.info("cwRotationNeeded. inside the else statement. ");
                }
            }


            //Get new image dimensions, which will be used for the icon.
            int[] transformedImageDims = new int[]{transformedImage.getWidth(), transformedImage.getHeight()};
            int[] newImageDims = getScaledDimension(transformedImageDims, boundaryDims);
            if (newImageDims[0] >= transformedImageDims[0] || newImageDims[1] >= transformedImageDims[1]) {
                LOGGER.info("Original image dimensions %d x %d are smaller "
                                + "than requested dimensions %d x %d returning original.",
                        transformedImageDims[0], transformedImageDims[1],
                        newImageDims[0], newImageDims[1]);
            }


            //Resize the image.
            BufferedImage resizedImage = new BufferedImage(newImageDims[0], newImageDims[1], type);
            Graphics2D g = resizedImage.createGraphics();
            if (transformedImage.getColorModel().getNumComponents() > 3) {
                g.drawImage(transformedImage, 0, 0, resizedImage.getWidth(), resizedImage.getHeight(), null);
            } else {
                g.drawImage(transformedImage, 0, 0, resizedImage.getWidth(), resizedImage.getHeight(), Color.BLACK, null);
            }
            g.dispose();

            //Write the bufferedImage to a file.
            ImageIO.write(resizedImage, format, out);
        } catch (IOException e) {
            throw new LumifyResourceNotFoundException("Error reading inputstream");
        }
        return new ArtifactThumbnail(out.toByteArray(), type, format);
    }

    public int[] getScaledDimension(int[] imgSize, int[] boundary) {
        int originalWidth = imgSize[0];
        int originalHeight = imgSize[1];
        int boundWidth = boundary[0];
        int boundHeight = boundary[1];
        int newWidth = originalWidth;
        int newHeight = originalHeight;

        if (originalWidth > boundWidth) {
            newWidth = boundWidth;
            newHeight = (newWidth * originalHeight) / originalWidth;
        }

        if (newHeight > boundHeight) {
            newHeight = boundHeight;
            newWidth = (newHeight * originalWidth) / originalHeight;
        }

        return new int[]{newWidth, newHeight};
    }
}

@@ -422,17 +422,16 @@
 actory;%0A
-%0A
 import o
@@ -1436,226 +1436,8 @@
 l);%0A
-        LOGGER.info(%22The yAxisFlipNeededPropertyIri is (From Constructor):%22 + yAxisFlipNeededPropertyIri );%0A        LOGGER.info(%22The cwRotationNeededPropertyIri is (From Constructor):%22 + cwRotationNeededPropertyIri );%0A
     
@@ -2586,122 +2586,8 @@
 ip.%0A
-            LOGGER.info(%22The cwRotationNeededPropertyIri is (From Constructor):%22 + cwRotationNeededPropertyIri );%0A
     
@@ -2929,508 +2929,146 @@
 i);%0A
-                LOGGER.info(%22cwRotationNeeded: %22 + cwRotationNeeded);%0A                LOGGER.info(%22yAxisFlipNeeded: %22 + yAxisFlipNeeded);%0A%0A                if (cwRotationNeeded %25 360 != 0) %7B%0A                    transformedImage = ImageUtils.tilt(originalImage, cwRotationNeeded );%0A                    LOGGER.info(%22cwRotationNeeded. rotating the image. inside the if statement. %22);%0A                %7D%0A                else %7B%0A                    LOGGER.info(%22cwRotationNeeded. inside the else statement. %22
+%0A                if (cwRotationNeeded %25 360 != 0) %7B%0A                    transformedImage = ImageUtils.tilt(originalImage, cwRotationNeeded
 );%0A 

remove LOGGER messages