'''
Created on 24/04/2014

@author: MMPE
'''
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from io import open
from builtins import range
from future import standard_library
standard_library.install_aliases()

import numpy as np
class AtTimeFile(object):
    """Loads an at time file generated by HAWC2
    
    Functions are generated for each sensor in the file from the template:
    xxx(l=None, curved_length=False)
    
    E.g.
    twist(36, curved_length=True) # Twist 36m from the root along the (curved) center line
    twist(36) # Twist at radius 36m (Straight line radius, nondim. with bladetip_radius which must be specified in constructor)
    twist() # Twist at all aerodynamic calculation points
        
    
    >>> at = AtTimeFile("at.dat", 86.3655) # load file
    >>> at.attribute_names # Attribute names
    ['radius_s', 'twist', 'chord']
    >>> at[:3,1]) # first 3 twist rows
    [-14.5    -14.5002 -14.5007]
    >>> at.twist()[:3]) # Twist first 3 twist rows
    [-14.5    -14.5002 -14.5007]
    >>> at.twist(36, curved_length=True) # Twist at curved_length = 36 (interpolated)
    -5.172195702789108
    >>> at.twist(36) # Twist at radius = 36 (interpolated)
    -5.162084567646019
    """
    def __init__(self, filename, bladetip_radius=None):
        """
        Parameters
        ----------
        filename : string
            Filename
        bladetip_radius : int, float or None, optional
            Radius of blade tip. Used to convert from curved length to radius  
        """
        self.blade_radius = bladetip_radius
        with open(filename, encoding='utf-8') as fid:
            lines = fid.readlines()
        atttribute_name_line = [l.strip().startswith("# Radius_s") for l in lines].index(True)
        #self.attribute_names = lines[atttribute_name_line].lower().replace("#", "").split()
        self.attribute_names = [n.strip() for n in lines[atttribute_name_line].lower().split("#")[1:]]
        data = np.array([[float(l) for l in lines[i].split() ] for i in range(atttribute_name_line+1, len(lines))])
        self.data = data
        def func_factory(column):
            def values(l=None, curved_length=False):
                assert curved_length==True or curved_length==False, "Curved length must be boolean, but is %s"%curved_length
                if l is None:
                    return self.data[:, column]
                else:
                    if curved_length:
                        return np.interp(l, self.data[:, 0], self.data[:, column])
                    else:
                        assert self.blade_radius is not None, "bladetip_radius must be specified in __init__ when requesting value of radius (alternatively you can request for curved_length)"
                        return np.interp(l/self.blade_radius, self.data[:, 0]/self.data[-1, 0], self.data[:, column])
                
            return values
        for column, att_name in enumerate(self.attribute_names):
            setattr(self, att_name, func_factory(column))

    def radius_curved_ac(self, radius=None):
        """Radius (curved distance) of aerodynamic calculation point(s) 

        Parameters
        ----------
        radius : int or float, optional
            - if None (default): Radius of calculation points\n
            - if int or float: Radius of calculation point nearest radius

        Returns
        -------
        radius : float or array_like
            Radius of calculation points or radius of calculation point nearest radius
        """
        if radius is None:
            return self.radius_s()
        else:
            return self.radius_s()[np.argmin(np.abs(self.radius_s() - radius))]

    def value(self, radius, column):
        return np.interp(radius, self.data[:, 0], self.data[:, column])

    def __getitem__(self, subset):
        return self.data[subset]


if __name__ == "__main__":
    at = AtTimeFile(r"tests/test_files/at.dat", 86.3655) # load file
    at = AtTimeFile(r'U:\hama\HAWC2-AVATAR\res/avatar-7ntm-scaled-rad.dat')
    
    at.attribute_names # Attribute names
    at[:3,1] # first 3 twist rows
    print (len(at.attribute_names))
    print ("\n".join(at.attribute_names))
    print (at.data.shape)
    #at.twist()[:3] # Twist first 3 twist rows
    #print (at.twist(36, curved_length=True)) # Twist at curved_length = 36 (interpolated)
    #print (at.twist(36)) # Twist at 36 (interpolated)
    

