#!/usr/bin/env python3
import time
import random
import RPi.GPIO as GPIO
from PIL import Image, ImageDraw, ImageFont

class OregonTrail:
    def __init__(self, display_obj, gpio_obj, backlight_obj):
        if None in (display_obj, gpio_obj, backlight_obj):
            raise ValueError("Missing hardware components")
            
        self.display = display_obj
        self.GPIO = gpio_obj
        self.backlight = backlight_obj
        self.last_input_time = 0
        self.debounce_delay = 0.15
        
        # Optimized fonts for 240x240 display
        try:
            self.font_small = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 14)
            self.font_medium = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 16)
            self.font_large = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 18)
        except:
            self.font_small = ImageFont.load_default()
            self.font_medium = ImageFont.load_default()
            self.font_large = ImageFont.load_default()

        self.reset_game()

    def reset_game(self):
        # Simplified game state
        self.money = 400
        self.food = 0
        self.bullets = 0
        self.oxen = 0
        self.clothes = 0
        
        # Simplified party (3 people instead of 5)
        self.party = [
            {"name": "You", "sick": False},
            {"name": "Wife", "sick": False},
            {"name": "Child", "sick": False}
        ]
        
        # Journey
        self.miles = 0
        self.month = 3  # March
        self.day = 1
        
        # Simplified landmarks
        self.landmarks = [
            {"name": "Independence", "miles": 0},
            {"name": "Kansas River", "miles": 185},
            {"name": "Big Blue River", "miles": 304},
            {"name": "Fort Kearney", "miles": 554},
            {"name": "Chimney Rock", "miles": 640},
            {"name": "Fort Laramie", "miles": 932},
            {"name": "Independence Rock", "miles": 1288},
            {"name": "Snake River", "miles": 1828},
            {"name": "Oregon City", "miles": 2040}
        ]
        self.current_landmark = 0

    def read_controls_debounced(self):
        current_time = time.time()
        if current_time - self.last_input_time < self.debounce_delay:
            return {}
            
        controls = {
            'up': not self.GPIO.input(17),
            'down': not self.GPIO.input(22),
            'left': not self.GPIO.input(27),
            'right': not self.GPIO.input(23),
            'button_a': not self.GPIO.input(5),
            'button_b': not self.GPIO.input(6)
        }
        
        if any(controls.values()):
            self.last_input_time = current_time
        return controls

    def draw_large_wagon(self, draw, x, y, color=(0, 255, 0)):
        """Draw a detailed wagon sprite"""
        # Wagon body
        draw.rectangle([x+10, y+5, x+50, y+25], fill=color)
        draw.rectangle([x+12, y+7, x+48, y+23], outline=(0, 0, 0), width=2)
        
        # Wagon cover
        draw.ellipse([x+8, y-5, x+52, y+15], fill=(255, 255, 255))
        draw.ellipse([x+10, y-3, x+50, y+13], outline=(0, 0, 0), width=2)
        
        # Wheels
        draw.ellipse([x+5, y+20, x+20, y+35], fill=color)
        draw.ellipse([x+7, y+22, x+18, y+33], outline=(0, 0, 0), width=2)
        draw.ellipse([x+40, y+20, x+55, y+35], fill=color)
        draw.ellipse([x+42, y+22, x+53, y+33], outline=(0, 0, 0), width=2)
        
        # Spokes
        draw.line([x+12, y+27, x+13, y+28], fill=(0, 0, 0), width=2)
        draw.line([x+47, y+27, x+48, y+28], fill=(0, 0, 0), width=2)

    def draw_broken_wagon(self, draw, x, y):
        """Draw a broken wagon with missing wheel"""
        # Tilted wagon body
        draw.polygon([x+10, y+15, x+50, y+10, x+48, y+30, x+12, y+35], fill=(139, 69, 19))
        
        # Torn wagon cover
        draw.polygon([x+8, y+5, x+30, y-5, x+52, y+8, x+35, y+20], fill=(200, 200, 200))
        
        # One good wheel
        draw.ellipse([x+5, y+30, x+20, y+45], fill=(139, 69, 19))
        draw.ellipse([x+7, y+32, x+18, y+43], outline=(0, 0, 0), width=2)
        
        # Broken wheel pieces
        draw.arc([x+40, y+25, x+55, y+40], 0, 180, fill=(139, 69, 19), width=3)
        draw.line([x+45, y+35, x+50, y+45], fill=(139, 69, 19), width=2)

    def draw_oxen(self, draw, x, y, color=(139, 69, 19)):
        """Draw oxen pulling the wagon"""
        # Ox body
        draw.ellipse([x, y+10, x+25, y+25], fill=color)
        # Ox head
        draw.ellipse([x-8, y+12, x+5, y+23], fill=color)
        # Horns
        draw.line([x-6, y+12, x-4, y+8], fill=(255, 255, 255), width=2)
        draw.line([x+1, y+12, x+3, y+8], fill=(255, 255, 255), width=2)
        # Legs
        draw.line([x+5, y+25, x+5, y+32], fill=color, width=3)
        draw.line([x+15, y+25, x+15, y+32], fill=color, width=3)
        draw.line([x+20, y+25, x+20, y+32], fill=color, width=3)

    def draw_sick_oxen(self, draw, x, y):
        """Draw sick/injured oxen"""
        # Lying down ox
        draw.ellipse([x, y+20, x+25, y+30], fill=(100, 50, 0))
        draw.ellipse([x-8, y+22, x+5, y+28], fill=(100, 50, 0))
        # X eyes (dead/sick)
        draw.line([x-5, y+23, x-2, y+26], fill=(255, 0, 0), width=2)
        draw.line([x-2, y+23, x-5, y+26], fill=(255, 0, 0), width=2)

    def draw_river_scene(self, draw, x, y):
        """Draw river crossing scene"""
        # River waves
        for i in range(4):
            draw.arc([x+i*20, y+15, x+i*20+25, y+30], 0, 180, fill=(0, 150, 255), width=3)
            draw.arc([x+i*20+12, y+20, x+i*20+37, y+35], 180, 360, fill=(0, 150, 255), width=3)
        
        # Small wagon crossing
        self.draw_large_wagon(draw, x+30, y-5, (139, 69, 19))

    def draw_fort(self, draw, x, y):
        """Draw fort with flag"""
        # Fort walls
        draw.rectangle([x, y, x+60, y+40], fill=(139, 69, 19))
        draw.rectangle([x+5, y+5, x+55, y+35], outline=(0, 0, 0), width=2)
        
        # Towers
        draw.rectangle([x-5, y-10, x+10, y+20], fill=(139, 69, 19))
        draw.rectangle([x+50, y-10, x+65, y+20], fill=(139, 69, 19))
        
        # Flag
        draw.line([x+30, y-15, x+30, y+5], fill=(139, 69, 19), width=3)
        draw.polygon([x+30, y-15, x+45, y-10, x+30, y-5], fill=(255, 0, 0))

    def draw_chimney_rock(self, draw, x, y):
        """Draw Chimney Rock landmark"""
        # Base rock
        draw.ellipse([x, y+20, x+50, y+50], fill=(128, 128, 128))
        # Chimney spire
        draw.rectangle([x+20, y-10, x+30, y+30], fill=(160, 160, 160))
        draw.rectangle([x+18, y-12, x+32, y-8], fill=(128, 128, 128))

    def draw_mountains(self, draw, x, y):
        """Draw mountain range"""
        # Multiple mountain peaks
        draw.polygon([x, y+40, x+20, y, x+40, y+25, x+60, y-5, x+80, y+40], fill=(100, 100, 100))
        draw.polygon([x+10, y+40, x+30, y+10, x+50, y+40], fill=(120, 120, 120))
        
        # Snow caps
        draw.polygon([x+15, y+5, x+25, y, x+35, y+5, x+25, y+15], fill=(255, 255, 255))
        draw.polygon([x+50, y, x+60, y-5, x+70, y, x+60, y+10], fill=(255, 255, 255))

    def draw_grave(self, draw, x, y):
        """Draw gravestone"""
        # Gravestone
        draw.rectangle([x+20, y+10, x+40, y+40], fill=(128, 128, 128))
        draw.ellipse([x+20, y+10, x+40, y+25], fill=(128, 128, 128))
        
        # Cross
        draw.line([x+30, y+15, x+30, y+30], fill=(255, 255, 255), width=3)
        draw.line([x+25, y+20, x+35, y+20], fill=(255, 255, 255), width=3)
        
        # RIP text
        draw.text((x+22, y+25), "RIP", font=self.font_small, fill=(0, 0, 0))

    def draw_storm_clouds(self, draw, x, y):
        """Draw storm clouds with lightning"""
        # Dark clouds
        draw.ellipse([x, y, x+30, y+20], fill=(64, 64, 64))
        draw.ellipse([x+20, y-5, x+50, y+15], fill=(64, 64, 64))
        draw.ellipse([x+40, y, x+70, y+20], fill=(64, 64, 64))
        
        # Lightning bolt
        draw.polygon([x+35, y+20, x+30, y+35, x+35, y+35, x+25, y+50, x+30, y+50, x+40, y+30], 
                    fill=(255, 255, 0))

    def draw_thief(self, draw, x, y):
        """Draw thief stealing supplies"""
        # Thief figure (stick figure with hat)
        draw.ellipse([x+15, y, x+25, y+10], fill=(255, 200, 150))  # Head
        draw.rectangle([x+12, y-5, x+28, y+2], fill=(0, 0, 0))     # Hat
        draw.line([x+20, y+10, x+20, y+30], fill=(0, 0, 0), width=3)  # Body
        draw.line([x+20, y+15, x+15, y+25], fill=(0, 0, 0), width=2)  # Arm
        draw.line([x+20, y+15, x+25, y+25], fill=(0, 0, 0), width=2)  # Arm
        draw.line([x+20, y+30, x+15, y+40], fill=(0, 0, 0), width=2)  # Leg
        draw.line([x+20, y+30, x+25, y+40], fill=(0, 0, 0), width=2)  # Leg
        
        # Stolen supplies bag
        draw.ellipse([x+30, y+20, x+45, y+35], fill=(139, 69, 19))
        draw.text((x+32, y+25), "$", font=self.font_small, fill=(255, 255, 0))

    def draw_snake(self, draw, x, y):
        """Draw snake for snake bite event"""
        # Snake body (S-curve)
        points = []
        for i in range(0, 60, 2):
            snake_y = y + 20 + int(10 * (i % 20 - 10) / 10)
            points.append((x + i, snake_y))
        
        for i in range(len(points)-1):
            draw.line([points[i], points[i+1]], fill=(0, 128, 0), width=4)
        
        # Snake head
        draw.ellipse([x+55, y+15, x+65, y+25], fill=(0, 100, 0))
        # Eyes
        draw.ellipse([x+57, y+17, x+59, y+19], fill=(255, 0, 0))
        draw.ellipse([x+61, y+17, x+63, y+19], fill=(255, 0, 0))

    def draw_deer(self, draw, x, y):
        """Draw deer for hunting"""
        # Deer body
        draw.ellipse([x+10, y+15, x+35, y+25], fill=(139, 69, 19))
        # Deer head
        draw.ellipse([x+30, y+10, x+45, y+20], fill=(139, 69, 19))
        # Antlers
        draw.line([x+35, y+5, x+32, y], fill=(160, 160, 160), width=2)
        draw.line([x+35, y+5, x+38, y], fill=(160, 160, 160), width=2)
        draw.line([x+40, y+5, x+37, y], fill=(160, 160, 160), width=2)
        draw.line([x+40, y+5, x+43, y], fill=(160, 160, 160), width=2)
        # Legs
        draw.line([x+15, y+25, x+15, y+35], fill=(139, 69, 19), width=2)
        draw.line([x+20, y+25, x+20, y+35], fill=(139, 69, 19), width=2)
        draw.line([x+25, y+25, x+25, y+35], fill=(139, 69, 19), width=2)
        draw.line([x+30, y+25, x+30, y+35], fill=(139, 69, 19), width=2)

    def draw_event_graphic(self, draw, event_type, x, y):
        """Draw graphics for different event types"""
        if event_type == "wagon_break":
            self.draw_broken_wagon(draw, x, y)
        elif event_type == "ox_injury":
            self.draw_sick_oxen(draw, x, y)
        elif event_type == "storm":
            self.draw_storm_clouds(draw, x, y)
        elif event_type == "theft":
            self.draw_thief(draw, x, y)
        elif event_type == "snake_bite":
            self.draw_snake(draw, x, y)
        elif event_type == "sickness":
            self.draw_grave(draw, x, y)
        elif event_type == "river_crossing":
            self.draw_river_scene(draw, x, y)
        elif event_type == "hunting":
            self.draw_deer(draw, x, y)
        elif event_type == "good_weather":
            # Sun
            draw.ellipse([x+20, y+10, x+40, y+30], fill=(255, 255, 0))
            # Sun rays
            for angle in range(0, 360, 45):
                import math
                rad = math.radians(angle)
                x1 = x + 30 + int(25 * math.cos(rad))
                y1 = y + 20 + int(25 * math.sin(rad))
                x2 = x + 30 + int(35 * math.cos(rad))
                y2 = y + 20 + int(35 * math.sin(rad))
                draw.line([x1, y1, x2, y2], fill=(255, 255, 0), width=2)

    def draw_landmark_graphic(self, draw, landmark_name, x, y):
        """Draw landmark-specific graphics"""
        if "River" in landmark_name:
            self.draw_river_scene(draw, x, y)
        elif "Fort" in landmark_name:
            self.draw_fort(draw, x, y)
        elif "Chimney Rock" in landmark_name:
            self.draw_chimney_rock(draw, x, y)
        elif "Rock" in landmark_name:
            # Independence Rock
            draw.ellipse([x, y+15, x+60, y+45], fill=(128, 128, 128))
            draw.ellipse([x+20, y, x+80, y+35], fill=(128, 128, 128))
            draw.text((x+25, y+20), "1847", font=self.font_small, fill=(0, 0, 0))
        elif "Pass" in landmark_name or "Mountain" in landmark_name:
            self.draw_mountains(draw, x, y)
        else:
            # Default town graphic
            draw.rectangle([x+10, y+20, x+30, y+40], fill=(139, 69, 19))
            draw.polygon([x+5, y+20, x+20, y+10, x+35, y+20], fill=(255, 0, 0))
            draw.rectangle([x+40, y+25, x+55, y+40], fill=(139, 69, 19))
            draw.polygon([x+37, y+25, x+47, y+15, x+58, y+25], fill=(255, 0, 0))

    def draw_simple_menu(self, title, options, selected):
        """Simplified menu with larger fonts"""
        image = Image.new('RGB', (240, 240), (0, 0, 0))
        draw = ImageDraw.Draw(image)
        
        # Title
        draw.text((10, 10), title, font=self.font_large, fill=(0, 255, 0))
        
        # Options with larger spacing
        y = 50
        for i, option in enumerate(options):
            color = (255, 255, 0) if i == selected else (255, 255, 255)
            prefix = ">" if i == selected else " "
            draw.text((15, y), f"{prefix} {option}", font=self.font_medium, fill=color)
            y += 25
            
        # Instructions
        draw.text((10, 210), "A=OK  B=Back", font=self.font_small, fill=(255, 255, 0))
        self.display.image(image)

    def draw_story_screen(self, title, text_lines, graphic_type=None, event_type=None):
        """Story screen with graphics and larger text"""
        image = Image.new('RGB', (240, 240), (0, 0, 0))
        draw = ImageDraw.Draw(image)
        
        # Title
        draw.text((10, 5), title, font=self.font_large, fill=(0, 255, 0))
        
        # Graphics
        if graphic_type == "wagon_scene":
            self.draw_oxen(draw, 20, 30)
            self.draw_large_wagon(draw, 50, 25)
        elif event_type:
            self.draw_event_graphic(draw, event_type, 120, 30)
        elif graphic_type:
            if graphic_type == "grave":
                self.draw_grave(draw, 100, 30)
            else:
                self.draw_landmark_graphic(draw, graphic_type, 90, 30)
            
        # Text with proper spacing
        y = 90 if (graphic_type or event_type) else 40
        for line in text_lines:
            if y > 190:
                break
            draw.text((10, y), line, font=self.font_small, fill=(255, 255, 255))
            y += 18
            
        draw.text((10, 215), "Press A to continue", font=self.font_small, fill=(255, 255, 0))
        self.display.image(image)
        
        # Wait for input
        while True:
            controls = self.read_controls_debounced()
            if controls.get('button_a') or controls.get('button_b'):
                break
            time.sleep(0.1)

    def shopping_screen(self):
        """Simplified shopping with visual feedback"""
        items = [
            {"name": "Oxen", "price": 40, "have": self.oxen},
            {"name": "Food", "price": 20, "have": self.food},
            {"name": "Bullets", "price": 10, "have": self.bullets},
            {"name": "Clothes", "price": 15, "have": self.clothes}
        ]
        selected = 0
        
        while True:
            image = Image.new('RGB', (240, 240), (0, 0, 0))
            draw = ImageDraw.Draw(image)
            
            draw.text((10, 5), "General Store", font=self.font_large, fill=(0, 255, 0))
            draw.text((10, 30), f"Money: ${self.money}", font=self.font_medium, fill=(255, 255, 0))
            
            y = 60
            for i, item in enumerate(items):
                color = (255, 255, 0) if i == selected else (255, 255, 255)
                prefix = ">" if i == selected else " "
                draw.text((15, y), f"{prefix} {item['name']}: ${item['price']}", 
                         font=self.font_medium, fill=color)
                draw.text((15, y+15), f"   Have: {item['have']}", 
                         font=self.font_small, fill=(200, 200, 200))
                y += 35
                
            draw.text((10, 195), "A=Buy  B=Done", font=self.font_small, fill=(255, 255, 0))
            draw.text((10, 210), "Need: 2 Oxen, 100 Food", font=self.font_small, fill=(255, 100, 100))
            
            self.display.image(image)
            
            controls = self.read_controls_debounced()
            if controls.get('up'):
                selected = max(0, selected - 1)
            elif controls.get('down'):
                selected = min(len(items) - 1, selected + 1)
            elif controls.get('button_a'):
                item = items[selected]
                if self.money >= item["price"]:
                    self.money -= item["price"]
                    if selected == 0:
                        self.oxen += 1
                        items[0]["have"] = self.oxen
                    elif selected == 1:
                        self.food += 50
                        items[1]["have"] = self.food
                    elif selected == 2:
                        self.bullets += 20
                        items[2]["have"] = self.bullets
                    elif selected == 3:
                        self.clothes += 1
                        items[3]["have"] = self.clothes
            elif controls.get('button_b'):
                if self.oxen >= 2 and self.food >= 100:
                    break
                else:
                    self.draw_story_screen("Not Ready!", [
                        "You need at least:",
                        "2 Oxen and 100 Food",
                        "to start your journey"
                    ])
                    
            time.sleep(0.1)

    def travel_screen(self):
        """Main travel interface with large, clear display"""
        image = Image.new('RGB', (240, 240), (0, 0, 0))
        draw = ImageDraw.Draw(image)
        
        # Date
        months = ["", "", "", "March", "April", "May", "June", "July", "August", "Sept"]
        draw.text((10, 5), f"{months[self.month]} {self.day}", font=self.font_medium, fill=(255, 255, 255))
        
        # Progress bar
        progress = min(100, int((self.miles / 2040) * 100))
        draw.rectangle([10, 25, 230, 35], outline=(255, 255, 255))
        draw.rectangle([10, 25, 10 + int(220 * progress / 100), 35], fill=(0, 255, 0))
        draw.text((10, 40), f"{self.miles}/2040 miles ({progress}%)", font=self.font_small, fill=(255, 255, 255))
        
        # Current location
        current_location = self.landmarks[self.current_landmark]["name"]
        draw.text((10, 60), f"At: {current_location}", font=self.font_medium, fill=(0, 255, 0))
        
        # Supplies - larger, clearer display
        draw.text((10, 85), f"Food: {self.food} lbs", font=self.font_medium, fill=(255, 255, 255))
        draw.text((10, 105), f"Bullets: {self.bullets}", font=self.font_medium, fill=(255, 255, 255))
        draw.text((10, 125), f"Oxen: {self.oxen}", font=self.font_medium, fill=(255, 255, 255))
        
        # Party health
        draw.text((10, 150), "Party:", font=self.font_medium, fill=(255, 255, 0))
        y = 170
        for member in self.party:
            color = (255, 0, 0) if member["sick"] else (0, 255, 0)
            status = "Sick" if member["sick"] else "Good"
            draw.text((15, y), f"{member['name']}: {status}", font=self.font_small, fill=color)
            y += 15
            
        draw.text((10, 215), "A=Continue  B=Menu", font=self.font_small, fill=(255, 255, 0))
        self.display.image(image)

    def trail_menu(self):
        """Simplified trail menu"""
        options = ["Continue", "Rest", "Hunt"]
        selected = 0
        
        while True:
            self.draw_simple_menu("What now?", options, selected)
            
            controls = self.read_controls_debounced()
            if controls.get('up'):
                selected = max(0, selected - 1)
            elif controls.get('down'):
                selected = min(len(options) - 1, selected + 1)
            elif controls.get('button_a'):
                return selected
            elif controls.get('button_b'):
                return -1
                
            time.sleep(0.1)

    def hunt_game(self):
        """Simplified hunting game with deer graphic"""
        if self.bullets < 5:
            return "Not enough bullets!", "hunting"
            
        self.draw_story_screen("Hunting", [
            "You see a deer!",
            "",
            "Press A quickly when",
            "you see 'SHOOT!'"
        ], event_type="hunting")
        
        # Wait random time
        time.sleep(random.uniform(1, 3))
        
        # Show shoot prompt
        image = Image.new('RGB', (240, 240), (0, 0, 0))
        draw = ImageDraw.Draw(image)
        draw.text((70, 100), "SHOOT!", font=self.font_large, fill=(255, 0, 0))
        self.display.image(image)
        
        # Check reaction time
        start_time = time.time()
        hit = False
        
        while time.time() - start_time < 1.5:
            controls = self.read_controls_debounced()
            if controls.get('button_a'):
                reaction_time = time.time() - start_time
                hit = reaction_time < 1.0
                break
            time.sleep(0.05)
            
        self.bullets -= 5
        
        if hit:
            meat = random.randint(20, 60)
            self.food += meat
            return f"Good shot! Got {meat} lbs meat", "good_weather"
        else:
            return "Missed! No food gained", "hunting"

    def travel_day(self):
        """Simplified daily travel with event graphics"""
        # Travel 15-25 miles per day
        daily_miles = random.randint(15, 25)
        if self.oxen < 2:
            daily_miles = int(daily_miles * 0.7)  # Slower with fewer oxen
            
        self.miles += daily_miles
        
        # Consume food
        self.food = max(0, self.food - 3)  # 3 people eat 1 lb each
        
        # Advance date
        self.day += 1
        if self.day > 30:
            self.day = 1
            self.month += 1
            
        # Random events with graphics
        if random.random() < 0.25:
            events = [
                {"text": "Wagon wheel broke!", "type": "wagon_break", "effect": "time"},
                {"text": "Ox injured and limping", "type": "ox_injury", "effect": "ox"},
                {"text": "Severe thunderstorm", "type": "storm", "effect": "time"},
                {"text": "Thief stole supplies", "type": "theft", "effect": "food"},
                {"text": "Snake bite - someone sick", "type": "snake_bite", "effect": "sick"},
                {"text": "Beautiful weather", "type": "good_weather", "effect": "bonus"},
                {"text": "River crossing ahead", "type": "river_crossing", "effect": "choice"}
            ]
            
            event = random.choice(events)
            
            # Apply event effects
            if event["effect"] == "food":
                self.food = max(0, self.food - random.randint(10, 20))
            elif event["effect"] == "ox" and self.oxen > 1:
                self.oxen -= 1
            elif event["effect"] == "sick":
                healthy = [p for p in self.party if not p["sick"]]
                if healthy:
                    random.choice(healthy)["sick"] = True
            elif event["effect"] == "bonus":
                self.miles += 10
            elif event["effect"] == "time":
                self.miles = max(0, self.miles - 10)
                
            return event["text"], event["type"]
            
        return None, None

    def check_landmarks(self):
        """Check for landmark arrivals with graphics"""
        for i, landmark in enumerate(self.landmarks):
            if (self.miles >= landmark["miles"] and 
                i > self.current_landmark and 
                landmark["miles"] > 0):
                self.current_landmark = i
                
                self.draw_story_screen(
                    "Landmark!",
                    [f"You have reached", landmark["name"], "", 
                     f"Miles traveled: {self.miles}"],
                    graphic_type=landmark["name"]
                )
                return True
        return False

    def run(self):
        game_state = "intro"
        
        while True:
            controls = self.read_controls_debounced()
            
            if controls.get('button_b') and game_state == "intro":
                return
                
            if game_state == "intro":
                self.draw_story_screen("The Oregon Trail", [
                    "It is 1847. You are a pioneer",
                    "heading west to Oregon City.",
                    "",
                    "You must travel 2040 miles",
                    "across dangerous frontier.",
                    "",
                    "Buy supplies, manage resources,",
                    "and survive the journey!",
                    "",
                    "Good luck, pioneer!"
                ], graphic_type="wagon_scene")
                
                game_state = "shopping"
                
            elif game_state == "shopping":
                self.shopping_screen()
                game_state = "traveling"
                
            elif game_state == "traveling":
                # Check win condition
                if self.miles >= 2040:
                    game_state = "win"
                    continue
                    
                # Check lose conditions
                alive_count = sum(1 for p in self.party if not p["sick"])
                if alive_count == 0:
                    game_state = "lose_sickness"
                    continue
                elif self.food <= 0:
                    game_state = "lose_starvation"
                    continue
                    
                # Show travel screen
                self.travel_screen()
                
                # Wait for input
                while True:
                    controls = self.read_controls_debounced()
                    if controls.get('button_a'):
                        break
                    elif controls.get('button_b'):
                        choice = self.trail_menu()
                        if choice == 0:  # Continue
                            break
                        elif choice == 1:  # Rest
                            self.draw_story_screen("Resting", ["Your party rests for 2 days"], 
                                                 event_type="good_weather")
                            self.day += 2
                            # Chance to recover
                            for member in self.party:
                                if member["sick"] and random.random() < 0.5:
                                    member["sick"] = False
                        elif choice == 2:  # Hunt
                            result, graphic = self.hunt_game()
                            self.draw_story_screen("Hunt Result", [result], event_type=graphic)
                        elif choice == -1:  # Back
                            break
                    time.sleep(0.1)
                
                # Travel for the day
                event, event_type = self.travel_day()
                if event:
                    self.draw_story_screen("Trail Event", [event], event_type=event_type)
                    
                # Check landmarks
                self.check_landmarks()
                
            elif game_state == "win":
                alive_count = sum(1 for p in self.party if not p["sick"])
                score = alive_count * 200 + self.food + self.bullets
                
                self.draw_story_screen("Success!", [
                    "You made it to Oregon City!",
                    "",
                    f"Final score: {score}",
                    f"Food left: {self.food} lbs",
                    f"Bullets left: {self.bullets}",
                    "",
                    "A=Play Again  B=Menu"
                ], graphic_type="wagon_scene")
                
                while True:
                    controls = self.read_controls_debounced()
                    if controls.get('button_a'):
                        self.reset_game()
                        game_state = "shopping"
                        break
                    elif controls.get('button_b'):
                        return
                    time.sleep(0.1)
                    
            elif game_state.startswith("lose"):
                if game_state == "lose_sickness":
                    message = [
                        "Your entire party has died",
                        "of dysentery and disease.",
                        "",
                        f"You traveled {self.miles} miles",
                        "out of 2040 total.",
                        "",
                        "A=Try Again  B=Menu"
                    ]
                else:  # lose_starvation
                    message = [
                        "Your party has starved",
                        "on the Oregon Trail.",
                        "",
                        f"You traveled {self.miles} miles",
                        "out of 2040 total.",
                        "",
                        "A=Try Again  B=Menu"
                    ]
                
                self.draw_story_screen("You Have Died", message, graphic_type="grave")
                
                while True:
                    controls = self.read_controls_debounced()
                    if controls.get('button_a'):
                        self.reset_game()
                        game_state = "shopping"
                        break
                    elif controls.get('button_b'):
                        return
                    time.sleep(0.1)
                    
            time.sleep(0.1)
