#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.

from fenrirscreenreader.core import debug


class CursorManager:
    def __init__(self):
        pass

    def initialize(self, environment):
        self.env = environment

    def should_process_numpad_commands(self):
        """
        Check if numpad commands should be processed based on numlock state
        Return True if numlock is OFF (commands should work)
        Return False if numlock is ON (let keys type numbers)
        """
        # Return False if numlock is ON
        return not self.env["input"]["new_num_lock"]

    def shutdown(self):
        pass

    def clear_marks(self):
        self.env["commandBuffer"]["Marks"]["1"] = None
        self.env["commandBuffer"]["Marks"]["2"] = None

    def is_mark_set(self):
        return self.env["commandBuffer"]["Marks"]["1"] is not None

    def is_single_mark(self):
        return (
            self.env["commandBuffer"]["Marks"]["1"] is not None
            and self.env["commandBuffer"]["Marks"]["2"] is None
        )

    def is_multible_mark(self):
        return (
            self.env["commandBuffer"]["Marks"]["1"] is not None
            and self.env["commandBuffer"]["Marks"]["2"] is not None
        )

    def set_mark(self):
        curr_cursor = None
        if self.env["screen"]["newCursorReview"]:
            curr_cursor = self.env["screen"]["newCursorReview"].copy()
        else:
            curr_cursor = self.env["screen"]["new_cursor"].copy()
        if not self.env["commandBuffer"]["Marks"]["1"]:
            self.env["commandBuffer"]["Marks"]["1"] = curr_cursor.copy()
            return 1
        else:
            self.env["commandBuffer"]["Marks"]["2"] = curr_cursor.copy()
            return 2
        return 0

    def get_review_or_text_cursor(self):
        if self.env["screen"]["newCursorReview"]:
            return self.env["screen"]["newCursorReview"].copy()
        else:
            return self.env["screen"]["new_cursor"].copy()

    def clear_review_cursor(self):
        if not self.is_review_mode():
            return
        self.env["screen"]["oldCursorReview"] = None
        self.env["screen"]["newCursorReview"] = None

    def is_cursor_horizontal_move(self):
        return (
            self.env["screen"]["new_cursor"]["x"]
            != self.env["screen"]["old_cursor"]["x"]
        )

    def is_cursor_vertical_move(self):
        return (
            self.env["screen"]["new_cursor"]["y"]
            != self.env["screen"]["old_cursor"]["y"]
        )

    def is_review_mode(self):
        return self.env["screen"]["newCursorReview"] is not None

    def enter_review_mode_curr_text_cursor(self, overwrite=False):
        if self.is_review_mode() and not overwrite:
            return
        self.env["screen"]["oldCursorReview"] = self.env["screen"][
            "newCursorReview"
        ]
        if not self.env["screen"]["newCursorReview"]:
            self.env["screen"]["newCursorReview"] = self.env["screen"][
                "new_cursor"
            ].copy()
            if (
                self.env["runtime"]["SettingsManager"].get_setting_as_bool(
                    "focus", "highlight"
                )
                and self.env["runtime"][
                    "AttributeManager"
                ].is_attribute_cursor_active()
            ):
                self.env["screen"]["newCursorReview"] = (
                    self.env["runtime"]["AttributeManager"]
                    .get_curr_attribute_cursor()
                    .copy()
                )

    def set_review_cursor_position(self, x, y):
        if not self.is_review_mode():
            self.enter_review_mode_curr_text_cursor()
        self.env["screen"]["oldCursorReview"] = self.env["screen"][
            "newCursorReview"
        ]
        self.env["screen"]["newCursorReview"]["x"] = x
        self.env["screen"]["newCursorReview"]["y"] = y

    def is_application_window_set(self):
        try:
            curr_app = self.env["runtime"][
                "ApplicationManager"
            ].get_current_application()
            if (
                curr_app in self.env["commandBuffer"]["windowArea"]
                and "1" in self.env["commandBuffer"]["windowArea"][curr_app]
                and self.env["commandBuffer"]["windowArea"][curr_app]["1"]
                is not None
            ):
                return True
        except Exception as e:
            self.env["runtime"]["DebugManager"].write_debug_out(
                "CursorManager is_application_window_set: Error checking window area: "
                + str(e),
                debug.DebugLevel.ERROR,
            )
        return False

    def set_window_for_application(self, start=None, end=None):
        x1 = 0
        x2 = 0
        y1 = 0
        y2 = 0
        if start is None:
            if not self.env["commandBuffer"]["Marks"]["1"]:
                return False
            else:
                x1 = self.env["commandBuffer"]["Marks"]["1"]["x"]
                y1 = self.env["commandBuffer"]["Marks"]["1"]["y"]
        else:
            x1 = start["x"]
            y1 = start["y"]
        if end is None:
            if not self.env["commandBuffer"]["Marks"]["2"]:
                return False
            else:
                x2 = self.env["commandBuffer"]["Marks"]["2"]["x"]
                y2 = self.env["commandBuffer"]["Marks"]["2"]["y"]
        else:
            x2 = end["x"]
            y2 = end["y"]

        curr_app = self.env["runtime"][
            "ApplicationManager"
        ].get_current_application()
        self.env["commandBuffer"]["windowArea"][curr_app] = {}

        if x1 * y1 <= x2 * y2:
            self.env["commandBuffer"]["windowArea"][curr_app]["1"] = {
                "x": x1,
                "y": y1,
            }
            self.env["commandBuffer"]["windowArea"][curr_app]["2"] = {
                "x": x2,
                "y": y2,
            }
        else:
            self.env["commandBuffer"]["windowArea"][curr_app]["1"] = {
                "x": x2,
                "y": y2,
            }
            self.env["commandBuffer"]["windowArea"][curr_app]["2"] = {
                "x": x1,
                "y": y1,
            }
        return True

    def clear_window_for_application(self):
        curr_app = self.env["runtime"][
            "ApplicationManager"
        ].get_current_application()
        try:
            del self.env["commandBuffer"]["windowArea"][curr_app]
        except Exception as e:
            self.env["runtime"]["DebugManager"].write_debug_out(
                "CursorManager clear_window_for_application: Error clearing window area: "
                + str(e),
                debug.DebugLevel.ERROR,
            )
            return False
        return True
