# Copyright (c) 2013 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from . import parse
from . import colours
from .colours import unknownColour
from .point import Point
import re
from . import blobs
from time import time as wall_time
import os

id_parts = "TSPLFE"

all_ids = set(id_parts)
no_ids = set([])

class BlobDataSelect(object):
    """Represents which data is displayed for Ided object"""
    def __init__(self):
        # Copy all_ids
        self.ids = set(all_ids)

    def __and__(self, rhs):
        """And for filtering"""
        ret = BlobDataSelect()
        ret.ids = self.ids.intersection(rhs.ids)
        return ret

class BlobVisualData(object):
    """Super class for block data colouring"""
    def to_striped_block(self, select):
        """Return an array of colours to use for a striped block"""
        return unknownColour

    def get_inst(self):
        """Get an instruction Id (if any) from this data"""
        return None

    def get_line(self):
        """Get a line Id (if any) from this data"""
        return None

    def __repr__(self):
        return self.__class__.__name__ + '().from_string(' + \
            self.__str__() + ')'

    def __str__(self):
        return ''

class Id(BlobVisualData):
    """A line or instruction id"""
    def __init__(self):
        self.isFault = False
        self.threadId = 0
        self.streamSeqNum = 0
        self.predictionSeqNum = 0
        self.lineSeqNum = 0
        self.fetchSeqNum = 0
        self.execSeqNum = 0

    def as_list(self):
        return [self.threadId, self.streamSeqNum, self.predictionSeqNum,
            self.lineSeqNum, self.fetchSeqNum, self.execSeqNum]

    def __cmp__(self, right):
        return cmp(self.as_list(), right.as_list())

    def from_string(self, string):
        m = re.match('^(F;)?(\d+)/(\d+)\.(\d+)/(\d+)(/(\d+)(\.(\d+))?)?',
            string)

        def seqnum_from_string(string):
            if string is None:
                return 0
            else:
                return int(string)

        if m is None:
            print('Invalid Id string', string)
        else:
            elems = m.groups()

            if elems[0] is not None:
                self.isFault = True
            else:
                self.isFault = False

            self.threadId = seqnum_from_string(elems[1])
            self.streamSeqNum = seqnum_from_string(elems[2])
            self.predictionSeqNum = seqnum_from_string(elems[3])
            self.lineSeqNum = seqnum_from_string(elems[4])
            self.fetchSeqNum = seqnum_from_string(elems[6])
            self.execSeqNum = seqnum_from_string(elems[8])
        return self

    def get_inst(self):
        if self.fetchSeqNum != 0:
            return self
        else:
            return None

    def get_line(self):
        return self

    def __str__(self):
        """Returns the usual id T/S.P/L/F.E string"""
        return (
            str(self.threadId) + '/' +
            str(self.streamSeqNum) + '.' +
            str(self.predictionSeqNum) + '/' +
            str(self.lineSeqNum) + '/' +
            str(self.fetchSeqNum) + '.' +
            str(self.execSeqNum))

    def to_striped_block(self, select):
        ret = []

        if self.isFault:
            ret.append(colours.faultColour)

        if 'T' in select.ids:
            ret.append(colours.number_to_colour(self.threadId))
        if 'S' in select.ids:
            ret.append(colours.number_to_colour(self.streamSeqNum))
        if 'P' in select.ids:
            ret.append(colours.number_to_colour(self.predictionSeqNum))
        if 'L' in select.ids:
            ret.append(colours.number_to_colour(self.lineSeqNum))
        if self.fetchSeqNum != 0 and 'F' in select.ids:
            ret.append(colours.number_to_colour(self.fetchSeqNum))
        if self.execSeqNum != 0 and 'E' in select.ids:
            ret.append(colours.number_to_colour(self.execSeqNum))

        if len(ret) == 0:
            ret = [colours.unknownColour]

        if self.isFault:
            ret.append(colours.faultColour)

        return ret

class Branch(BlobVisualData):
    """Branch data new stream and prediction sequence numbers, a branch
    reason and a new PC"""
    def __init__(self):
        self.newStreamSeqNum = 0
        self.newPredictionSeqNum = 0
        self.newPC = 0
        self.reason = "NoBranch"
        self.id = Id()

    def from_string(self, string):
        m = re.match('^(\w+);(\d+)\.(\d+);([0-9a-fA-Fx]+);(.*)$', string)

        if m is not None:
            self.reason, newStreamSeqNum, newPredictionSeqNum, \
                newPC, id = m.groups()

            self.newStreamSeqNum = int(newStreamSeqNum)
            self.newPredictionSeqNum = int(newPredictionSeqNum)
            self.newPC = int(newPC, 0)
            self.id = special_view_decoder(Id)(id)
            # self.branch = special_view_decoder(Branch)(branch)
        else:
            print("Bad Branch data:", string)
        return self

    def to_striped_block(self, select):
        return [colours.number_to_colour(self.newStreamSeqNum),
            colours.number_to_colour(self.newPredictionSeqNum),
            colours.number_to_colour(self.newPC)]

class Counts(BlobVisualData):
    """Treat the input data as just a /-separated list of count values (or
    just a single value)"""
    def __init__(self):
        self.counts = []

    def from_string(self, string):
        self.counts = list(map(int, re.split('/', string)))
        return self

    def to_striped_block(self, select):
        return list(map(colours.number_to_colour, self.counts))

class Colour(BlobVisualData):
    """A fixed colour block, used for special colour decoding"""
    def __init__(self, colour):
        self.colour = colour

    def to_striped_block(self, select):
        return [self.colour]

class DcacheAccess(BlobVisualData):
    """Data cache accesses [RW];id"""
    def __init__(self):
        self.direc = 'R'
        self.id = Id()

    def from_string(self, string):
        self.direc, id = re.match('^([RW]);([^;]*);.*$', string).groups()
        self.id.from_string(id)
        return self

    def get_inst(self):
        return self.id

    def to_striped_block(self, select):
        if self.direc == 'R':
            direc_colour = colours.readColour
        elif self.direc == 'R':
            direc_colour = colours.writeColour
        else:
            direc_colour = colours.errorColour
        return [direc_colour] + self.id.to_striped_block(select)

class ColourPattern(object):
    """Super class for decoders that make 2D grids rather than just single
    striped blocks"""
    def elems(self):
        return []

    def to_striped_block(self, select):
        return [[[colours.errorColour]]]

def special_view_decoder(class_):
    """Generate a decode function that checks for special character
    arguments first (and generates a fixed colour) before building a
    BlobVisualData of the given class"""
    def decode(symbol):
        if symbol in special_state_colours:
            return Colour(special_state_colours[symbol])
        else:
            return class_().from_string(symbol)
    return decode

class TwoDColours(ColourPattern):
    """A 2D grid pattern decoder"""
    def __init__(self, blockss):
        self.blockss = blockss

    @classmethod
    def decoder(class_, elemClass, dataName):
        """Factory for making decoders for particular block types"""
        def decode(pairs):
            if dataName not in pairs:
                print('TwoDColours: no event data called:', \
                    dataName, 'in:', pairs)
                return class_([[Colour(colours.errorColour)]])
            else:
                parsed = parse.list_parser(pairs[dataName])
                return class_(parse.map2(special_view_decoder(elemClass), \
                    parsed))
        return decode

    @classmethod
    def indexed_decoder(class_, elemClass, dataName, picPairs):
        """Factory for making decoders for particular block types but
        where the list elements are pairs of (index, data) and
        strip and stripelems counts are picked up from the pair
        data on the decoder's picture file.  This gives a 2D layout
        of the values with index 0 at strip=0, elem=0 and index 1
        at strip=0, elem=1"""
        def decode(pairs):
            if dataName not in pairs:
                print('TwoDColours: no event data called:', \
                    dataName, 'in:', pairs)
                return class_([[Colour(colours.errorColour)]])
            else:
                strips = int(picPairs['strips'])
                strip_elems = int(picPairs['stripelems'])

                raw_iv_pairs = pairs[dataName]

                parsed = parse.parse_indexed_list(raw_iv_pairs)

                array = [[Colour(colours.emptySlotColour)
                    for i in range(0, strip_elems)]
                    for j in range(0, strips)]

                for index, value in parsed:
                    try:
                        array[index % strips][index / strips] = \
                            special_view_decoder(elemClass)(value)
                    except:
                        print("Element out of range strips: %d," \
                            " stripelems %d, index: %d" % (strips,
                            strip_elems, index))

                # return class_(array)
                return class_(array)
        return decode

    def elems(self):
        """Get a flat list of all elements"""
        ret = []
        for blocks in self.blockss:
            ret += blocks
        return ret

    def to_striped_block(self, select):
        return parse.map2(lambda d: d.to_striped_block(select), self.blockss)

class FrameColours(ColourPattern):
    """Decode to a 2D grid which has a single occupied row from the event
    data and some blank rows forming a frame with the occupied row as a
    'title' coloured stripe"""
    def __init__(self, block, numBlankSlots):
        self.numBlankSlots = numBlankSlots
        self.block = block

    @classmethod
    def decoder(class_, elemClass, numBlankSlots, dataName):
        """Factory for element type"""
        def decode(pairs):
            if dataName not in pairs:
                print('FrameColours: no event data called:', dataName, \
                    'in:', pairs)
                return class_([Colour(colours.errorColour)])
            else:
                parsed = parse.list_parser(pairs[dataName])
                return class_(special_view_decoder(elemClass)
                    (parsed[0][0]), numBlankSlots)
        return decode

    def elems(self):
        return [self.block]

    def to_striped_block(self, select):
        return ([[self.block.to_striped_block(select)]] +
            (self.numBlankSlots * [[[colours.backgroundColour]]]))

special_state_colours = {
    'U': colours.unknownColour,
    'B': colours.blockedColour,
    '-': colours.bubbleColour,
    '': colours.emptySlotColour,
    'E': colours.emptySlotColour,
    'R': colours.reservedSlotColour,
    'X': colours.errorColour,
    'F': colours.faultColour,
    'r': colours.readColour,
    'w': colours.writeColour
    }

special_state_names = {
    'U': '(U)nknown',
    'B': '(B)locked',
    '-': '(-)Bubble',
    '': '()Empty',
    'E': '(E)mpty',
    'R': '(R)eserved',
    'X': '(X)Error',
    'F': '(F)ault',
    'r': '(r)ead',
    'w': '(w)rite'
    }

special_state_chars = list(special_state_colours.keys())

# The complete set of available block data types
decoder_element_classes = {
    'insts': Id,
    'lines': Id,
    'branch': Branch,
    'dcache': DcacheAccess,
    'counts': Counts
    }

indexed_decoder_element_classes = {
    'indexedCounts' : Counts
    }

def find_colour_decoder(stripSpace, decoderName, dataName, picPairs):
    """Make a colour decoder from some picture file blob attributes"""
    if decoderName == 'frame':
        return FrameColours.decoder(Counts, stripSpace, dataName)
    elif decoderName in decoder_element_classes:
        return TwoDColours.decoder(decoder_element_classes[decoderName],
            dataName)
    elif decoderName in indexed_decoder_element_classes:
        return TwoDColours.indexed_decoder(
            indexed_decoder_element_classes[decoderName], dataName, picPairs)
    else:
        return None

class IdedObj(object):
    """An object identified by an Id carrying paired data.
    The super class for Inst and Line"""

    def __init__(self, id, pairs={}):
        self.id = id
        self.pairs = pairs

    def __cmp__(self, right):
        return cmp(self.id, right.id)

    def table_line(self):
        """Represent the object as a list of table row data"""
        return []

    # FIXME, add a table column titles?

    def __repr__(self):
        return ' '.join(self.table_line())

class Inst(IdedObj):
    """A non-fault instruction"""
    def __init__(self, id, disassembly, addr, pairs={}):
        super(Inst,self).__init__(id, pairs)
        if 'nextAddr' in pairs:
            self.nextAddr = int(pairs['nextAddr'], 0)
            del pairs['nextAddr']
        else:
            self.nextAddr = None
        self.disassembly = disassembly
        self.addr = addr

    def table_line(self):
        if self.nextAddr is not None:
            addrStr = '0x%x->0x%x' % (self.addr, self.nextAddr)
        else:
            addrStr = '0x%x' % self.addr
        ret = [addrStr, self.disassembly]
        for name, value in self.pairs.items():
            ret.append("%s=%s" % (name, str(value)))
        return ret

class InstFault(IdedObj):
    """A fault instruction"""
    def __init__(self, id, fault, addr, pairs={}):
        super(InstFault,self).__init__(id, pairs)
        self.fault = fault
        self.addr = addr

    def table_line(self):
        ret = ["0x%x" % self.addr, self.fault]
        for name, value in self.pairs:
            ret.append("%s=%s", name, str(value))
        return ret

class Line(IdedObj):
    """A fetched line"""
    def __init__(self, id, vaddr, paddr, size, pairs={}):
        super(Line,self).__init__(id, pairs)
        self.vaddr = vaddr
        self.paddr = paddr
        self.size = size

    def table_line(self):
        ret = ["0x%x/0x%x" % (self.vaddr, self.paddr), "%d" % self.size]
        for name, value in self.pairs:
            ret.append("%s=%s", name, str(value))
        return ret

class LineFault(IdedObj):
    """A faulting line"""
    def __init__(self, id, fault, vaddr, pairs={}):
        super(LineFault,self).__init__(id, pairs)
        self.vaddr = vaddr
        self.fault = fault

    def table_line(self):
        ret = ["0x%x" % self.vaddr, self.fault]
        for name, value in self.pairs:
            ret.append("%s=%s", name, str(value))
        return ret

class BlobEvent(object):
    """Time event for a single blob"""
    def __init__(self, unit, time, pairs = {}):
        # blob's unit name
        self.unit = unit
        self.time = time
        # dict of picChar (blob name) to visual data
        self.visuals = {}
        # Miscellaneous unparsed MinorTrace line data
        self.pairs = pairs
        # Non-MinorTrace debug printout for this unit at this time
        self.comments = []

    def find_ided_objects(self, model, picChar, includeInstLines):
        """Find instructions/lines mentioned in the blob's event
        data"""
        ret = []
        if picChar in self.visuals:
            blocks = self.visuals[picChar].elems()
            def find_inst(data):
                instId = data.get_inst()
                lineId = data.get_line()
                if instId is not None:
                    inst = model.find_inst(instId)
                    line = model.find_line(instId)
                    if inst is not None:
                        ret.append(inst)
                    if includeInstLines and line is not None:
                        ret.append(line)
                elif lineId is not None:
                    line = model.find_line(lineId)
                    if line is not None:
                        ret.append(line)
            list(map(find_inst, blocks))
        return sorted(ret)

class BlobModel(object):
    """Model bringing together blob definitions and parsed events"""
    def __init__(self, unitNamePrefix=''):
        self.blobs = []
        self.unitNameToBlobs = {}
        self.unitEvents = {}
        self.clear_events()
        self.picSize = Point(20,10)
        self.lastTime = 0
        self.unitNamePrefix = unitNamePrefix

    def clear_events(self):
        """Drop all events and times"""
        self.lastTime = 0
        self.times = []
        self.insts = {}
        self.lines = {}
        self.numEvents = 0

        for unit, events in self.unitEvents.items():
            self.unitEvents[unit] = []

    def add_blob(self, blob):
        """Add a parsed blob to the model"""
        self.blobs.append(blob)
        if blob.unit not in self.unitNameToBlobs:
            self.unitNameToBlobs[blob.unit] = []

        self.unitNameToBlobs[blob.unit].append(blob)

    def add_inst(self, inst):
        """Add a MinorInst instruction definition to the model"""
        # Is this a non micro-op instruction.  Microops (usually) get their
        #   fetchSeqNum == 0 varient stored first
        macroop_key = (inst.id.fetchSeqNum, 0)
        full_key = (inst.id.fetchSeqNum, inst.id.execSeqNum)

        if inst.id.execSeqNum != 0 and macroop_key not in self.insts:
            self.insts[macroop_key] = inst

        self.insts[full_key] = inst

    def find_inst(self, id):
        """Find an instruction either as a microop or macroop"""
        macroop_key = (id.fetchSeqNum, 0)
        full_key = (id.fetchSeqNum, id.execSeqNum)

        if full_key in self.insts:
            return self.insts[full_key]
        elif macroop_key in self.insts:
            return self.insts[macroop_key]
        else:
            return None

    def add_line(self, line):
        """Add a MinorLine line to the model"""
        self.lines[line.id.lineSeqNum] = line

    def add_unit_event(self, event):
        """Add a single event to the model.  This must be an event at a
        time >= the current maximum time"""
        if event.unit in self.unitEvents:
            events = self.unitEvents[event.unit]
            if len(events) > 0 and events[len(events)-1].time > event.time:
                print("Bad event ordering")
            events.append(event)
        self.numEvents += 1
        self.lastTime = max(self.lastTime, event.time)

    def extract_times(self):
        """Extract a list of all the times from the seen events.  Call after
        reading events to give a safe index list to use for time indices"""
        times = {}
        for unitEvents in self.unitEvents.values():
            for event in unitEvents:
                times[event.time] = 1
        self.times = list(times.keys())
        self.times.sort()

    def find_line(self, id):
        """Find a line by id"""
        key = id.lineSeqNum
        return self.lines.get(key, None)

    def find_event_bisection(self, unit, time, events,
        lower_index, upper_index):
        """Find an event by binary search on time indices"""
        while lower_index <= upper_index:
            pivot = (upper_index + lower_index) / 2
            pivotEvent = events[pivot]
            event_equal = (pivotEvent.time == time or
                (pivotEvent.time < time and
                    (pivot == len(events) - 1 or
                        events[pivot + 1].time > time)))

            if event_equal:
                return pivotEvent
            elif time > pivotEvent.time:
                if pivot == upper_index:
                    return None
                else:
                    lower_index = pivot + 1
            elif time < pivotEvent.time:
                if pivot == lower_index:
                    return None
                else:
                    upper_index = pivot - 1
            else:
                return None
        return None

    def find_unit_event_by_time(self, unit, time):
        """Find the last event for the given unit at time <= time"""
        if unit in self.unitEvents:
            events = self.unitEvents[unit]
            ret = self.find_event_bisection(unit, time, events,
                0, len(events)-1)

            return ret
        else:
            return None

    def find_time_index(self, time):
        """Find a time index close to the given time (where
        times[return] <= time and times[return+1] > time"""
        ret = 0
        lastIndex = len(self.times) - 1
        while ret < lastIndex and self.times[ret + 1] <= time:
            ret += 1
        return ret

    def add_minor_inst(self, rest):
        """Parse and add a MinorInst line to the model"""
        pairs = parse.parse_pairs(rest)
        other_pairs = dict(pairs)

        id = Id().from_string(pairs['id'])
        del other_pairs['id']

        addr = int(pairs['addr'], 0)
        del other_pairs['addr']

        if 'inst' in other_pairs:
            del other_pairs['inst']

            # Collapse unnecessary spaces in disassembly
            disassembly = re.sub('  *', ' ',
                re.sub('^ *', '', pairs['inst']))

            inst = Inst(id, disassembly, addr, other_pairs)
            self.add_inst(inst)
        elif 'fault' in other_pairs:
            del other_pairs['fault']

            inst = InstFault(id, pairs['fault'], addr, other_pairs)

            self.add_inst(inst)

    def add_minor_line(self, rest):
        """Parse and add a MinorLine line to the model"""
        pairs = parse.parse_pairs(rest)
        other_pairs = dict(pairs)

        id = Id().from_string(pairs['id'])
        del other_pairs['id']

        vaddr = int(pairs['vaddr'], 0)
        del other_pairs['vaddr']

        if 'paddr' in other_pairs:
            del other_pairs['paddr']
            del other_pairs['size']
            paddr = int(pairs['paddr'], 0)
            size = int(pairs['size'], 0)

            self.add_line(Line(id,
                vaddr, paddr, size, other_pairs))
        elif 'fault' in other_pairs:
            del other_pairs['fault']

            self.add_line(LineFault(id, pairs['fault'], vaddr, other_pairs))

    def load_events(self, file, startTime=0, endTime=None):
        """Load an event file and add everything to this model"""
        def update_comments(comments, time):
            # Add a list of comments to an existing event, if there is one at
            #   the given time, or create a new, correctly-timed, event from
            #   the last event and attach the comments to that
            for commentUnit, commentRest in comments:
                event = self.find_unit_event_by_time(commentUnit, time)
                # Find an event to which this comment can be attached
                if event is None:
                    # No older event, make a new empty one
                    event = BlobEvent(commentUnit, time, {})
                    self.add_unit_event(event)
                elif event.time != time:
                    # Copy the old event and make a new one with the right
                    #   time and comment
                    newEvent = BlobEvent(commentUnit, time, event.pairs)
                    newEvent.visuals = dict(event.visuals)
                    event = newEvent
                    self.add_unit_event(event)
                event.comments.append(commentRest)

        self.clear_events()

        # A negative time will *always* be different from an event time
        time = -1
        time_events = {}
        last_time_lines = {}
        minor_trace_line_count = 0
        comments = []

        default_colour = [[colours.unknownColour]]
        next_progress_print_event_count = 1000

        if not os.access(file, os.R_OK):
            print('Can\'t open file', file)
            exit(1)
        else:
            print('Opening file', file)

        f = open(file)

        start_wall_time = wall_time()

        # Skip leading events
        still_skipping = True
        l = f.readline()
        while l and still_skipping:
            match = re.match('^\s*(\d+):', l)
            if match is not None:
                event_time = match.groups()
                if int(event_time[0]) >= startTime:
                    still_skipping = False
                else:
                    l = f.readline()
            else:
                l = f.readline()

        match_line_re = re.compile(
            '^\s*(\d+):\s*([\w\.]+):\s*(Minor\w+:)?\s*(.*)$')

        # Parse each line of the events file, accumulating comments to be
        #   attached to MinorTrace events when the time changes
        reached_end_time = False
        while not reached_end_time and l:
            match = match_line_re.match(l)
            if match is not None:
                event_time, unit, line_type, rest = match.groups()
                event_time = int(event_time)

                unit = re.sub('^' + self.unitNamePrefix + '\.?(.*)$',
                    '\\1', unit)

                # When the time changes, resolve comments
                if event_time != time:
                    if self.numEvents > next_progress_print_event_count:
                        print(('Parsed to time: %d' % event_time))
                        next_progress_print_event_count = (
                            self.numEvents + 1000)
                    update_comments(comments, time)
                    comments = []
                    time = event_time

                if line_type is None:
                    # Treat this line as just a 'comment'
                    comments.append((unit, rest))
                elif line_type == 'MinorTrace:':
                    minor_trace_line_count += 1

                    # Only insert this event if it's not the same as
                    #   the last event we saw for this unit
                    if last_time_lines.get(unit, None) != rest:
                        event = BlobEvent(unit, event_time, {})
                        pairs = parse.parse_pairs(rest)
                        event.pairs = pairs

                        # Try to decode the colour data for this event
                        blobs = self.unitNameToBlobs.get(unit, [])
                        for blob in blobs:
                            if blob.visualDecoder is not None:
                                event.visuals[blob.picChar] = (
                                    blob.visualDecoder(pairs))

                        self.add_unit_event(event)
                        last_time_lines[unit] = rest
                elif line_type == 'MinorInst:':
                    self.add_minor_inst(rest)
                elif line_type == 'MinorLine:':
                    self.add_minor_line(rest)

            if endTime is not None and time > endTime:
                reached_end_time = True

            l = f.readline()

        update_comments(comments, time)
        self.extract_times()
        f.close()

        end_wall_time = wall_time()

        print('Total events:', minor_trace_line_count, 'unique events:', \
            self.numEvents)
        print('Time to parse:', end_wall_time - start_wall_time)

    def add_blob_picture(self, offset, pic, nameDict):
        """Add a parsed ASCII-art pipeline markup to the model"""
        pic_width = 0
        for line in pic:
            pic_width = max(pic_width, len(line))
        pic_height = len(pic)

        # Number of horizontal characters per 'pixel'.  Should be 2
        charsPerPixel = 2

        # Clean up pic_width to a multiple of charsPerPixel
        pic_width = (pic_width + charsPerPixel - 1) // 2

        self.picSize = Point(pic_width, pic_height)

        def pic_at(point):
            """Return the char pair at the given point.
            Returns None for characters off the picture"""
            x, y = point.to_pair()
            x *= 2
            if y >= len(pic) or x >= len(pic[y]):
                return None
            else:
                return pic[y][x:x + charsPerPixel]

        def clear_pic_at(point):
            """Clear the chars at point so we don't trip over them again"""
            line = pic[point.y]
            x = point.x * charsPerPixel
            pic[point.y] = line[0:x] + (' ' * charsPerPixel) + \
                line[x + charsPerPixel:]

        def skip_same_char(start, increment):
            """Skip characters which match pic_at(start)"""
            char = pic_at(start)
            hunt = start
            while pic_at(hunt) == char:
                hunt += increment
            return hunt

        def find_size(start):
            """Find the size of a rectangle with top left hand corner at
            start consisting of (at least) a -. shaped corner describing
            the top right corner of a rectangle of the same char"""
            char = pic_at(start)
            hunt_x = skip_same_char(start, Point(1,0))
            hunt_y = skip_same_char(start, Point(0,1))
            off_bottom_right = (hunt_x * Point(1,0)) + (hunt_y * Point(0,1))
            return off_bottom_right - start

        def point_return(point):
            """Carriage return, line feed"""
            return Point(0, point.y + 1)

        def find_arrow(start):
            """Find a simple 1-char wide arrow"""

            def body(endChar, contChar, direc):
                arrow_point = start
                arrow_point += Point(0, 1)
                clear_pic_at(start)
                while pic_at(arrow_point) == contChar:
                    clear_pic_at(arrow_point)
                    arrow_point += Point(0, 1)

                if pic_at(arrow_point) == endChar:
                    clear_pic_at(arrow_point)
                    self.add_blob(blobs.Arrow('_', start + offset,
                        direc = direc,
                        size = (Point(1, 1) + arrow_point - start)))
                else:
                    print('Bad arrow', start)

            char = pic_at(start)
            if char == '-\\':
                body('-/', ' :', 'right')
            elif char == '/-':
                body('\\-', ': ', 'left')

        blank_chars = ['  ', ' :', ': ']

        # Traverse the picture left to right, top to bottom to find blobs
        seen_dict = {}
        point = Point(0,0)
        while pic_at(point) is not None:
            while pic_at(point) is not None:
                char = pic_at(point)
                if char == '->':
                    self.add_blob(blobs.Arrow('_', point + offset,
                        direc = 'right'))
                elif char == '<-':
                    self.add_blob(blobs.Arrow('_', point + offset,
                        direc = 'left'))
                elif char == '-\\' or char == '/-':
                    find_arrow(point)
                elif char in blank_chars:
                    pass
                else:
                    if char not in seen_dict:
                        size = find_size(point)
                        topLeft = point + offset
                        if char not in nameDict:
                            # Unnamed blobs
                            self.add_blob(blobs.Block(char,
                                nameDict.get(char, '_'),
                                topLeft, size = size))
                        else:
                            # Named blobs, set visual info.
                            blob = nameDict[char]
                            blob.size = size
                            blob.topLeft = topLeft
                            self.add_blob(blob)
                    seen_dict[char] = True
                point = skip_same_char(point, Point(1,0))
            point = point_return(point)

    def load_picture(self, filename):
        """Load a picture file into the model"""
        def parse_blob_description(char, unit, macros, pairsList):
            # Parse the name value pairs in a blob-describing line
            def expand_macros(pairs, newPairs):
                # Recursively expand macros
                for name, value in newPairs:
                    if name in macros:
                        expand_macros(pairs, macros[name])
                    else:
                        pairs[name] = value
                return pairs

            pairs = expand_macros({}, pairsList)

            ret = None

            typ = pairs.get('type', 'block')
            colour = colours.name_to_colour(pairs.get('colour', 'black'))

            if typ == 'key':
                ret = blobs.Key(char, unit, Point(0,0), colour)
            elif typ == 'block':
                ret = blobs.Block(char, unit, Point(0,0), colour)
            else:
                print("Bad picture blog type:", typ)

            if 'hideId' in pairs:
                hide = pairs['hideId']
                ret.dataSelect.ids -= set(hide)

            if typ == 'block':
                ret.displayName = pairs.get('name', unit)
                ret.nameLoc = pairs.get('nameLoc', 'top')
                ret.shape = pairs.get('shape', 'box')
                ret.stripDir = pairs.get('stripDir', 'horiz')
                ret.stripOrd = pairs.get('stripOrd', 'LR')
                ret.blankStrips = int(pairs.get('blankStrips', '0'))
                ret.shorten = int(pairs.get('shorten', '0'))

                if 'decoder' in pairs:
                    decoderName = pairs['decoder']
                    dataElement = pairs.get('dataElement', decoderName)

                    decoder = find_colour_decoder(ret.blankStrips,
                        decoderName, dataElement, pairs)
                    if decoder is not None:
                        ret.visualDecoder = decoder
                    else:
                        print('Bad visualDecoder requested:', decoderName)

                if 'border' in pairs:
                    border = pairs['border']
                    if border == 'thin':
                        ret.border = 0.2
                    elif border == 'mid':
                        ret.border = 0.5
                    else:
                        ret.border = 1.0
            elif typ == 'key':
                ret.colours = pairs.get('colours', ret.colours)

            return ret

        def line_is_comment(line):
            """Returns true if a line starts with #, returns False
            for lines which are None"""
            return line is not None \
                and re.match('^\s*#', line) is not None

        def get_line(f):
            """Get a line from file f extending that line if it ends in
            '\' and dropping lines that start with '#'s"""
            ret = f.readline()

            # Discard comment lines
            while line_is_comment(ret):
                ret = f.readline()

            if ret is not None:
                extend_match = re.match('^(.*)\\\\$', ret)

                while extend_match is not None:
                    new_line = f.readline()

                    if new_line is not None and not line_is_comment(new_line):
                        line_wo_backslash, = extend_match.groups()
                        ret = line_wo_backslash + new_line
                        extend_match = re.match('^(.*)\\\\$', ret)
                    else:
                        extend_match = None

            return ret

        # Macros are recursively expanded into name=value pairs
        macros = {}

        if not os.access(filename, os.R_OK):
            print('Can\'t open file', filename)
            exit(1)
        else:
            print('Opening file', filename)

        f = open(filename)
        l = get_line(f)
        picture = []
        blob_char_dict = {}

        self.unitEvents = {}
        self.clear_events()

        # Actually parse the file
        in_picture = False
        while l:
            l = parse.remove_trailing_ws(l)
            l = re.sub('#.*', '', l)

            if re.match("^\s*$", l) is not None:
                pass
            elif l == '<<<':
                in_picture = True
            elif l == '>>>':
                in_picture = False
            elif in_picture:
                picture.append(re.sub('\s*$', '', l))
            else:
                line_match = re.match(
                    '^([a-zA-Z0-9][a-zA-Z0-9]):\s+([\w.]+)\s*(.*)', l)
                macro_match = re.match('macro\s+(\w+):(.*)', l)

                if macro_match is not None:
                    name, defn = macro_match.groups()
                    macros[name] = parse.parse_pairs_list(defn)
                elif line_match is not None:
                    char, unit, pairs = line_match.groups()
                    blob = parse_blob_description(char, unit, macros,
                        parse.parse_pairs_list(pairs))
                    blob_char_dict[char] = blob
                    # Setup the events structure
                    self.unitEvents[unit] = []
                else:
                    print('Problem with Blob line:', l)

            l = get_line(f)

        self.blobs = []
        self.add_blob_picture(Point(0,1), picture, blob_char_dict)
