
import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.utils import get_color_from_hex as rgb

from kivy.graphics import Line, RenderContext, Color, Rectangle
from kivy.graphics.texture import Texture
from kivy_garden.graph import Graph

use_simple_lineplot = True
if use_simple_lineplot:
    from SimpleLinePlot import LinePlot
else:
    from kivy_garden.graph import LinePlot

import numpy
import pickle
import sys
import threading
from math import floor, ceil

import queue

kv = '''
#:import Graph kivy_garden.graph.Graph
<KivySourceCodeGraphBody>:

<KivySourceCodeGraph>:
    orientation: 'vertical'

    KivySourceCodeGraphBody:
        id: graph_plot
        background_color: (0.5, 0.5, 0.5, 1)
        xlabel: 'Time [frame]'
        ylabel: 'Azimuth [deg]'
        x_grid: True
        y_grid: True
        x_grid_label: True
        y_grid_label: True
        x_ticks_minor: 10
        x_ticks_major: 50
        ymin: -180
        ymax: 180
        y_ticks_minor: 30
        y_ticks_major: 90

'''
Builder.load_string(kv)

BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)


class KivySourceCodeGraphBody(Graph):
    def _get_ticks(self, major, minor, log, s_min, s_max):
        if log or s_min < 0:
            # seems y-axis or else:
            return super(KivySourceCodeGraphBody, self)._get_ticks(major, minor, log, s_min, s_max)
        else:
            # seems x-axis
            tick_dist = major / float(minor if minor else 1.0)
            n_ticks_max = floor(s_max / float(tick_dist))
            n_ticks_min = ceil(s_min / float(tick_dist))

            points_minor = [0] * (n_ticks_max - n_ticks_min + 1)
            points_major = [0] * (n_ticks_max - n_ticks_min + 1)
            n_major = 0
            n_minor = 0
            for i in range(n_ticks_min, n_ticks_max):
                if minor and i % minor:
                    points_minor[n_minor] = i * tick_dist
                    n_minor += 1
                else:
                    points_major[n_major] = i * tick_dist
                    n_major += 1

            return points_major[:n_major], points_minor[:n_minor]


class KivySourceCodeGraph(BoxLayout):
    def __init__(self):
        super(KivySourceCodeGraph, self).__init__()

        self.graph = self.ids.graph_plot
        self.plots = {}

    def do_plot(self):
        while True:
            dat = pickle.load(sys.stdin.buffer)
            q.put(dat)

    def read_queue(self, dt):
        if q.empty():
            # print("empty")
            pass

        else:
            item = q.get()
            # print(item)

            self.graph.xmin, self.graph.xmax = item['trange']

            for id, points in item['points'].items():
                if id not in self.plots:
                    # print("id: {}".format(id))
                    color_dict = {0: [1, 0, 0, 1], 1: [0, 1, 0, 1], 2: [0, 0, 1, 1]}
                    color = color_dict[int(id) % 3]
                    # print("color: {}, {}, {}".format(id, (id % 3), color))

                    plot = LinePlot(id=id, color=color, line_width=1.5)

                    self.plots[id] = plot
                    self.graph.add_plot(plot)

                plot = self.plots[id]

                if use_simple_lineplot:
                    plot.points.append(points)
                else:
                    plot.points = points

            for id, plot in list(self.plots.items()):
                if id not in item['points']:
                    self.graph.remove_plot(plot)
                    del self.plots[id]


class KivySourceCodeApp(App):
    def on_start(self):
        threading.Thread(target=self.root.do_plot).start()
        Clock.schedule_interval(self.root.read_queue, 0.001)

    def build(self):
        return KivySourceCodeGraph()


if __name__ == '__main__':
    KivySourceCodeApp().run()



