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

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.knecon.fforesight.service.layoutparser.processor.docstrum.model.BoundingBox;
import com.knecon.fforesight.service.layoutparser.processor.model.text.TextPageBlock;
import com.knecon.fforesight.service.layoutparser.processor.model.text.Word;
import com.knecon.fforesight.service.layoutparser.processor.utils.TextNormalizationUtilities;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@SuppressWarnings("serial")
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class Cell extends BoundingBox {

    private List<TextPageBlock> textBlocks = new ArrayList<>();

    private List<Cell> headerCells = new ArrayList<>();

    private boolean isHeaderCell;

    private static final int MIN_SIZE = 1;

    private int pageNumber;


    public Cell(Point2D topLeft, Point2D bottomRight) {

        this.bBoxPdf = new Rectangle2D.Double(topLeft.getX(), topLeft.getY(), (bottomRight.getX() - topLeft.getX()), (bottomRight.getY() - topLeft.getY()));
        this.bBox = bBoxPdf;
    }


    public Cell(Rectangle2D bBoxInitialUserSpace, AffineTransform initialUserSpaceToJava) {

        this.bBoxPdf = bBoxInitialUserSpace;
        this.bBox = initialUserSpaceToJava.createTransformedShape(bBoxInitialUserSpace).getBounds2D();
    }


    public static Cell copy(Cell cell) {

        Cell copy = new Cell();
        copy.bBoxPdf = cell.bBoxPdf;
        copy.bBox = cell.bBox;
        return copy;
    }


    public void addTextBlock(TextPageBlock textBlock) {

        textBlocks.add(textBlock);
    }


    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();

        Iterator<TextPageBlock> itty = textBlocks.iterator();
        Word previous = null;
        while (itty.hasNext()) {

            TextPageBlock textBlock = itty.next();

            for (Word word : textBlock.getWords()) {
                if (previous != null) {
                    if (Math.abs(previous.getMaxYDirAdj() - word.getMaxYDirAdj()) > word.getTextHeight()) {
                        sb.append('\n');
                    } else {
                        sb.append(' ');
                    }
                }
                sb.append(word.toString());
                previous = word;
            }

        }

        return TextNormalizationUtilities.cleanString(sb.toString());
    }


    public boolean hasMinimumSize() {

        return this.getHeight() >= MIN_SIZE && this.getWidth() >= MIN_SIZE;
    }

}
