import serial
import sys
import threading
import time
import wx
import random
import wx.lib.plot as plot


average = 1

if len(sys.argv)>1:
  average = int(sys.argv[1])

s = serial.Serial("/dev/ttyUSB0", 115200)
s.readline()

def getReading():
  x = s.readline()
  k = x.split()
  if len(k)<2:
    return getReading()
    
  #print k[0], k[1]
  
  try:
    return int(k[0]) - int(k[1])
  except ValueError:
    return getReading()

def averageReadings(average):
  sum = 0.0
  for i in xrange(average):
    sum += getReading()
  return sum / average
    


ZERO = 132.201
SLOPE = 1.5465
def readingToPounds(x):
  global ZERO, SLOPE
  
  return (x-ZERO)/SLOPE

MAX_SAMPLES = 150


class DrawPanel(wx.Frame):

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, size=wx.Size(800,600))
        self.points = [0 for i in range(MAX_SAMPLES)]
        print self.points
        self.currMax = 0;
        self.lastPoint = len(self.points)
        self.SetBackgroundColour('#4f5049')

        vbox = wx.BoxSizer(wx.VERTICAL)

        self.client = plot.PlotCanvas(self)
        wx.EVT_LEFT_DOWN(self, self.OnMouseDown)
        wx.EVT_CLOSE(self, self.OnQuit)


        vbox.Add(self.client, 1, wx.EXPAND | wx.BOTTOM, 0)

        #self.Bind(wx.EVT_IDLE, self.OnIdle)

        self.OnUpdateGraph()
        self.SetSizer(vbox)
        self.Show(True)

    def OnIdle(self,evt=None):
      z = averageReadings(average)
      print "%2.2f\t=\t%+2.2f pounds"% (z, readingToPounds(z))
      self.addPoint(readingToPounds(z))

    def OnQuit(self,evt=None):
      self.Destroy()
      sys.exit(0)

    def OnMouseDown (self, event):
        self.addPoint(random.randint(0,200))
        self.OnUpdateGraph()

    def getRandData(self, size=MAX_SAMPLES):
        teList = []
        for i in range(size):
            teList.append((i,random.randint(1,1000)))
        return teList


    def addPoint(self,newPoint):
        #print "adding point" + str(newPoint)
        self.points.pop(0)
        if(newPoint > self.currMax):
            self.currMax = newPoint
        self.points.append(newPoint)
        self.lastPoint += 1
        self.OnUpdateGraph()

    def getDataFromPoints(self):
      return [(i,self.points[i - (self.lastPoint - MAX_SAMPLES)]) for i in range(self.lastPoint - MAX_SAMPLES,self.lastPoint)]
    
    def OnUpdateGraph(self, event=None):
        #frm = wx.Frame(self, -1, 'line', size=(600,450))
        #client = plot.PlotCanvas(self)
        line = plot.PolyLine(self.getDataFromPoints(), legend='', colour='blue', width=4)
        gc = plot.PlotGraphics([line], 'Weight Graph', 'Sample', '# Of Cans')
        self.client.Draw(gc,xAxis=(self.lastPoint - MAX_SAMPLES,self.lastPoint),yAxis=(0,self.currMax))
        self.Refresh(True)
        self.Update()
        #frm.Show(True)


class DrawingApp(wx.App):
    def OnInit(self):
        #frame = wx.Frame(None, 100, 'Scale App', wx.Point(100,50), wx.Size(800,600))
        #frame.Center(wx.BOTH)
        self.drawing = DrawPanel(None)
        #frame.Show(True)
        return True


app = None

class MyThread(threading.Thread):
  def run(self):
    global app
    app = DrawingApp(0)
    app.MainLoop()


MyThread().start()



##############
#STARTUP: measure zero
print "Measuring zero..."

ZERO = averageReadings(1000)
CAN_DIVISOR = 2.7/3 #pounds/can

#app = DrawingApp(0)
#app.MainLoop()


sum = 0.0
count = 0
while True:
  z = averageReadings(average)
  print "%2.2f\t=\t%+2.2f pounds"% (z, readingToPounds(z))
  if app:
    wx.CallAfter(app.drawing.addPoint,round(readingToPounds(z)/CAN_DIVISOR))
