import RPi.GPIO as GPIO
import time


class Display():
    delay = 0.000001
    muxDelay = 0.001

    def __init__(self, DS=5, STCP=13, SHCP=19, MR=26, OE=6, D1=17, D2=27, D3=22, D4=10):
        self.DS = DS  # Serial data input (pin 14 IC)
        self.STCP = STCP  # Storage register clock input (pin 12 IC)
        self.SHCP = SHCP  # Shift register clock input (pin 11 IC)
        self.MR = MR  # Master reset (activate LOW)
        self.OE = OE  # Output enable input (activate LOW)
        self.D1 = D1  # Digit 1
        self.D2 = D2  # Digit 2
        self.D3 = D3  # Digit 3
        self.D4 = D4  # Digit 4

    def init(self):
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BCM)
        Allpins = (self.DS, self.STCP, self.SHCP, self.MR, self.OE, self.D1, self.D2, self.D3, self.D4)
        for i in range(9):
            GPIO.setup(Allpins[i], GPIO.OUT)
        GPIO.output(self.D1, GPIO.HIGH)  # common anode display (PNP transistor)
        GPIO.output(self.D2, GPIO.HIGH)
        GPIO.output(self.D3, GPIO.HIGH)
        GPIO.output(self.D4, GPIO.HIGH)

    def initShiftRegister(self):
        GPIO.output(self.OE, GPIO.LOW)
        GPIO.output(self.MR, GPIO.HIGH)

    def writeOneBit(self, bit):
        if bit:
            GPIO.output(self.DS, GPIO.LOW)  # common anode display
            # print("hoog")
            Display().clock()
        else:
            GPIO.output(self.DS, GPIO.HIGH)  # common anode display
            # print("laag")
            Display().clock()

    def clock(self):
        time.sleep(Display().delay)
        GPIO.output(self.SHCP, GPIO.HIGH)
        time.sleep(Display().delay)
        GPIO.output(self.DS, GPIO.LOW)
        GPIO.output(self.SHCP, GPIO.LOW)
        time.sleep(Display().delay)

    def writeByte(self, dataByte):
        filterbit = 0x80
        for i in range(0, 8):
            bit = dataByte & filterbit
            filterbit = filterbit >> 1
            Display().writeOneBit(bit)
        Display().copyToStorageRegister()

    def reset(self):
        GPIO.output(self.MR, GPIO.LOW)
        time.sleep(Display().delay)
        GPIO.output(self.MR, GPIO.HIGH)
        time.sleep(Display().delay)

    def copyToStorageRegister(self):
        GPIO.output(self.STCP, GPIO.HIGH)
        time.sleep(Display().delay)
        GPIO.output(self.STCP, GPIO.LOW)
        time.sleep(Display().delay)

    def convertDecToHex(self, argument):
        switcher = {0: 0x3F,
                    1: 0x06,
                    2: 0x5B,
                    3: 0x4F,
                    4: 0x66,
                    5: 0x6D,
                    6: 0x7D,
                    7: 0x07,
                    8: 0x7F,
                    9: 0x6F,
                    "graden": 0x63,
                    "celsius": 0x39}
        return switcher.get(argument, 0x40)

    def updateDisplay(self, D, digit):
        Display().writeByte(Display().convertDecToHex(digit))
        GPIO.output(D, GPIO.LOW)
        time.sleep(Display().muxDelay)
        GPIO.output(D, GPIO.HIGH)

    def integerToTiental(self):
        tiental = list(str(Display().readTemp()))[0]
        return tiental

    def integerToEenheid(self):
        eenheid = list(str(Display().readTemp()))[1]
        return eenheid


try:
    run = Display()
    run.init()
    run.reset()
    run.initShiftRegister()
    digit1 = "1"
    digit2 = "2"
    digit3 = "graden"
    digit4 = "celsius"
    while True:
        run.updateDisplay(run.D1, digit1)
        run.updateDisplay(run.D2, digit2)
        run.updateDisplay(run.D3, digit3)
        run.updateDisplay(run.D4, digit4)

except(KeyboardInterrupt, SystemExit):
    print("\n\nExit...")
