#!/usr/bin/python

import sys, time, os, os.path
import gi

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

import RPi.GPIO as GPIO

class SwitcherWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Cluster HAT")
        self.set_border_width(10)
        self.set_resizable(False)

	# HAT File locations
	hat_product = "/proc/device-tree/hat/product"
	hat_version = "/proc/device-tree/hat/product_ver"

	# Do we have a HAT?
	if ( not os.path.isfile(hat_product) or not os.access(hat_product, os.R_OK) or not os.path.isfile(hat_version) or not os.access(hat_version, os.R_OK) ):
	        dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "ERROR Cluster HAT not found")
	        dialog.format_secondary_text("Shutdown the Controller, plug in Cluster HAT and power on")
	        dialog.run()
	        dialog.destroy()
	        sys.exit()

	# Is it a Cluster HAT?
	f = open(hat_product, 'r')
	if ( f.read().strip('\x00') != 'ZC4:ClusterHAT' ):
		dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "ERROR Cluster HAT not found")
		dialog.format_secondary_text("Shutdown the Controller, plug in Cluster HAT and power on")
		dialog.run()
		dialog.destroy()
        	sys.exit()
	f.close()

	# Are we running a v1.x or v2.x ?
	# 0x001? = v1.x / 0x002? = v2.x
	f = open(hat_version, 'r')
	tmp = int(f.read().strip('\x00'),16)
	f.close()
	self.version = 0
	if ( tmp >= 16 and tmp <=31 ):
	        self.version = 1
		self.version_minor = tmp - 16
	elif ( tmp >= 32 and tmp <= 47 ):
	        self.version = 2
		self.version_minor = tmp - 32
	else:
		dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Unknown Cluster HAT found")
		dialog.format_secondary_text("Please update the Cluster HAT software");
		dialog.run()
		dialog.destroy()
	        sys.exit()

	# Version specific setup
	if ( self.version == 1 ): # v1.x
	        import RPi.GPIO as GPIO
	        GPIO.setwarnings(False)
	        ports = [31, 33, 35, 37]
	        GPIO.setmode(GPIO.BOARD)
	        GPIO.setup(ports, GPIO.OUT)
	else: # v2.x
	        sys.path.append('/usr/share/clusterctrl/python')
	        import xra1200, smbus
		ports = [1, 2, 3, 4]
	        bus = smbus.SMBus(1)
	        hat = xra1200.Xra1200(bus=1, address=0x20)
		self.p = []
	        self.p.append(xra1200.Xra1200(bus=1, address=0x20, port=0))
	        self.p.append(xra1200.Xra1200(bus=1, address=0x20, port=1))
	        self.p.append(xra1200.Xra1200(bus=1, address=0x20, port=2))
	        self.p.append(xra1200.Xra1200(bus=1, address=0x20, port=3))
	        led = xra1200.Xra1200(bus=1, address=0x20, port=4)
	        hub = xra1200.Xra1200(bus=1, address=0x20, port=5)
	        alert = xra1200.Xra1200(bus=1, address=0x20, port=6)
	        wp = xra1200.Xra1200(bus=1, address=0x20, port=7)
	
	        # Get status of I/O Extender
	        dir = hat.get_dir() # I/O pin directions
	        status = hat.read_byte() # Pin Status
	
	        # If all pins are inputs this is the first run since HAT power up
	        if ( dir == 255 ):
	                if ( ( status & 0xF ) == 0xF ): # Check POS [Power On State]
	                        # POS [NO LINK] set power ON (CUT)
				for port in ports:
					self.p[port-1].on()
	                else:
	                        # POS [LINK] set power off (Default)
				for port in ports:
					self.p[port-1].off()
	                # Set default state for other pins
	                alert.off()
	                led.on()
			if ( self.version_minor == 0 ):
				hub.on()
			else:
				hub.off()
	                wp.on() # We can't detect the state of the WP solder bridge as it pulls high
	                hat.set_dir(0x00) # Set all pins as outputs

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(vbox)

        for port in ports:
                switch = Gtk.Switch()
                switch.connect("notify::active", self.on_switch_activated,port)
		if ( self.version == 1 ):
	                switch.set_active(GPIO.input(port))
		else:
			switch.set_active(self.p[port-1].get())
                switch.set_property("width-request", 400)
                switch.set_property("height-request", 10)
                vbox.pack_start(switch, True, True, 0)


    def on_switch_activated(self, switch, gparam, port):
        if switch.get_active():
		if ( self.version == 1):
            		GPIO.output(port, 1)
		else:
			self.p[port-1].on()
        else:
		if ( self.version == 1):
			GPIO.output(port, 0)
		else:
			self.p[port-1].off()


win = SwitcherWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
