# 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.
#
# Authors: Andrew Bardsley

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import cairo
import re

from point import Point
import parse
import colours
import model
from model import Id, BlobModel, BlobDataSelect, special_state_chars
import blobs

class BlobView(object):
    """The canvas view of the pipeline"""
    def __init__(self, model):
        # A unit blob will appear at size blobSize inside a space of
        #   size pitch.
        self.blobSize = Point(45.0, 45.0)
        self.pitch = Point(60.0, 60.0)
        self.origin = Point(50.0, 50.0)
        # Some common line definitions to cut down on arbitrary
        #   set_line_widths
        self.thickLineWidth = 10.0
        self.thinLineWidth = 4.0
        self.midLineWidth = 6.0
        # The scale from the units of pitch to device units (nominally
        #   pixels for 1.0 to 1.0
        self.masterScale = Point(1.0,1.0)
        self.model = model
        self.fillColour = colours.emptySlotColour
        self.timeIndex = 0
        self.time = 0
        self.positions = []
        self.controlbar = None
        # The sequence number selector state
        self.dataSelect = BlobDataSelect()
        # Offset of this view's time from self.time used for miniviews
        #   This is actually an offset of the index into the array of times
        #   seen in the event file)
        self.timeOffset = 0
        # Maximum view size for initial window mapping
        self.initialHeight = 600.0

        # Overlays are speech bubbles explaining blob data
        self.overlays = []

        self.da = gtk.DrawingArea()
        def draw(arg1, arg2):
            self.redraw()
        self.da.connect('expose_event', draw)

        # Handy offsets from the blob size
        self.blobIndent = (self.pitch - self.blobSize).scale(0.5)
        self.blobIndentFactor = self.blobIndent / self.pitch

    def add_control_bar(self, controlbar):
        """Add a BlobController to this view"""
        self.controlbar = controlbar

    def draw_to_png(self, filename):
        """Draw the view to a PNG file"""
        surface = cairo.ImageSurface(
            cairo.FORMAT_ARGB32,
            self.da.get_allocation().width,
            self.da.get_allocation().height)
        cr = gtk.gdk.CairoContext(cairo.Context(surface))
        self.draw_to_cr(cr)
        surface.write_to_png(filename)

    def draw_to_cr(self, cr):
        """Draw to a given CairoContext"""
        cr.set_source_color(colours.backgroundColour)
        cr.set_line_width(self.thickLineWidth)
        cr.paint()
        cr.save()
        cr.scale(*self.masterScale.to_pair())
        cr.translate(*self.origin.to_pair())

        positions = [] # {}

        # Draw each blob
        for blob in self.model.blobs:
            blob_event = self.model.find_unit_event_by_time(
                blob.unit, self.time)

            cr.save()
            pos = blob.render(cr, self, blob_event, self.dataSelect,
                self.time)
            cr.restore()
            if pos is not None:
                (centre, size) = pos
                positions.append((blob, centre, size))

        # Draw all the overlays over the top
        for overlay in self.overlays:
            overlay.show(cr)

        cr.restore()

        return positions

    def redraw(self):
        """Redraw the whole view"""
        buffer = cairo.ImageSurface(
            cairo.FORMAT_ARGB32,
            self.da.get_allocation().width,
            self.da.get_allocation().height)

        cr = gtk.gdk.CairoContext(cairo.Context(buffer))
        positions = self.draw_to_cr(cr)

        # Assume that blobs are in order for depth so we want to
        #   hit the frontmost blob first if we search by position
        positions.reverse()
        self.positions = positions

        # Paint the drawn buffer onto the DrawingArea
        dacr = self.da.window.cairo_create()
        dacr.set_source_surface(buffer, 0.0, 0.0)
        dacr.paint()

        buffer.finish()

    def set_time_index(self, time):
        """Set the time index for the view.  A time index is an index into
        the model's times array of seen event times"""
        self.timeIndex = time + self.timeOffset
        if len(self.model.times) != 0:
            if self.timeIndex >= len(self.model.times):
                self.time = self.model.times[len(self.model.times) - 1]
            else:
                self.time = self.model.times[self.timeIndex]
        else:
            self.time = 0

    def get_pic_size(self):
        """Return the size of ASCII-art picture of the pipeline scaled by
        the blob pitch"""
        return (self.origin + self.pitch *
            (self.model.picSize + Point(1.0,1.0)))

    def set_da_size(self):
        """Set the DrawingArea size after scaling"""
        self.da.set_size_request(10 , int(self.initialHeight))

class BlobController(object):
    """The controller bar for the viewer"""
    def __init__(self, model, view,
        defaultEventFile="", defaultPictureFile=""):
        self.model = model
        self.view = view
        self.playTimer = None
        self.filenameEntry = gtk.Entry()
        self.filenameEntry.set_text(defaultEventFile)
        self.pictureEntry = gtk.Entry()
        self.pictureEntry.set_text(defaultPictureFile)
        self.timeEntry = None
        self.defaultEventFile = defaultEventFile
        self.startTime = None
        self.endTime = None

        self.otherViews = []

        def make_bar(elems):
            box = gtk.HBox(homogeneous=False, spacing=2)
            box.set_border_width(2)
            for widget, signal, handler in elems:
                if signal is not None:
                    widget.connect(signal, handler)
                box.pack_start(widget, False, True, 0)
            return box

        self.timeEntry = gtk.Entry()

        t = gtk.ToggleButton('T')
        t.set_active(False)
        s = gtk.ToggleButton('S')
        s.set_active(True)
        p = gtk.ToggleButton('P')
        p.set_active(True)
        l = gtk.ToggleButton('L')
        l.set_active(True)
        f = gtk.ToggleButton('F')
        f.set_active(True)
        e = gtk.ToggleButton('E')
        e.set_active(True)

        # Should really generate this from above
        self.view.dataSelect.ids = set("SPLFE")

        self.bar = gtk.VBox()
        self.bar.set_homogeneous(False)

        row1 = make_bar([
            (gtk.Button('Start'), 'clicked', self.time_start),
            (gtk.Button('End'), 'clicked', self.time_end),
            (gtk.Button('Back'), 'clicked', self.time_back),
            (gtk.Button('Forward'), 'clicked', self.time_forward),
            (gtk.Button('Play'), 'clicked', self.time_play),
            (gtk.Button('Stop'), 'clicked', self.time_stop),
            (self.timeEntry, 'activate', self.time_set),
            (gtk.Label('Visible ids:'), None, None),
            (t, 'clicked', self.toggle_id('T')),
            (gtk.Label('/'), None, None),
            (s, 'clicked', self.toggle_id('S')),
            (gtk.Label('.'), None, None),
            (p, 'clicked', self.toggle_id('P')),
            (gtk.Label('/'), None, None),
            (l, 'clicked', self.toggle_id('L')),
            (gtk.Label('/'), None, None),
            (f, 'clicked', self.toggle_id('F')),
            (gtk.Label('.'), None, None),
            (e, 'clicked', self.toggle_id('E')),
            (self.filenameEntry, 'activate', self.load_events),
            (gtk.Button('Reload'), 'clicked', self.load_events)
            ])

        self.bar.pack_start(row1, False, True, 0)
        self.set_time_index(0)

    def toggle_id(self, id):
        """One of the sequence number selector buttons has been toggled"""
        def toggle(button):
            if button.get_active():
                self.view.dataSelect.ids.add(id)
            else:
                self.view.dataSelect.ids.discard(id)

            # Always leave one thing visible
            if len(self.view.dataSelect.ids) == 0:
                self.view.dataSelect.ids.add(id)
                button.set_active(True)
            self.view.redraw()
        return toggle

    def set_time_index(self, time):
        """Set the time index in the view"""
        self.view.set_time_index(time)

        for view in self.otherViews:
            view.set_time_index(time)
            view.redraw()

        self.timeEntry.set_text(str(self.view.time))

    def time_start(self, button):
        """Start pressed"""
        self.set_time_index(0)
        self.view.redraw()

    def time_end(self, button):
        """End pressed"""
        self.set_time_index(len(self.model.times) - 1)
        self.view.redraw()

    def time_forward(self, button):
        """Step forward pressed"""
        self.set_time_index(min(self.view.timeIndex + 1,
            len(self.model.times) - 1))
        self.view.redraw()
        gtk.gdk.flush()

    def time_back(self, button):
        """Step back pressed"""
        self.set_time_index(max(self.view.timeIndex - 1, 0))
        self.view.redraw()

    def time_set(self, entry):
        """Time dialogue changed.  Need to find a suitable time
        <= the entry's time"""
        newTime = self.model.find_time_index(int(entry.get_text()))
        self.set_time_index(newTime)
        self.view.redraw()

    def time_step(self):
        """Time step while playing"""
        if not self.playTimer \
            or self.view.timeIndex == len(self.model.times) - 1:
            self.time_stop(None)
            return False
        else:
            self.time_forward(None)
            return True

    def time_play(self, play):
        """Automatically advance time every 100 ms"""
        if not self.playTimer:
            self.playTimer = gobject.timeout_add(100, self.time_step)

    def time_stop(self, play):
        """Stop play pressed"""
        if self.playTimer:
            gobject.source_remove(self.playTimer)
            self.playTimer = None

    def load_events(self, button):
        """Reload events file"""
        self.model.load_events(self.filenameEntry.get_text(),
            startTime=self.startTime, endTime=self.endTime)
        self.set_time_index(min(len(self.model.times) - 1,
            self.view.timeIndex))
        self.view.redraw()

class Overlay(object):
    """An Overlay is a speech bubble explaining the data in a blob"""
    def __init__(self, model, view, point, blob):
        self.model = model
        self.view = view
        self.point = point
        self.blob = blob

    def find_event(self):
        """Find the event for a changing time and a fixed blob"""
        return self.model.find_unit_event_by_time(self.blob.unit,
            self.view.time)

    def show(self, cr):
        """Draw the overlay"""
        event = self.find_event()

        if event is None:
            return

        insts = event.find_ided_objects(self.model, self.blob.picChar,
            False)

        cr.set_line_width(self.view.thinLineWidth)
        cr.translate(*(Point(0.0,0.0) - self.view.origin).to_pair())
        cr.scale(*(Point(1.0,1.0) / self.view.masterScale).to_pair())

        # Get formatted data from the insts to format into a table
        lines = list(inst.table_line() for inst in insts)

        text_size = 10.0
        cr.set_font_size(text_size)

        def text_width(str):
            xb, yb, width, height, dx, dy = cr.text_extents(str)
            return width

        # Find the maximum number of columns and the widths of each column
        num_columns = 0
        for line in lines:
            num_columns = max(num_columns, len(line))

        widths = [0] * num_columns
        for line in lines:
            for i in xrange(0, len(line)):
                widths[i] = max(widths[i], text_width(line[i]))

        # Calculate the size of the speech bubble
        column_gap = 1 * text_size
        id_width = 6 * text_size
        total_width = sum(widths) + id_width + column_gap * (num_columns + 1)
        gap_step = Point(1.0, 0.0).scale(column_gap)

        text_point = self.point
        text_step = Point(0.0, text_size)

        size = Point(total_width, text_size * len(insts))

        # Draw the speech bubble
        blobs.speech_bubble(cr, self.point, size, text_size)
        cr.set_source_color(colours.backgroundColour)
        cr.fill_preserve()
        cr.set_source_color(colours.black)
        cr.stroke()

        text_point += Point(1.0,1.0).scale(2.0 * text_size)

        id_size = Point(id_width, text_size)

        # Draw the rows in the table
        for i in xrange(0, len(insts)):
            row_point = text_point
            inst = insts[i]
            line = lines[i]
            blobs.striped_box(cr, row_point + id_size.scale(0.5),
                id_size, inst.id.to_striped_block(self.view.dataSelect))
            cr.set_source_color(colours.black)

            row_point += Point(1.0, 0.0).scale(id_width)
            row_point += text_step
            # Draw the columns of each row
            for j in xrange(0, len(line)):
                row_point += gap_step
                cr.move_to(*row_point.to_pair())
                cr.show_text(line[j])
                row_point += Point(1.0, 0.0).scale(widths[j])

            text_point += text_step

class BlobWindow(object):
    """The top-level window and its mouse control"""
    def __init__(self, model, view, controller):
        self.model = model
        self.view = view
        self.controller = controller
        self.controlbar = None
        self.window = None
        self.miniViewCount = 0

    def add_control_bar(self, controlbar):
        self.controlbar = controlbar

    def show_window(self):
        self.window = gtk.Window()

        self.vbox = gtk.VBox()
        self.vbox.set_homogeneous(False)
        if self.controlbar:
            self.vbox.pack_start(self.controlbar, False, True, 0)
        self.vbox.add(self.view.da)

        if self.miniViewCount > 0:
            self.miniViews = []
            self.miniViewHBox = gtk.HBox(homogeneous=True, spacing=2)

            # Draw mini views
            for i in xrange(1, self.miniViewCount + 1):
                miniView = BlobView(self.model)
                miniView.set_time_index(0)
                miniView.masterScale = Point(0.1, 0.1)
                miniView.set_da_size()
                miniView.timeOffset = i + 1
                self.miniViews.append(miniView)
                self.miniViewHBox.pack_start(miniView.da, False, True, 0)

            self.controller.otherViews = self.miniViews
            self.vbox.add(self.miniViewHBox)

        self.window.add(self.vbox)

        def show_event(picChar, event):
            print '**** Comments for', event.unit, \
                'at time', self.view.time
            for name, value in event.pairs.iteritems():
                print name, '=', value
            for comment in event.comments:
                print comment
            if picChar in event.visuals:
                # blocks = event.visuals[picChar].elems()
                print '**** Colour data'
                objs = event.find_ided_objects(self.model, picChar, True)
                for obj in objs:
                    print ' '.join(obj.table_line())

        def clicked_da(da, b):
            point = Point(b.x, b.y)

            overlay = None
            for blob, centre, size in self.view.positions:
                if point.is_within_box((centre, size)):
                    event = self.model.find_unit_event_by_time(blob.unit,
                        self.view.time)
                    if event is not None:
                        if overlay is None:
                            overlay = Overlay(self.model, self.view, point,
                                blob)
                        show_event(blob.picChar, event)
            if overlay is not None:
                self.view.overlays = [overlay]
            else:
                self.view.overlays = []

            self.view.redraw()

        # Set initial size and event callbacks
        self.view.set_da_size()
        self.view.da.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.view.da.connect('button-press-event', clicked_da)
        self.window.connect('destroy', lambda(widget): gtk.main_quit())

        def resize(window, event):
            """Resize DrawingArea to match new window size"""
            size = Point(float(event.width), float(event.height))
            proportion = size / self.view.get_pic_size()
            # Preserve aspect ratio
            daScale = min(proportion.x, proportion.y)
            self.view.masterScale = Point(daScale, daScale)
            self.view.overlays = []

        self.view.da.connect('configure-event', resize)

        self.window.show_all()
