package com.knecon.fforesight.service.layoutparser.processor.model.text;

import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

import org.apache.pdfbox.text.TextPosition;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RedTextPosition {

    private final static int HEIGHT_PADDING = 2;
    private Rectangle2D.Float directionAdjustedPosition;
    private Rectangle2D initialUserSpacePosition;

    @JsonIgnore
    private int rotation;

    @JsonIgnore
    private float pageHeight;

    @JsonIgnore
    private float pageWidth;

    private String unicode;

    @JsonIgnore
    private float dir;

    // not used in reanalysis
    @JsonIgnore
    private float widthOfSpace;

    // not used in reanalysis
    @JsonIgnore
    private float fontSizeInPt;

    // not used in reanalysis
    @JsonIgnore
    private String fontName;


    @SneakyThrows
    public static RedTextPosition fromTextPosition(TextPosition textPosition) {

        var pos = new RedTextPosition();
        pos.setRotation(textPosition.getRotation());
        pos.setPageHeight(textPosition.getPageHeight());
        pos.setPageWidth(textPosition.getPageWidth());
        pos.setUnicode(textPosition.getUnicode());
        pos.setDir(textPosition.getDir());
        pos.setWidthOfSpace(textPosition.getWidthOfSpace());
        pos.setFontSizeInPt(textPosition.getFontSizeInPt());
        pos.setFontName(textPosition.getFont().getName());

        float textHeight = textPosition.getHeight() + HEIGHT_PADDING;
        Rectangle2D.Float dirAdjPosition = new Rectangle2D.Float(textPosition.getXDirAdj(),
                                                            textPosition.getYDirAdj() - textHeight,
                                                            textPosition.getWidthDirAdj(),
                                                            textHeight + HEIGHT_PADDING);
        pos.setDirectionAdjustedPosition(dirAdjPosition);

        AffineTransform affineTransform = getRotationMatrix(TextDirection.fromDegrees(textPosition.getDir()), textPosition.getPageWidth(), textPosition.getPageHeight());
        Rectangle2D initialUserSpacePositionRect = affineTransform.createTransformedShape(dirAdjPosition).getBounds2D();

        pos.setInitialUserSpacePosition(initialUserSpacePositionRect);

        return pos;
    }


    private static AffineTransform getRotationMatrix(TextDirection textDirection, float pageWidth, float pageHeight) {

        AffineTransform transform = new AffineTransform();

        if (textDirection == TextDirection.ZERO || textDirection == TextDirection.HALF_CIRCLE) {
            transform.rotate(textDirection.getRadians(), pageWidth / 2f, pageHeight / 2f);
            transform.translate(0f, pageHeight);
        } else if (textDirection == TextDirection.QUARTER_CIRCLE) {
            transform.rotate(textDirection.getRadians(), pageWidth / 2f, pageWidth / 2f);
            transform.translate(0f, pageWidth);
        } else {
            transform.rotate(textDirection.getRadians(), pageHeight / 2f, pageHeight / 2f);
            transform.translate(0f, pageWidth);
        }
        transform.scale(1., -1.);
        return transform;
    }

    @JsonIgnore
    public float getXDirAdj() {

        return this.directionAdjustedPosition.x;
    }


    @JsonIgnore
    public float getYDirAdj() {

        return  this.directionAdjustedPosition.y;
    }


    @JsonIgnore
    public float getWidthDirAdj() {

        return this.directionAdjustedPosition.width;
    }


    @JsonIgnore
    public float getHeightDir() {

        return this.directionAdjustedPosition.height;
    }

}
