from IPython.core.display import display, HTML
from string import Template
import pandas as pd
import json, random

HTML('<script src="lib/d3/d3.min.js"></script>')

html_template = Template('''
<svg id="graph-div"></div>
<script> $js_text </script>
''')

js_text_template = Template('''
var data = $data;

var barHeight = 30;
var barWidth = 30;
var width = 400;

var x = d3.scale.linear()
        .domain([0, 4096])
        .range(["black", "white"]);

var chart = d3.select('#graph-div')
    .attr('width', width)
    .attr('height', 400);

function update() {
    var row = chart.selectAll('.item')
        .data(data)
        .enter()
        .append('g')
        .attr('class', 'item')
        .attr('transform', function(d, i){
            console.log(d);
            console.log(i);
            return 'translate(' + barWidth * (i%10) + ', ' + barHeight * Math.floor(i/10) + ')';
        })
        .append('rect')
        .attr('width', barWidth)
        .attr('height', barHeight)
        .attr('fill', function(d) {
            return x(d);
        });
}

update();
''')

data = [];
js_text = js_text_template.substitute({'data': json.dumps(data)})
HTML(html_template.substitute({'js_text': js_text}))

"""
Explanation: Step 1: Set up D3 area
End of explanation
"""


js_text_template_2 = Template('''
data = $data;
update();
console.log("updating");
''')

data = [] #[0,500,1000,2000,4000]

def update_graph(data):
    js_text = js_text_template_2.substitute({'data': json.dumps(data)})
    display(HTML('<script>' + js_text + '</script>'))

update_graph(data)

"""
Explanation: OK, the D3 area is set up
Now we'll focus on live updating.  A manual test first.
End of explanation
"""


import paho.mqtt.client as mqtt

data = []
tests = [[]]

update_graph(data)

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("/outTopic")

def on_message(client, userdata, msg):
    global data
    try:
        msg_json = json.loads(msg.payload)
    except:
        print "Error"
        print(msg.topic+" "+str(msg.payload))
        return
    # if msg_json['type'] == "BREAK" and msg_json['label'] == "LOOP":  # and msg_json['value'] == "END":
    #     tests.append(data)
    #     data = []
    #     update_graph(data)
    if msg_json['type'] == "BINARY" and msg_json['label'] == "A0":
        data.append(int(msg_json['value']))
        # tests[-1] = data
        update_graph(data)
        print int(msg_json['value']), data

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set("zettlmtm", "VOUbRcmhjffA")
client.connect("m11.cloudmqtt.com", 19280, 60)
client.loop_start()
# Make sure to call client.loop_stop() later

client.loop_stop()

print data

"""
Explanation: Step 2: Now use MQTT to update the graph
Now for the fun stuff.  Using the update_graph(data) function set up above.  Each group of data, separated by "start" messages, is saved in the tests array.  As new data comes in, the live data graph is updated to show data from the last test.  All data is neatly saved inside the tests array for replotting and further analysis later.
Using the CloudMQTT free Cat plan:
* https://api.cloudmqtt.com/sso/cloudmqtt/console
* haipjacob@gmail.com:paramour-sieve-paper
* If the Websocket UI has trouble connecting, restart the instance
End of explanation
"""


