
class DBC:
    def __init__(self,file):
        self.Messages = {}
        self.load_dbc(file)

    class Signal:
        def __init__(self):
            self.name = ""
            self.msb = -1
            self.len = -1
            self.endianness = ""
            self.type = ""
            self.mul = -1
            self.offset = 0
            self.unit = ""
            self.max = -1
            self.min = -1
            self.receivers = []
            self.values = []
            self.enum = None

        def to_float(self,len):
            if len == "1":    # float
                if self.len != 32:
                    pass
                self.type = "f"
                    #raise Exception("ID {}: Float has to be length 32".format())
            elif len == "2":  # double
                if self.len != 64:
                    pass
                elif self.msb != 0:
                    pass
                self.type = "d"
            self.data = 0.0


#    Mgr_CAN.add_CAN_0_cb(update, self.Key, self.ID)

    class Message:
        def __init__(self):
            self.id = -1
            self.len = -1
            self.name = ""
            self.emitter = ""
            self.period = -1
            self.signals = {}

        def has_receiver(self, rec):
             for signal in self.signals:
                for receiver in signal.receivers:
                    if rec == receiver:
                        return True

			return False

    def load_dbc(self, path_dbc):
        import sys
        import ure

        with open(path_dbc, 'r') as f:
            text = f.read()
            regex = ure.compile("[\r\n]")
            lines =  regex.split(text)
            for idx, line in enumerate(lines):
                if line != None and len(line) > 4:
                    if line[0:4] == "BU_:":
                        self.name = line[5:-1]
                        del lines[idx]
                        break
                    else:
                        del lines[idx]
                else:
                    del lines[idx]

            for idx, line in enumerate(lines):
                if line != None and len(line) > 4:
                    l = line
                    for char in [":","(",",",")","[","]","|","@",";"]:
                        l = l.replace(char, " ")
                    l = l.split()
                    if l[0] == "BO_":
                        self.Messages[l[1]] = self.Message()
                        message = self.Messages[l[1]]
                        message.id = int(l[1])
                        message.name = l[2][:-1]
                        message.len = int(l[3])
                        message.emitter = l[4]
                    elif l[0] == "SG_":
                        message.signals[l[1]] = self.Signal()
                        signal = message.signals[l[1]]
                        if "m" in l[2].lower():
                            m = 1
                            signal.mux = l[2]
                        else:
                            m = 0

                        signal = message.signals[l[1]]
                        signal.name = l[1]
                        signal.msb = int(l[2 + m])
                        signal.len = int(l[3 + m])
                        signal.endianness = "big" if "0" in l[4 + m] else "little"
                        print("name: {} endianness: {}".format(signal.name, signal.endianness))
                        signal.type = "s" if "-" in l[4 + m] else "u"
                        signal.mul = float(l[5 + m]) if "." in l[5 + m] else int(l[5 + m])
                        signal.offset = float(l[6 + m]) if "." in l[6 + m] else int(l[6 + m])
                        signal.min = int(l[7 + m])
                        signal.max = int(l[8 + m])
                        if signal.min == 0 and signal.max == 0:
                            signal.min_max = False
                        else:
                            signal.min_max = True
                        signal.unit = l[9][1:-1]

                        for rec in l[10:]:
                            signal.receivers.append(rec)

                        # Stolen from henery's code.
                        # if signal.endianness:
                        #     # No idea why this adjustment is required for Motorola
                        #     for i in range(signal.len - 1):
                        #         if not signal.msb & 7:
                        #             signal.msb += 16
                        #         signal.msb -= 1



                    elif l[0] == "BA_":
                        pass

                    elif l[0] == "VAL_":
                        signal = self.Messages[l[1]].signals[l[2]]
                        signal.type = "e"
                        signal.enum = {}
                        for i in range(3,len(l)-1,2):
                            signal.enum[l[i]] = l[i+1].strip("\"")

                    elif l[0] == "SIG_VALTYPE_":
                        self.Messages[l[1]].signals[l[2]].to_float(l[3])

                    # some kind of enum thing
                    # & a Mux handler
