import numpy as np
from pathlib import Path
from src.tools.getGeo import getGeo
from src.tools.toECEF import toECEF
from src.tools.cg_convex_hull import cg_convex_hull
from src.tools.own_bb import own_bb_Geo
import hashlib

class timeGeoObject:
    def __init__(self, hash: np.int64,fname : Path = None, record: dict = None):
        self.hash = hash
        if fname is not None and record is None:
            self.id=fname.stem
            self.fname= fname
            self.image = fname.with_suffix(".png")
            self.data=self.read_file(fname)
            self.perc=self.data[:,0]
            self.time=self.data[:,1]
            self.lat=self.data[:,2]
            self.lon=self.data[:,3]
            self.altitude=self.data[:,4]
            self.yaw=-self.data[:,5]
            self.speed = self.data[:, 6]
            self.angv_x = self.data[:, 7]
            self.angv_y = self.data[:, 8]
            self.angv_z = self.data[:, 9]
            self.range=float(fname.stem.split("_")[-2])/2.0
 #           [self.convex_hull,self.mean_z]=self.get_convex_hull()
            self.rtree_bb=own_bb_Geo(self.get_externals())
        elif record is not None and fname is None:
            self.id= record['id']
            self.fname= Path(record['fullpath'])
            self.image = Path(record['image'])
            self.data = record['data']
            self.perc= record['perc']
            self.time = record['time']
            self.lat = record['lat']
            self.lon = record['lon']
            self.altitude = record['altitude']
            self.yaw = record['yaw']
            self.speed = record['speed']
            self.angv_x = record['angv_x']
            self.angv_y = record['angv_y']
            self.angv_z = record['angv_z']
            self.range= record['range']
#            self.convex_hull= record['convex_hull']
#            self.mean_z= record['mean_z']
            self.rtree_bb= record['bb']
        else:
            raise Exception("Either fname or record must be given")


    def read_file(self, fname: Path) -> np.array:
        data=np.genfromtxt(fname,delimiter=' ')
        return data

#    def get_convex_hull(self):
#        '''
#        in ECEF
#        :return: M  converx hull
#                 altitude: mean altitude of the convex hull
#         '''
#         X=[]
#         Y=[]
#         X0=[]
#         Y0=[]
#         X1=[]
#         Y1=[]
#         M=[]
#         altitudes=[]
#         for idx in range(len(self.time)): # für jede Zeile
#             [la0,lo0,d0]=getGeo(0.0, 0.0, self.range, self.lat[idx], self.lon[idx], 0*self.altitude[idx], self.yaw[idx], 0.0) # Anfang geodetic
#             [la1,lo1,d1]=getGeo(1.0, 0.0, self.range, self.lat[idx], self.lon[idx], 0*self.altitude[idx], self.yaw[idx], 0.0) # Ende geodetic
#
#             [x,y,z]=toECEF(self.lat[idx], self.lon[idx], 0*self.altitude[idx]) # Mitte ECRF
#             [x0,y0,z0]=toECEF(la0,lo0,d0) # Anfang ECEF
#             [x1,y1,z1]=toECEF(la1,lo1,d1) # Ende ECEF
#
#             X.append(x) # x of center
#             Y.append(y) # y of center
#             X0.append(x0)  # x of 0 side
#             Y0.append(y0)  # y of 0 side
#             X1.append(x1)  # x of 1 side
#             Y1.append(y1)  # y of 1 side
#             M.append((x1,y1))
#             M.append((x0,y0))
#             altitudes.append(z)
#             altitudes.append(z0)
#             altitudes.append(z1)
#
#             if len(M)>5:
#                 M=cg_convex_hull(M)
#
#
#             altitude=np.mean(altitudes)
#         return np.array(M),altitude
#
    def get_convex_hull_Geo(self):
        '''
            in WGS84
        :return:
        '''
        G0=[]
        G1=[]

        for idx in range(len(self.time)): # für jede Zeile
            [la0,lo0,d0]=getGeo(0.0, 0.0, self.range, self.lat[idx], self.lon[idx], 0*self.altitude[idx], self.yaw[idx], 0.0) # Anfang geodetic
            [la1,lo1,d1]=getGeo(1.0, 0.0, self.range, self.lat[idx], self.lon[idx], 0*self.altitude[idx], self.yaw[idx], 0.0) # Ende geodetic
            G0.append((la0,lo0))
            G1.append((la1,lo1))

        M=G0
        M.extend(G1[::-1])
        if len(M)>5:
            M=cg_convex_hull(M)
        return np.array(M)

    def get_externals(self,multi=False):
        G0 = []
        G1 = []
        G=[]
        for idx in range(len(self.time)):  # für jede Zeile
            [la0, lo0, d0] = getGeo(0.0, self.perc[idx], self.range, self.lat[idx], self.lon[idx], 0 * self.altitude[idx],
                                    self.yaw[idx], 0.0)  # Anfang geodetic
            [la1, lo1, d1] = getGeo(1.0, self.perc[idx], self.range, self.lat[idx], self.lon[idx], 0 * self.altitude[idx],
                                    self.yaw[idx], 0.0)  # Ende geodetic

            G.append((self.lat[idx],self.lon[idx]))
            G0.append([la0,lo0])
            G1.append([la1,lo1])

        if not multi:
            return  np.concatenate((G0,G1))
        else:
            return np.array(G0),np.array(G1),np.array(G)

