# 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.

import pygtk

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

from .point import Point
from . import parse
from . import colours
from . import model
from .model import Id, BlobModel, BlobDataSelect, special_state_chars
from . 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 range(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 range(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 range(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 range(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.items():
                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()
