from .cli import ProgressBar
import numpy as np
import hiper

def soleno_calculate_field(elements, eval_coordinates, distance_limit = 999.9, job_name="B-Field Calculation"):
    """
    Calculates the field at all given evaluation coordinates, including the summed effect of all solenoid elements.
    Binds to Soleno-library in C.
    """
    # Progress counter
    n = 0
    # Number of solenoid elements
    nr_elems = len(elements)
    # Total number of field evaluations regquired
    if job_name is not None:
        prog_bar = ProgressBar(nr_elems * len(eval_coordinates), f'{job_name}:', interval=1000)
    Br = np.zeros((len(eval_coordinates), nr_elems))
    Bz = np.zeros((len(eval_coordinates), nr_elems))
    for i in range(len(eval_coordinates)):
        # For each coordinate, sum up the contributions of all magnetic elements
        for j in range(nr_elems):
            # Distance between eval coordinate and the averaged coil position
            coil_distance = (((elements[j][1 ] +elements[j][0] ) /2.0 -eval_coordinates[i][0] )**2
                             + ((elements[j][2 ] +elements[j][3] ) /2.0 -eval_coordinates[i][1] )**2 )**0.5

            if coil_distance <= distance_limit:
                # Calculate effect of coil element
                Rin, Rout, Zup, Zbot, I = elements[j][0], elements[j][1], elements[j][2], elements[j][3], elements[j][4]
                Brt, Bzt = hiper.calc_single_field(eval_coordinates[i][0], eval_coordinates[i][1], Rin, Rout, Zup, Zbot, I, 5)
                Br[i ,j] += Brt
                Bz[i ,j] += Bzt
            # Print status bar to console
            if job_name is not None:
                prog_bar.update(n)
            n += 1
    return Br, Bz