# cpy Thonny - guizero shuttle simulation - signal patterns
# provided by Anthony Vogelaar, Perth Scotland
# rev 0.10  2025-01-03  initial release

# tools |  manage packages | guizero : search on pypi | install
# drawing: https://lawsie.github.io/guizero/drawing/

import	time
from 	guizero import App, Drawing

# ==================== GUI setup =========================

app = App('Shuttle simulation', width=800, height=200)
ctx = Drawing(app, width='fill', height='fill')

# ======================= Globals ========================

signal_patterns = [['r', 'r', 'r',  'r', 'r', 'r'],
                   ['g', 'g', 'g',  'r', 'r', 'r'],
                   ['r', 'g', 'g',  'r', 'r', 'r'],
                   ['r', 'r', 'g',  'r', 'r', 'r'],
                   ['r', 'r', 'r',  'r', 'r', 'r'],
                   ['r', 'r', 'r',  'g', 'g', 'g'],
                   ['r', 'r', 'r',  'g', 'g', 'r'],
                   ['r', 'r', 'r',  'g', 'r', 'r']]

# ======================= Widgets ========================

# draw track, center @ x=400, y=100
def track():
    ctx.line(10,  90, 790,  90, width=4)
    ctx.line(10, 110, 790, 110, width=4)


# draw 2 aspect signal, centre at x, y
def aspect2(x=0, y=0, green=False, mirror=False):
    x0 = 400+x; y0=100+y
    m  = -1 if mirror else +1
    ctx.line     (x0-m*30, y0-2,  x0-m*10, y0-2,  width=2)
    ctx.line     (x0-m*30, y0+2,  x0-m*10, y0+2,  width=2)
    ctx.line     (x0-m*30, y0-10, x0-m*30, y0+10, width=5)
    ctx.rectangle(x0-m*10, y0-10, x0+m*30, y0+10, color='black')
    if green: ctx.oval(x0+m*14, y0-6, x0+m*26, y0+6, color='lime')
    else    : ctx.oval(x0-m*6,  y0-6, x0+m*6,  y0+6, color='red')


# set 6 signals according to pattern
def setSignals(pattern=['r', 'r', 'r',  'g', 'r', 'r']):
    for pos, idx in zip((-250, 0, 250), ((0, 3), (1, 4), (2, 5))):
        aspect2(x=pos, y=-40, green=pattern[idx[0]]=='g')
        aspect2(x=pos, y= 40, green=pattern[idx[1]]=='g', mirror=True)


# draw layout:  signals[state], track and train
def layout(state=0):
    pattern = signal_patterns[state]
    ctx.clear()					# clear context
    track()
    setSignals(pattern)
    
# ======================= Timer =========================

state   = 1
# application sequencer @ 2 Sec
def onTimer():
    global state
    
    layout(state)
    state += 1
    if state == len(signal_patterns):
        state = 0

# ========================= main =========================

layout()
ctx.repeat(2000, onTimer)			# sequencer @ 2 Sec
app.display()						# start GUI loop
    
# ========================== end =========================    
