#!/usr/bin/python
# -*- coding: ANSI_X3.4-1968 -*-
# generated by wxGlade 0.4.1 on Fri May  5 17:17:53 2006

import wx
import os
import time
import cal
from math import *


# this dictionary puts the various brightness settings for the
# display module in order
display_dict = { 0:0 ,  1:16,  2:32,  3:48,  4:33,  5:17,  6:34,  7:1 ,\
		 8:35,  9:18, 10:49, 11:36, 12:2 , 13:19, 14:37, 15:50,\
		16:20, 17:38, 18:3 , 19:39, 20:21, 21:4 , 22:40, 23:51,\
		24:22, 25:5 , 26:52, 27:23, 28:41, 29:53, 30:6 , 31:24,\
		32:42, 33:7 , 34:25, 35:43, 36:54, 37:8 , 38:44, 39:26,\
		40:55, 41:9 , 42:27, 43:45, 44:56, 45:10, 46:28, 47:57,\
		48:46, 49:11, 50:29, 51:58, 52:47, 53:12, 54:59, 55:30,\
		56:13, 57:60, 58:31, 59:14, 60:61, 61:15, 62:62, 63:63}
reverse_dict = dict(zip(display_dict.values(),display_dict.keys()))
cal_data = [];

class PonyDisplay(wx.Window):
    # nothing exciting...
    pass

def connect(name):
    # testing now...
    global st_out,st_in
    st_out,st_in = os.popen2(name,'b',0);
    try:
        st_out.write("Hello\n")
    except:
        return 0
    time.sleep(0.1)
    if st_in.readline().startswith("Hi"):
        if st_in.readline().startswith("OK"):
            return 1;
    return 0;

def get_response(text):
    st_out.write(text + '\n')
    time.sleep(0.1)
    response = st_in.readline()
    if st_in.readline().startswith('OK'):
        return response
    else:
        return ''

def check_response(text,num,digits):
    # bring up error if don't get back what we expected...
    format = '%%(text)s %%(num)0%(digits)dX\n' % vars()
    text = format % vars()

def tidy(n):
    if n > 0x7fff:
        return float(n - 0x10000)
    return float(n)

class PonyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: PonyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.notebook_1 = wx.Notebook(self, -1, style=0)
        self.notebook_1_pane_3 = wx.Panel(self.notebook_1, -1)
        self.notebook_1_pane_2 = wx.Panel(self.notebook_1, -1)
        self.notebook_1_pane_1 = wx.Panel(self.notebook_1, -1)
        self.statusbar = self.CreateStatusBar(2, 0)
        self.label_1 = wx.StaticText(self.notebook_1_pane_1, -1, "Laser brightness")
        self.laser_slider = wx.Slider(self.notebook_1_pane_1, -1, 128, 0, 255)
        self.label_2 = wx.StaticText(self.notebook_1_pane_1, -1, "Display brightness")
        self.display_slider = wx.Slider(self.notebook_1_pane_1, -1, 32, 0, 63)
        self.temp_box = wx.CheckBox(self.notebook_1_pane_1, -1, "Display temperature on startup")
        self.batt_box = wx.CheckBox(self.notebook_1_pane_1, -1, "Display battery power on startup")
        self.calibration_list = wx.ListCtrl(self.notebook_1_pane_2, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.label_3 = wx.StaticText(self.notebook_1_pane_2, -1, "Compass")
        self.compass = wx.TextCtrl(self.notebook_1_pane_2, -1, "")
        self.label_4 = wx.StaticText(self.notebook_1_pane_2, -1, "Clino")
        self.clino = wx.TextCtrl(self.notebook_1_pane_2, -1, "")
        self.button_1 = wx.Button(self.notebook_1_pane_2, -1, "Acquire")
        self.button_2 = wx.Button(self.notebook_1_pane_2, -1, "Remove")
        self.button_3 = wx.Button(self.notebook_1_pane_2, -1, "Calibrate Pony")
        self.model = PonyDisplay(self.notebook_1_pane_3, -1)

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_COMMAND_SCROLL, self.laser_scroll, self.laser_slider)
        self.Bind(wx.EVT_COMMAND_SCROLL, self.display_scroll, self.display_slider)
        self.Bind(wx.EVT_CHECKBOX, self.set_temp, self.temp_box)
        self.Bind(wx.EVT_CHECKBOX, self.set_power, self.batt_box)
        self.Bind(wx.EVT_BUTTON, self.acquire, self.button_1)
        self.Bind(wx.EVT_BUTTON, self.remove, self.button_2)
        self.Bind(wx.EVT_BUTTON, self.calibrate, self.button_3)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: PonyFrame.__set_properties
        self.SetTitle("PonyTrainer")
        self.SetSize((400, 436))
        self.statusbar.SetStatusWidths([-1, -1])
        # statusbar fields
        statusbar_fields = ["Device", "Status"]
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)
        self.laser_slider.SetMinSize((200, 40))
        self.display_slider.SetMinSize((200,40))
        self.batt_box.SetValue(1)
        self.calibration_list.SetMinSize((384, 245))
        self.button_1.SetDefault()
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: PonyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_6 = wx.BoxSizer(wx.VERTICAL)
        sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.GridSizer(2, 2, 0, 0)
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3.Add(self.label_1, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 3)
        sizer_3.Add(self.laser_slider, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 3)
        sizer_2.Add(sizer_3, 0, wx.SHAPED, 0)
        sizer_4.Add(self.label_2, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 3)
        sizer_4.Add(self.display_slider, 0, wx.ALL|wx.EXPAND, 3)
        sizer_2.Add(sizer_4, 0, 0, 0)
        sizer_2.Add(self.temp_box, 0, wx.ALL, 3)
        sizer_2.Add(self.batt_box, 0, wx.ALL, 3)
        self.notebook_1_pane_1.SetAutoLayout(True)
        self.notebook_1_pane_1.SetSizer(sizer_2)
        sizer_2.Fit(self.notebook_1_pane_1)
        sizer_2.SetSizeHints(self.notebook_1_pane_1)
        sizer_6.Add(self.calibration_list, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(self.label_3, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 3)
        grid_sizer_1.Add(self.compass, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3)
        grid_sizer_1.Add(self.label_4, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 3)
        grid_sizer_1.Add(self.clino, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3)
        sizer_8.Add(grid_sizer_1, 1, wx.ALIGN_CENTER_VERTICAL, 0)
        sizer_7.Add(sizer_8, 1, wx.ALIGN_CENTER_VERTICAL, 0)
        sizer_7.Add(self.button_1, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 3)
        sizer_7.Add(self.button_2, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 3)
        sizer_6.Add(sizer_7, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.SHAPED, 0)
        sizer_6.Add(self.button_3, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.SHAPED, 3)
        self.notebook_1_pane_2.SetAutoLayout(True)
        self.notebook_1_pane_2.SetSizer(sizer_6)
        sizer_6.Fit(self.notebook_1_pane_2)
        sizer_6.SetSizeHints(self.notebook_1_pane_2)
        sizer_5.Add(self.model, 1, wx.EXPAND, 0)
        self.notebook_1_pane_3.SetAutoLayout(True)
        self.notebook_1_pane_3.SetSizer(sizer_5)
        sizer_5.Fit(self.notebook_1_pane_3)
        sizer_5.SetSizeHints(self.notebook_1_pane_3)
        self.notebook_1.AddPage(self.notebook_1_pane_1, "Settings")
        self.notebook_1.AddPage(self.notebook_1_pane_2, "Calibrate")
        self.notebook_1.AddPage(self.notebook_1_pane_3, "Model")
        sizer_1.Add(self.notebook_1, 1, wx.EXPAND, 0)
        self.SetAutoLayout(True)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade
        # ok - here we do our detection for our stuff
        # laser
        self.laser_slider.SetValue(int(get_response('Laser'),16))
        self.display_slider.SetValue(reverse_dict[int(get_response('Display'),16)])
        self.temp_box.SetValue(int(get_response('Temp'),16))
        self.batt_box.SetValue(int(get_response('Battery'),16))
        self.calibration_list.InsertColumn(0,'Compass');
        self.calibration_list.InsertColumn(1,'Clino');
        self.calibration_list.InsertColumn(2,'RCompass');
        self.calibration_list.InsertColumn(3,'RClino');
        self.calibration_list.InsertColumn(4,'Error');
        

    def laser_scroll(self, event): # wxGlade: PonyFrame.<event_handler>
        check_response('Laser',self.laser_slider.GetValue(),2)
        event.Skip()

    def display_scroll(self, event): # wxGlade: PonyFrame.<event_handler>
        check_response('Display',display_dict[self.display_slider.GetValue()],2)
        event.Skip()

    def set_temp(self, event): # wxGlade: PonyFrame.<event_handler>
        check_response('Temp',self.temp_box.GetValue(),1)
        event.Skip()

    def set_power(self, event): # wxGlade: PonyFrame.<event_handler>
        check_response('Battery',self.batt_box.GetValue(),1)
        event.Skip()

    def acquire(self, event): # wxGlade: PonyFrame.<event_handler>
        G = [tidy(int(f,16)) for f in get_response('GG').split()]
        M = [tidy(int(f,16)) for f in get_response('GM').split()]
        tempdict = {'compass':self.compass.GetValue(),
                         'clino':self.clino.GetValue(),
                         'rcompass':0.0,
                         'rclino':0.0,
                         'error':-1,
                         'G':G,
                         'M':M}
        (tempdict['rcompass'],tempdict['rclino']) = cal.get_raw_reading(tempdict)
        # get data from 
        cal_data.append(tempdict);
        self.update_list()
        self.compass.SetFocus()
        event.Skip()

    def remove(self, event): # wxGlade: PonyFrame.<event_handler>
        item = self.calibration_list.GetNextItem(-1,wx.LIST_NEXT_ALL,wx.LIST_STATE_SELECTED)
        if item>=0:
            del cal_data[item]
            self.update_list()
        event.Skip()

    def calibrate(self, event): # wxGlade: PonyFrame.<event_handler>
        (M,G) = cal.calibrate(cal_data)
        print M
        print G
        event.Skip()

    def update_list(self):
        self.calibration_list.DeleteAllItems()
        i=0
        for f in cal_data:
            self.calibration_list.InsertStringItem(i,"")
            self.calibration_list.SetStringItem(i,0,str(f['compass']))
            self.calibration_list.SetStringItem(i,1,str(f['clino']))
            self.calibration_list.SetStringItem(i,2,str(int(f['rcompass'])))
            self.calibration_list.SetStringItem(i,3,str(int(f['rclino'])))
            self.calibration_list.SetStringItem(i,4,str(f['error']))
            i = i+1
            
        

# end of class PonyFrame


if __name__ == "__main__":
    PonyTrainer = wx.PySimpleApp(0)
    fname = './fraud'
    while (not connect(fname)):
        fname = wx.FileSelector("File for SAP?")
        if len(fname) == 0:
            exit(0)
    wx.InitAllImageHandlers()
    PonyFrame1 = PonyFrame(None, -1, "")
    PonyTrainer.SetTopWindow(PonyFrame1)
    PonyFrame1.Show()
    PonyTrainer.MainLoop()

