import numpy as np

from Link import Link

class RubberBand:
    # class attributes
 
    def __init__(self, N, a=1., kBT=1., biased=False, force=0.):
        """
        RubberBand is a class that can simulate a rubber band with N
        incompressible links of length a.

        Parameters
        ----------
        N : int
            The number of links.
        a : float, optional
            The fixed length of the links. The default is 1..
        kBT : float, optional
            Temperature of the system (arb. units). The default is 1..
        force : float, optional
            Force applied to the RubberBand.
            The default is 0, which is an unbiased RubberBand.
        """

        self.N = N
        self.a = a
        self.kBT = kBT
        self.links = self.__sample_links(force=force)

    def w(self, f, l):
        beta = (self.kBT)**(-1)
        return np.exp(beta*f*l)
    
    @property
    def length(self):
        return self.a * np.sum([l.direction for l in self.links])
    
    def __sample_links(self, force):
        """
        Sample N Link objects with a random direction.
        """

        samples = np.random.random_sample((self.N,))
        directions = np.ones(samples.shape)
        
        p_negative = 1 - 0.5*(1 + np.tanh(force*self.a/self.kBT))

        directions[samples < p_negative] = -1.
        directions = directions.astype(int)
        return [Link(d) for d in directions]