#!/usr/bin/env python3
"""
Two-Way Traffic Light Controller (Generator Version)
====================================================
Uses Python generators for elegant, non-blocking control.

Circuit:
--------
Direction A (North-South): Red=GPIO2, Amber=GPIO3, Green=GPIO4
Direction B (East-West):   Red=GPIO17, Amber=GPIO27, Green=GPIO22

This version uses gpiozero's 'source' parameter to drive lights
from generator functions, creating a more Pythonic solution.

Author: Based on gpiozero documentation
"""

from gpiozero import TrafficLights
from time import sleep
from signal import pause

# Define the two sets of traffic lights
lights_a = TrafficLights(2, 3, 4)    # North-South
lights_b = TrafficLights(17, 27, 22) # East-West

# Timing constants (in seconds)
GREEN_TIME = 10
AMBER_TIME = 3
ALL_RED_TIME = 2
RED_AMBER_TIME = 2

def direction_a_sequence():
    """
    Generator that yields the light states for Direction A.
    
    Yields:
        Tuple of (red, amber, green) boolean values
    """
    while True:
        # Red+Amber (preparing to go)
        yield (1, 1, 0)
        sleep(RED_AMBER_TIME)
        
        # Green
        yield (0, 0, 1)
        sleep(GREEN_TIME)
        
        # Amber (preparing to stop)
        yield (0, 1, 0)
        sleep(AMBER_TIME)
        
        # Red (stopped)
        yield (1, 0, 0)
        sleep(ALL_RED_TIME + RED_AMBER_TIME + GREEN_TIME + AMBER_TIME + ALL_RED_TIME)

def direction_b_sequence():
    """
    Generator that yields the light states for Direction B.
    
    The timing is offset to alternate with Direction A.
    
    Yields:
        Tuple of (red, amber, green) boolean values
    """
    while True:
        # Red (while A has priority)
        yield (1, 0, 0)
        sleep(RED_AMBER_TIME + GREEN_TIME + AMBER_TIME + ALL_RED_TIME)
        
        # Red+Amber (preparing to go)
        yield (1, 1, 0)
        sleep(RED_AMBER_TIME)
        
        # Green
        yield (0, 0, 1)
        sleep(GREEN_TIME)
        
        # Amber (preparing to stop)
        yield (0, 1, 0)
        sleep(AMBER_TIME)
        
        # Red (stopped)
        yield (1, 0, 0)
        sleep(ALL_RED_TIME)

def main():
    """
    Set up the generator-based traffic light control.
    """
    print("Two-Way Traffic Light Controller (Generator Version)")
    print("====================================================")
    print("Press Ctrl+C to stop")
    print()
    print("Direction A: North-South")
    print("Direction B: East-West")
    print()
    print("Running... (lights controlled by generators)")
    print()
    
    # Connect the generators to the traffic lights
    lights_a.source = direction_a_sequence()
    lights_b.source = direction_b_sequence()
    
    # Keep the program running
    try:
        pause()
    except KeyboardInterrupt:
        print("\n\nShutting down...")
        lights_a.off()
        lights_b.off()
        print("All lights off. Goodbye!")

if __name__ == "__main__":
    main()
