#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4 import Qt
from optparse import OptionParser

# interface lib
import serial
import pyor
from pyor import testio

CDEV='/dev/rfcomm0'
BAUD=115200

SP_H=0x60
SP_M=0x40
SP_L=0x20

SR_L = 0x60
SR_R = 0x61
DR_L = 0x62
DR_R = 0x63

FWD = 0x00
BKWD = 0x01

REGIO = False

class JoyButton(Qt.QPushButton):

    def __init__(self, parent=None, req=None, lp=None, rp=None, ld=None, rd=None):
        Qt.QPushButton.__init__(self, parent)

        self.r = req
        self.lp = lp
        self.rp = rp
        self.ld = ld
        self.rd = rd

        self.connect(self, Qt.SIGNAL("pressed()"), self.sl_pressed)
        self.connect(self, Qt.SIGNAL("released()"), self.sl_released)

    def sl_pressed(self):
        if REGIO:
            self.r.set_reg(register=DR_L, data=self.ld)
            self.r.set_reg(register=DR_R, data=self.rd)
            self.r.set_reg(register=SR_L, data=self.lp)
            self.r.set_reg(register=SR_R, data=self.rp)
        else:
            l = self.r.localhost
            with self.r.transaction():
                self.r.i2cwrite_req(l, [DR_L, self.ld])
                self.r.i2cwrite_req(l, [DR_R, self.rd])
                self.r.i2cwrite_req(l, [SR_L, self.lp])
                self.r.i2cwrite_req(l, [SR_R, self.rp])
            self.r.response()

    def sl_released(self):
        if REGIO:
            self.r.set_reg(register=SR_L, data=0)
            self.r.set_reg(register=SR_R, data=0)
        else:
            l = self.r.localhost
            with self.r.transaction():
                self.r.i2cwrite_req(l, [SR_L, 0])
                self.r.i2cwrite_req(l, [SR_R, 0])
            self.r.response()


class JoyCtl(Qt.QWidget):
    def __init__(self, req, parent=None):
        Qt.QWidget.__init__(self, parent)

        self.layout = Qt.QGridLayout(self)

        # name, key, y_pos, x_pos, l_dir, l_pwm, r_dir, r_pwm
        btn_names = (
            ("l fw",    "7", 0, 0, FWD,   SP_L, FWD,    SP_H, ),
            ("fw",      "8", 0, 1, FWD,   SP_H, FWD,    SP_H, ),
            ("r fw",    "9", 0, 2, FWD,   SP_H, FWD,    SP_L, ),
            ("l",       "4", 1, 0, BKWD,  SP_M, FWD,    SP_M, ),
            ("r",       "6", 1, 2, FWD,   SP_M, BKWD,   SP_M, ),
            ("l bw",    "1", 2, 0, BKWD,  SP_L, BKWD,   SP_H, ),
            ("bw",      "2", 2, 1, BKWD,  SP_H, BKWD,   SP_H, ),
            ("r fw",    "3", 2, 2, BKWD,  SP_H, BKWD,   SP_L, ), )

        for b in btn_names:
            btn = JoyButton("%s (%s)" % (b[0], b[1], ),
                            req=req,
                            ld=b[4], lp=b[5],
                            rd=b[6], rp=b[7]
                            )
            btn.setShortcut(Qt.QKeySequence(b[1]))
            self.layout.addWidget(btn, b[2], b[3])


class MainWindow():

    def __init__(self, req):
        self.req = req

        self.app = Qt.QApplication(sys.argv)

        self.window = Qt.QWidget()
        self.window.setWindowTitle("QTiger")

        self.layout = Qt.QVBoxLayout()
        self.window.setLayout(self.layout)

        # hack
        cdev = self.req.ser.ser.port
        baud = self.req.ser.ser.baudrate
        self.port_label = Qt.QLabel("Port: %s, baud: %s" % (cdev, baud, ))
        self.layout.addWidget(self.port_label)

        ver = self.req.protocol_version
        local = self.req.localhost
        freq = self.req.busfreq
        self.dev_label = Qt.QLabel("Protocol ver: %s; Local: 0x%02x; I<sup>2</sup>C freq: %s kHz" % (ver, local, freq, ))
        self.layout.addWidget(self.dev_label)

        self.joy_ctl = JoyCtl(self.req)
        self.layout.addWidget(self.joy_ctl)

    def start(self):
        self.window.show()
        self.app.exec_()


def main():
    parser = OptionParser()
    parser.add_option("-p", "--port", dest="port", help="communication port",
                      metavar="FILE", default=CDEV)
    parser.add_option("-b", "--baud", dest="baud", help="baud rate",
                      metavar="N", default=BAUD)
    (options, args) = parser.parse_args()

    ser = serial.Serial(options.port, options.baud, timeout=1)
    logio = testio.LogIO(ser)
    req = pyor.Request(logio)
    req.localhost = 0x10
    req.busfreq = 100

    gui_ = MainWindow(req)
    gui_.start()

if __name__ == "__main__":
    main()
