<commit_before>package org.libreoffice;

import android.graphics.RectF;
import android.util.Log;

import org.libreoffice.kit.Document;
import org.mozilla.gecko.TextSelection;
import org.mozilla.gecko.TextSelectionHandle;

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

/**
 * Parses (interprets) and handles invalidation messages from LibreOffice.
 */
public class InvalidationHandler {
    private static String LOGTAG = InvalidationHandler.class.getSimpleName();

    private TextCursorLayer mTextCursorLayer;
    private TextSelection mTextSelection;

    public InvalidationHandler(LibreOfficeMainActivity mainActivity) {
        mTextCursorLayer = mainActivity.getTextCursorLayer();
        mTextSelection = mainActivity.getTextSelection();
    }

    /**
     * Processes invalidation message
     *
     * @param messageID - ID of the message
     * @param payload   - additional invalidation message payload
     */
    public void processMessage(int messageID, String payload) {
        switch (messageID) {
            case Document.CALLBACK_INVALIDATE_TILES:
                invalidateTiles(payload);
                break;
            case Document.CALLBACK_INVALIDATE_VISIBLE_CURSOR:
                Log.i(LOGTAG, "Cursor: " + payload);
                invalidateCursor(payload);
                break;
            case Document.CALLBACK_INVALIDATE_TEXT_SELECTION:
                Log.i(LOGTAG, "Selection: " + payload);
                invalidateSelection(payload);
                break;
            case Document.CALLBACK_INVALIDATE_TEXT_SELECTION_START:
                Log.i(LOGTAG, "Selection start: " + payload);
                invalidateSelectionStart(payload);
                break;
            case Document.CALLBACK_INVALIDATE_TEXT_SELECTION_END:
                Log.i(LOGTAG, "Selection end: " + payload);
                invalidateSelectionEnd(payload);
                break;
        }
    }

    /**
     * Parses the payload text with rectangle coordinates and converts to rectangle in pixel coordinates
     *
     * @param payload - invalidation message payload text
     * @return rectangle in pixel coordinates
     */
    private RectF convertPayloadToRectangle(String payload) {
        if (payload.equals("EMPTY")) {
            return null;
        }

        String[] coordinates = payload.split(",");

        if (coordinates.length != 4) {
            return null;
        }
        int width = Integer.decode(coordinates[0].trim());
        int height = Integer.decode(coordinates[1].trim());
        int x = Integer.decode(coordinates[2].trim());
        int y = Integer.decode(coordinates[3].trim());

        float dpi = (float) LOKitShell.getDpi();

        RectF rect = new RectF(
                LOKitTileProvider.twipToPixel(x, dpi),
                LOKitTileProvider.twipToPixel(y, dpi),
                LOKitTileProvider.twipToPixel(x + width, dpi),
                LOKitTileProvider.twipToPixel(y + height, dpi)
        );

        return rect;
    }

    /**
     * Parses the payload text with more rectangles (separated by ';') and converts to a list of rectangles.
     *
     * @param payload - invalidation message payload text
     * @return list of rectangles
     */
    private List<RectF> convertPayloadToRectangles(String payload) {
        List<RectF> rectangles = new ArrayList<RectF>();
        String[] rectangleArray = payload.split(";");

        for (String coordinates : rectangleArray) {
            RectF rectangle = convertPayloadToRectangle(payload);
            rectangles.add(rectangle);
        }

        return rectangles;
    }

    /**
     * From input rectangle, create a new rectangle which positions under the input rectangle.
     *
     * @param rectangle - input rectangle
     * @return new rectangle positioned under the input rectangle
     */
    private RectF createRectangleUnderSelection(RectF rectangle) {
        return new RectF(rectangle.centerX(), rectangle.bottom, rectangle.centerX(), rectangle.bottom);
    }

    /**
     * Handles the cursor invalidation message
     *
     * @param payload
     */
    private void invalidateCursor(String payload) {
        RectF cursorRectangle = convertPayloadToRectangle(payload);
        if (cursorRectangle != null) {
            TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
            textSelection.positionHandle(TextSelectionHandle.HandleType.MIDDLE, createRectangleUnderSelection(cursorRectangle));
            textSelection.showHandle(TextSelectionHandle.HandleType.MIDDLE);

            textSelection.hideHandle(TextSelectionHandle.HandleType.START);
            textSelection.hideHandle(TextSelectionHandle.HandleType.END);

            TextCursorLayer textCursorLayer = LibreOfficeMainActivity.mAppContext.getTextCursorLayer();
            textCursorLayer.positionCursor(cursorRectangle);
            textCursorLayer.showCursor();
        }
    }

    /**
     * Handles the tile invalidation message
     *
     * @param payload
     */
    private void invalidateTiles(String payload) {
        RectF rectangle = convertPayloadToRectangle(payload);
        if (rectangle != null) {
            LOKitShell.sendTileInvalidationRequest(rectangle);
        }
    }

    /**
     * Handles the selection start invalidation message
     *
     * @param payload
     */
    private void invalidateSelectionStart(String payload) {
        RectF selectionRectangle = convertPayloadToRectangle(payload);
        if (selectionRectangle != null) {
            mTextSelection.positionHandle(TextSelectionHandle.HandleType.START, createRectangleUnderSelection(selectionRectangle));
            mTextSelection.showHandle(TextSelectionHandle.HandleType.START);
            mTextSelection.hideHandle(TextSelectionHandle.HandleType.MIDDLE);
            mTextCursorLayer.hideCursor();
        }
    }

    /**
     * Handles the selection end invalidation message
     *
     * @param payload
     */
    private void invalidateSelectionEnd(String payload) {
        RectF selectionRect = convertPayloadToRectangle(payload);<commit_msg>android: swap position of invalidateCursor and invalidateTiles<commit_after>package org.libreoffice;

import android.graphics.RectF;
import android.util.Log;

import org.libreoffice.kit.Document;
import org.mozilla.gecko.TextSelection;
import org.mozilla.gecko.TextSelectionHandle;

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

/**
 * Parses (interprets) and handles invalidation messages from LibreOffice.
 */
public class InvalidationHandler {
    private static String LOGTAG = InvalidationHandler.class.getSimpleName();

    private TextCursorLayer mTextCursorLayer;
    private TextSelection mTextSelection;

    public InvalidationHandler(LibreOfficeMainActivity mainActivity) {
        mTextCursorLayer = mainActivity.getTextCursorLayer();
        mTextSelection = mainActivity.getTextSelection();
    }

    /**
     * Processes invalidation message
     *
     * @param messageID - ID of the message
     * @param payload   - additional invalidation message payload
     */
    public void processMessage(int messageID, String payload) {
        switch (messageID) {
            case Document.CALLBACK_INVALIDATE_TILES:
                invalidateTiles(payload);
                break;
            case Document.CALLBACK_INVALIDATE_VISIBLE_CURSOR:
                Log.i(LOGTAG, "Cursor: " + payload);
                invalidateCursor(payload);
                break;
            case Document.CALLBACK_INVALIDATE_TEXT_SELECTION:
                Log.i(LOGTAG, "Selection: " + payload);
                invalidateSelection(payload);
                break;
            case Document.CALLBACK_INVALIDATE_TEXT_SELECTION_START:
                Log.i(LOGTAG, "Selection start: " + payload);
                invalidateSelectionStart(payload);
                break;
            case Document.CALLBACK_INVALIDATE_TEXT_SELECTION_END:
                Log.i(LOGTAG, "Selection end: " + payload);
                invalidateSelectionEnd(payload);
                break;
        }
    }

    /**
     * Parses the payload text with rectangle coordinates and converts to rectangle in pixel coordinates
     *
     * @param payload - invalidation message payload text
     * @return rectangle in pixel coordinates
     */
    private RectF convertPayloadToRectangle(String payload) {
        if (payload.equals("EMPTY")) {
            return null;
        }

        String[] coordinates = payload.split(",");

        if (coordinates.length != 4) {
            return null;
        }
        int width = Integer.decode(coordinates[0].trim());
        int height = Integer.decode(coordinates[1].trim());
        int x = Integer.decode(coordinates[2].trim());
        int y = Integer.decode(coordinates[3].trim());

        float dpi = (float) LOKitShell.getDpi();

        RectF rect = new RectF(
                LOKitTileProvider.twipToPixel(x, dpi),
                LOKitTileProvider.twipToPixel(y, dpi),
                LOKitTileProvider.twipToPixel(x + width, dpi),
                LOKitTileProvider.twipToPixel(y + height, dpi)
        );

        return rect;
    }

    /**
     * Parses the payload text with more rectangles (separated by ';') and converts to a list of rectangles.
     *
     * @param payload - invalidation message payload text
     * @return list of rectangles
     */
    private List<RectF> convertPayloadToRectangles(String payload) {
        List<RectF> rectangles = new ArrayList<RectF>();
        String[] rectangleArray = payload.split(";");

        for (String coordinates : rectangleArray) {
            RectF rectangle = convertPayloadToRectangle(payload);
            rectangles.add(rectangle);
        }

        return rectangles;
    }

    /**
     * From input rectangle, create a new rectangle which positions under the input rectangle.
     *
     * @param rectangle - input rectangle
     * @return new rectangle positioned under the input rectangle
     */
    private RectF createRectangleUnderSelection(RectF rectangle) {
        return new RectF(rectangle.centerX(), rectangle.bottom, rectangle.centerX(), rectangle.bottom);
    }

    /**
     * Handles the tile invalidation message
     *
     * @param payload
     */
    private void invalidateTiles(String payload) {
        RectF rectangle = convertPayloadToRectangle(payload);
        if (rectangle != null) {
            LOKitShell.sendTileInvalidationRequest(rectangle);
        }
    }

    /**
     * Handles the cursor invalidation message
     *
     * @param payload
     */
    private void invalidateCursor(String payload) {
        RectF cursorRectangle = convertPayloadToRectangle(payload);
        if (cursorRectangle != null) {
            TextSelection textSelection = LibreOfficeMainActivity.mAppContext.getTextSelection();
            textSelection.positionHandle(TextSelectionHandle.HandleType.MIDDLE, createRectangleUnderSelection(cursorRectangle));
            textSelection.showHandle(TextSelectionHandle.HandleType.MIDDLE);

            textSelection.hideHandle(TextSelectionHandle.HandleType.START);
            textSelection.hideHandle(TextSelectionHandle.HandleType.END);

            TextCursorLayer textCursorLayer = LibreOfficeMainActivity.mAppContext.getTextCursorLayer();
            textCursorLayer.positionCursor(cursorRectangle);
            textCursorLayer.showCursor();
        }
    }

    /**
     * Handles the selection start invalidation message
     *
     * @param payload
     */
    private void invalidateSelectionStart(String payload) {
        RectF selectionRectangle = convertPayloadToRectangle(payload);
        if (selectionRectangle != null) {
            mTextSelection.positionHandle(TextSelectionHandle.HandleType.START, createRectangleUnderSelection(selectionRectangle));
            mTextSelection.showHandle(TextSelectionHandle.HandleType.START);
            mTextSelection.hideHandle(TextSelectionHandle.HandleType.MIDDLE);
            mTextCursorLayer.hideCursor();
        }
    }

    /**
     * Handles the selection end invalidation message
     *
     * @param payload
     */
    private void invalidateSelectionEnd(String payload) {
        RectF selectionRect = convertPayloadToRectangle(payload);
{'fraction_non_alphanumeric': 0.08385522570150468, 'fraction_numerical': 0.0008133387555917039, 'mean_word_length': 2.5984781972490487, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1796614', 'n_tokens_mistral': 3179, 'n_tokens_neox': 3078, 'n_words': 691}