from numpy import array

from helix.constants.global_constants import minimum_racking_capacity
from helix.constants.panel_type import PanelType


class DualTilt128CellConstants(object):
    tolerance = 0.1 #require 10% additional space for panel spacing
    panel_spacing = (88.24, 82.0)  # inches
    spacing_size_inches = 5.12  # This is inches
    presenter_spacing = (1.5, 1.5)
    panel_area = 23.29
    surface_area = 46.58  # aka tent area
    tributary_area = array([3.23, 6.84, 6.54, 13.57])
    ground_coverage_ratio = 0.91
    friction_coefficient = 0.59
    seismic_anchor_interval_constants = (13.8768, 3.23792)
    max_psf = 32

    def c_p_lower_bound(self):
        return array([0.06, 0.05, 0.052, 0.039])

    def edge_factor(self, wind_zone, panel_type):
        return 1

    def racking_capacity(self, panel_type):
        if panel_type == PanelType.Corner or panel_type == PanelType.NorthSouth:
            return minimum_racking_capacity
        else:
            return 308

    def c_p_constants(self, A_n, wind_zone):
        if wind_zone == 'A':
            if A_n < 825:
                return -0.144, 1.1451
            else:
                return -0.058, 0.5651
        elif wind_zone == 'B':
            if A_n < 465:
                return -0.117, 0.8824
            elif A_n < 825:
                return -0.087, 0.6981
            else:
                return -0.033, 0.3336
        elif wind_zone == 'C':
            if A_n < 465:
                return -0.073, 0.5479
            elif A_n < 825:
                return -0.035, 0.3143
            else:
                return -0.015, 0.184
        elif wind_zone == 'D':
            if A_n < 465:
                return -0.039, 0.303
            elif A_n < 825:
                return -0.023, 0.2023
            else:
                return -0.008, 0.102
        else:
            return 1, 1

    def base_weight(self, panel_type, tray_count):
        values_per_panel_type = {
            PanelType.Corner:       [122.70,
                                    124.55,
                                    126.40,
                                    129.55,
                                    132.71,
                                    135.86,
                                    139.01][tray_count],
            PanelType.NorthSouth:   [121.63,
                                    123.48,
                                    125.33,
                                    128.48,
                                    131.64,
                                    134.79,
                                    137.94][tray_count],
            PanelType.EastWest:     [118.28,
                                    120.13,
                                    121.99,
                                    125.14,
                                    128.29,
                                    131.45,
                                    134.60][tray_count],
            PanelType.Middle:       [117.21,
                                    119.06,
                                    120.92,
                                    124.07,
                                    127.22,
                                    130.38,
                                    133.53][tray_count],   
        }
        return values_per_panel_type.get(panel_type)

    def link_tray_thresholds(self, panel_type):
        if panel_type == PanelType.Corner or panel_type == PanelType.NorthSouth:
            return [7.5, 10, 15]
        else:
            return [5, 7.5, 10]

    def cross_tray_thresholds(self, panel_type):
        if panel_type == PanelType.Corner or panel_type == PanelType.NorthSouth:
            return [15, 23, 31, 39, 47]
        else:
            return [10, 18, 26, 34, 42]

    def weighted_average_c_p(self, corner, north_south, east_west, middle):
        return (corner * 2. + east_west * 26. + middle * 104. + north_south * 8.) / 140.

    def minimum_a_n_coefficients(self, uplift_c_p, wind_zone):
        if wind_zone == 'A':
            if uplift_c_p > 0.275:
                return 1.5305, 0.187
            else:
                return 0.9252, 0.097
        elif wind_zone == 'B':
            if uplift_c_p > 0.2292:
                return 1.2058, 0.159
            elif uplift_c_p > 0.1534:
                return 1.0334, 0.131
            else:
                return 0.4411, 0.043
        elif wind_zone == 'C':
            if uplift_c_p > 0.151:
                return 0.7899, 0.104
            elif uplift_c_p > 0.108:
                return 0.5785, 0.07
            else:
                return 0.2921, 0.027
        elif wind_zone == 'D':
            if uplift_c_p > 0.0929:
                return 0.3939, 0.049
            elif uplift_c_p > 0.069:
                return 0.3043, 0.035
            else:
                return 0.122, 0.008
        return None
