#!/usr/bin/env python
#
# A port of the semaphore example from TQt.


import sys

# Check if thread support was enabled.
try:
    from PyTQt.tqt import TQThread
except:
    print("Thread support not enabled")
    sys.exit(1)

from PyTQt.tqt import *


# The semaphore instances.
yellowSem = None
greenSem = None


class YellowThread(TQThread):
    def __init__(self,o):
        TQThread.__init__(self)

        self.receiver = o
        self.stopped = 0
        self.mutex = TQMutex()

    def run(self):
        global yellowSem, greenSem

        for i in range(20):
            yellowSem += 1

            event = TQCustomEvent(12345)
            event.setData(TQString("Yellow!"))
            TQThread.postEvent(self.receiver,event)
            self.msleep(200);

            greenSem -= 1

            self.mutex.lock()
            if self.stopped:
                self.stopped = 0
                self.mutex.unlock()
                break

            self.mutex.unlock()

        yellowSem += 1

        event = TQCustomEvent(12346)
        event.setData(TQString("Yellow!"))
        TQThread.postEvent(self.receiver,event)

        greenSem -= 1

    def stop(self):
        self.mutex.lock()
        self.stopped = 1
        self.mutex.unlock()


class GreenThread(TQThread):
    def __init__(self,o):
        TQThread.__init__(self)

        self.receiver = o
        self.stopped = 0
        self.mutex = TQMutex()

    def run(self):
        global yellowSem, greenSem

        for i in range(20):
            greenSem += 1

            event = TQCustomEvent(12345)
            event.setData(TQString("Green!"))
            TQThread.postEvent(self.receiver,event)
            self.msleep(200)

            yellowSem -= 1

            self.mutex.lock()
            if self.stopped:
                self.stopped = 0
                self.mutex.unlock()
                break

            self.mutex.unlock()

        greenSem += 1

        event = TQCustomEvent(12346)
        event.setData(TQString("Green!"))
        TQThread.postEvent(self.receiver,event)
        self.msleep(10)

        yellowSem -= 1

    def stop(self):
        self.mutex.lock()
        self.stopped = 1
        self.mutex.unlock()


class SemaphoreExample(TQWidget):
    def __init__(self):
        TQWidget.__init__(self)

        self.yellowThread = YellowThread(self)
        self.greenThread = GreenThread(self)

        global yellowSem, greenSem
        yellowSem = TQSemaphore(1)
        greenSem = TQSemaphore(1)

        self.button = TQPushButton("&Ignition!",self)
        self.connect(self.button,TQ_SIGNAL("clicked()"),self.startExample)

        self.mlineedit = TQMultiLineEdit(self)
        self.label = TQLabel(self)

        vbox = TQVBoxLayout(self,5)
        vbox.addWidget(self.button)
        vbox.addWidget(self.mlineedit)
        vbox.addWidget(self.label)

    def __del__(self):
        stopYellow = self.yellowThread.running()
        stopGreen = self.greenThread.running()

        if stopYellow:
            self.yellowThread.stop()

        if self.greenThread.running():
            self.greenThread.stop()

        if stopYellow:
            self.yellowThread.wait()

        if stopGreen:
            self.greenThread.wait()

        global yellowSem, greenSem
        yellowSem = None
        greenSem = None

    def startExample(self):
        if self.yellowThread.running() or self.greenThread.running():
            TQMessageBox.information(self,"Sorry",
                "The threads have not completed yet, and must finish before "
                "they can be started again.")

            return

        self.mlineedit.clear()

        global yellowSem

        while yellowSem.available() < yellowSem.total():
            yellowSem -= 1

        yellowSem += 1

        self.yellowThread.start()
        self.greenThread.start()

    def customEvent(self,event):
        if event.type() == 12345:
            s = event.data()

            self.mlineedit.append(s)

            if s.latin1() == "Green!":
                self.label.setEraseColor(TQt.green)
            else:
                self.label.setEraseColor(TQt.yellow)

            self.label.setText(s)

            del s
        elif event.type() == 12346:
            s = event.data()

            TQMessageBox.information(self,s.latin1() + " - Finished",
                "The thread creating the \"" + s.latin1() +
                "\" events has finished.")

            del s
        else:
            print("Unknown custom event type:", event.type())


app = TQApplication(sys.argv)
se = SemaphoreExample()
app.setMainWidget(se)
se.show()

sys.exit(app.exec_loop())
