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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.knecon.fforesight.service.layoutparser.processor.docstrum.utils.FastAtan2;
import com.knecon.fforesight.service.layoutparser.processor.model.text.RedTextPosition;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;

@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Character {

    @EqualsAndHashCode.Include
    private final double x;
    @EqualsAndHashCode.Include
    private final double y;
    private final RedTextPosition textPosition;

    @Setter
    private List<Neighbor> neighbors = new ArrayList<>();


    public Character(RedTextPosition chunk) {

        this.x = chunk.getDirectionAdjustedPosition().getCenterX();
        this.y = chunk.getDirectionAdjustedPosition().getCenterY();
        this.textPosition = chunk;
    }


    public double getHeight() {

        return textPosition.getHeightDir();
    }


    public double distance(Character character) {

        double dx = getX() - character.getX();
        double dy = getY() - character.getY();
        return Math.sqrt(dx * dx + dy * dy);
    }


    public double horizontalDistance(Character character) {

        return Math.abs(getX() - character.getX());
    }


    public double verticalDistance(Character character) {

        return Math.abs(getY() - character.getY());
    }


    public double overlappingDistance(Character other) {

        double[] xs = new double[4];
        double s = Math.sin(-0);
        double c = Math.cos(-0);
        xs[0] = c * x - s * y;
        xs[1] = c * (x + textPosition.getWidthDirAdj()) - s * (y + textPosition.getHeightDir());
        xs[2] = c * other.x - s * other.y;
        xs[3] = c * (other.x + other.textPosition.getWidthDirAdj()) - s * (other.y + other.textPosition.getHeightDir());
        boolean overlapping = xs[1] >= xs[2] && xs[3] >= xs[0];
        Arrays.sort(xs);
        return Math.abs(xs[2] - xs[1]) * (overlapping ? 1 : -1);
    }


    public double angle(Character character) {

        if (getX() > character.getX()) {
            return FastAtan2.fastAtan2(getY() - character.getY(), getX() - character.getX());
        } else {
            return FastAtan2.fastAtan2(character.getY() - getY(), character.getX() - getX());
        }
    }

}