import random

def generate_song_title():
    adjectives = [
        # Colors & Light
        "gentle", "quiet", "distant", "silver", "golden", "crystal",
        "velvet", "misty", "serene", "tender", "whispered", "floating",
        "dreamy", "soft", "mellow", "tranquil", "peaceful", "calm",
        "ethereal", "delicate", "subtle", "graceful", "luminous", "pale",
        "amber", "ivory", "pearl", "opal", "sapphire", "emerald",
        "crimson", "violet", "indigo", "turquoise", "copper", "bronze",
        
        # Textures & Feelings
        "smooth", "silken", "feathered", "quilted", "woven", "polished",
        "hushed", "muted", "gentle", "soothing", "warming", "cooling",
        "flowing", "rippling", "swaying", "drifting", "gliding", "soaring",
        "nestled", "cradled", "embraced", "sheltered", "protected", "safe",
        
        # Time & Space
        "eternal", "infinite", "boundless", "fleeting", "passing", "lingering",
        "distant", "nearby", "faraway", "close", "approaching", "departing",
        "ascending", "descending", "circling", "spiraling", "meandering", "wandering",
        
        # Nature-inspired
        "dewy", "misty", "foggy", "cloudy", "sunny", "moonlit",
        "starlit", "shadowed", "dappled", "filtered", "reflected", "mirrored",
        "blooming", "budding", "unfurling", "opening", "closing", "resting"
    ]
    
    nouns = [
        # Time periods
        "morning", "evening", "shadow", "light", "rain", "cloud",
        "river", "ocean", "mountain", "valley", "garden", "meadow",
        "breeze", "dawn", "dusk", "star", "moon", "sky",
        "reflection", "echo", "memory", "dream", "moment", "silence",
        "afternoon", "midnight", "twilight", "daybreak", "nightfall", "sunrise",
        "sunset", "moonrise", "starlight", "candlelight", "firelight", "lamplight",
        
        # Natural elements
        "mist", "fog", "dew", "frost", "snow", "ice",
        "stone", "pebble", "sand", "dust", "ash", "ember",
        "leaf", "petal", "bloom", "blossom", "branch", "root",
        "wave", "tide", "current", "stream", "brook", "pond",
        "hill", "cliff", "shore", "beach", "cove", "bay",
        
        # Abstract concepts
        "thought", "feeling", "notion", "idea", "sense", "touch",
        "whisper", "murmur", "sigh", "breath", "pause", "rest",
        "journey", "passage", "crossing", "bridge", "threshold", "doorway",
        "window", "mirror", "veil", "curtain", "screen", "shade",
        
        # Places & Spaces
        "chamber", "room", "hall", "corridor", "path", "trail",
        "forest", "grove", "glade", "clearing", "hollow", "dell",
        "field", "plain", "prairie", "steppe", "tundra", "desert",
        "island", "peninsula", "archipelago", "lagoon", "reef", "atoll"
    ]
    
    modifiers = [
        "endless", "forgotten", "hidden", "ancient", "timeless", "sacred",
        "wandering", "dancing", "sleeping", "waking", "drifting", "fading",
        "rising", "falling", "turning", "spinning", "floating", "sinking",
        "growing", "shrinking", "expanding", "contracting", "pulsing", "breathing",
        "whispering", "singing", "humming", "sighing", "calling", "beckoning",
        "glowing", "dimming", "flickering", "shimmering", "sparkling", "gleaming"
    ]
    
    connectors = [
        "of", "in", "on", "by", "for", "with", "under", "over",
        "through", "between", "among", "within", "without", "beneath",
        "above", "across", "along", "around", "behind", "before"
    ]
    
    articles_no_an = ["the", "this", "that", "my", "your", "our"]
    
    def get_article(word):
        """Return 'a' or 'an' based on the starting sound of the word"""
        vowel_sounds = ['a', 'e', 'i', 'o', 'u']
        word_lower = word.lower()
        
        # Handle special cases where spelling doesn't match sound
        # Silent H words (use 'an')
        if word_lower in ['hour', 'honest', 'honor', 'heir', 'hourly', 'honesty']:
            return 'an'
        # Words starting with 'u' that sound like 'yu' (use 'a')
        elif word_lower in ['one', 'once', 'uniform', 'university', 'unique', 'union', 'unit', 'united', 'universal', 'unicorn']:
            return 'a'
        # Words starting with vowels but consonant sounds
        elif word_lower.startswith('eu') and word_lower in ['european', 'eucalyptus', 'euphemism']:
            return 'a'
        # Check if it starts with a vowel sound
        elif word[0].lower() in vowel_sounds:
            return 'an'
        else:
            return 'a'
    
    def choose_article_for(word):
        """Choose an article, handling a/an correctly"""
        if random.random() < 0.3:  # 30% chance of a/an
            return get_article(word)
        else:
            return random.choice(articles_no_an)
    
    # Note: Using walrus operator (:=) to capture the word before applying article selection
    # This ensures the article matches the word that follows it
    patterns = [
        # Simple patterns
        lambda: f"{random.choice(adjectives)} {random.choice(nouns)}",
        lambda: (adj := random.choice(adjectives), f"{choose_article_for(adj)} {adj} {random.choice(nouns)}")[1],
        lambda: f"{random.choice(modifiers)} {random.choice(nouns)}",
        
        # Compound patterns
        lambda: f"{random.choice(nouns)} {random.choice(connectors)} {random.choice(nouns)}",
        lambda: (noun := random.choice(nouns), adj := random.choice(adjectives), f"{choose_article_for(noun)} {noun} {random.choice(connectors)} {adj} {random.choice(nouns)}")[2],
        lambda: f"{random.choice(adjectives)} {random.choice(nouns)} {random.choice(connectors)} {random.choice(nouns)}",
        
        # Possessive patterns
        lambda: (adj := random.choice(adjectives), f"{choose_article_for(adj)} {adj} {random.choice(nouns)}'s {random.choice(nouns)}")[1],
        lambda: f"{random.choice(nouns)}'s {random.choice(adjectives)} {random.choice(nouns)}",
        
        # Complex patterns
        lambda: (adj := random.choice(adjectives), f"{random.choice(connectors)} {choose_article_for(adj)} {adj} {random.choice(nouns)}")[1],
        lambda: f"{random.choice(modifiers)} {random.choice(nouns)} {random.choice(connectors)} {random.choice(adjectives)} {random.choice(nouns)}",
        lambda: (noun := random.choice(nouns), modifier := random.choice(modifiers), f"{choose_article_for(noun)} {noun} {random.choice(connectors)} {modifier} {random.choice(nouns)}")[2],
        
        # Poetic patterns
        lambda: f"when {random.choice(nouns)} {random.choice(modifiers)}",
        lambda: f"where {random.choice(adjectives)} {random.choice(nouns)} {random.choice(modifiers)}",
        lambda: (noun := random.choice(nouns), f"as {choose_article_for(noun)} {noun} {random.choice(modifiers)}")[1],
        
        # Number patterns (for even more variety)
        lambda: f"{random.choice(['one', 'two', 'three', 'seven', 'twelve', 'hundred', 'thousand'])} {random.choice(adjectives)} {random.choice(nouns)}",
        lambda: f"{random.choice(nouns)} {random.choice(['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'])}",
        
        # Time-based patterns
        lambda: f"{random.choice(['first', 'last', 'next', 'final', 'eternal'])} {random.choice(nouns)}",
        lambda: (adj := random.choice(adjectives), f"{random.choice(['before', 'after', 'during', 'beyond'])} {choose_article_for(adj)} {adj} {random.choice(nouns)}")[1],
        
        # Double adjective patterns
        lambda: f"{random.choice(adjectives)}, {random.choice(adjectives)} {random.choice(nouns)}",
        lambda: (adj1 := random.choice(adjectives), adj2 := random.choice(adjectives), f"{choose_article_for(adj1)} {adj1} and {adj2} {random.choice(nouns)}")[2]
    ]
    
    def proper_title_case(text):
        """Apply proper title case rules"""
        # Words that should remain lowercase (unless first or last)
        lowercase_words = {
            'a', 'an', 'and', 'as', 'at', 'but', 'by', 'for', 'from',
            'in', 'into', 'nor', 'of', 'on', 'or', 'out', 'over', 'so',
            'the', 'to', 'up', 'with', 'yet', 'under', 'above', 'across',
            'after', 'along', 'among', 'around', 'before', 'behind',
            'beneath', 'between', 'beyond', 'during', 'through', 'throughout',
            'within', 'without'
        }
        
        words = text.split()
        result = []
        
        for i, word in enumerate(words):
            # Handle possessives
            if "'" in word:
                parts = word.split("'")
                parts[0] = parts[0].capitalize()
                word = "'".join(parts)
                result.append(word)
            # First or last word is always capitalized
            elif i == 0 or i == len(words) - 1:
                result.append(word.capitalize())
            # Check if it should be lowercase
            elif word.lower() in lowercase_words:
                result.append(word.lower())
            # Otherwise capitalize
            else:
                result.append(word.capitalize())
        
        return ' '.join(result)
    
    # Generate the title
    title = random.choice(patterns)()
    return proper_title_case(title)

# Example usage
if __name__ == "__main__":
    print("=== 50 Anodyne Song Titles ===\n")
    for i in range(50):
        print(f"{i+1:2d}. {generate_song_title()}")