from helix.constants.subarray import SUBARRAY_SIZE_BIG
from helix.constants.system_type import SystemType
from helix.models.dxf.dxf_error import DXFError
from helix.models.dxf.graph_direction import GraphDirection


class SubarrayValidator(object):
    """
    Tests to make sure that Single Tilt systems have East or West neighbors
    (as a panel without an East/West neighbor is
    invalid, and that Dual Tilt systems have North or South neighbors.
    Also checks to make sure that all "sides" of the
    subarray are less than 150' long (due to government safety requirements).
    """

    @staticmethod
    def validate_subarray(node_graph, subarray_number, system_type):
        subarray_node_graph = [node for node in node_graph if node.panel.subarray == subarray_number]
        furthest_west = subarray_node_graph[0].panel.coordinate.unrotate()
        furthest_east = subarray_node_graph[0].panel.coordinate.unrotate()
        furthest_north = subarray_node_graph[0].panel.coordinate.unrotate()
        furthest_south = subarray_node_graph[0].panel.coordinate.unrotate()

        for node in subarray_node_graph:
            if system_type == SystemType.singleTilt:
                if not (node.has_existing_neighbor(GraphDirection.East) or node.has_existing_neighbor(GraphDirection.West)):
                    raise DXFError("Error - Unsupported panel configuration in subarray %d." % subarray_number)
            if not (node.has_existing_neighbor(GraphDirection.North) or node.has_existing_neighbor(GraphDirection.South)):
                raise DXFError("Error - Unsupported panel configuration in subarray %d." % subarray_number)
            rotated_coordinate = node.panel.coordinate.unrotate()
            if rotated_coordinate.x < furthest_west.x:
                furthest_west = rotated_coordinate
            elif rotated_coordinate.x > furthest_east.x:
                furthest_east = rotated_coordinate
            if rotated_coordinate.y < furthest_south.y:
                furthest_south = rotated_coordinate
            elif rotated_coordinate.y > furthest_north.y:
                furthest_north = rotated_coordinate

        # detect subarray size
        horizontal_distance = furthest_east.x - furthest_west.x
        if horizontal_distance > (150 * 12):
            raise DXFError(SUBARRAY_SIZE_BIG)

        vertical_distance = furthest_north.y - furthest_south.y
        if vertical_distance > (150 * 12):
            raise DXFError(SUBARRAY_SIZE_BIG)
