#!/usr/bin/python
# coding: utf-8

"""Autopia
   Copyright (c) 2016-2018 Nick Montfort
   Python 2 version, autopia.py, 20 September 2016
   Python 2/3 version, autopia.py, 28 July 2018

Copying and distribution of this file, with or without modification, are
permitted in any medium without royalty provided the copyright notice and this
notice are preserved. This file is offered as-is, without any warranty."""

from random import choice, random
from time import sleep
import re

# A distribution of templates is defined in 'intransitive' and 'transitive'
# Very rare actions/cars are less frequent, no multiplier (equivalent to * 1)
# More usual actions/cars, but still not the most common, get * 2
# Common actions/cars are frequent; e.g., PERSON Golf_s gets * 3

intransitive = \
    [u'EITHER Aspire_s'] * 2 + \
    [u'PLACE Avalanche_s'] + \
    [u'ESCAPABLE Bolt_s'] + \
    [u'PERSON Caravan_s'] * 2 + \
    [u'ANIMATE Dart_s'] * 2 + \
    [u'ESCAPABLE Escape_s'] * 2 + \
    [u'EITHER Excel_s'] + \
    [u'PERSON Golf_s'] * 3 + \
    [u'PERSON Focus_es'] * 3 + \
    [u'NOVABLE Nova_s'] + \
    [u'PERSON Quest_s'] * 2 + \
    [u'EITHER Rabbit_s'] + \
    [u'PERSON Rally_@ies'] * 2 + \
    [u'EITHER Rampage_s'] * 2 + \
    [u'EITHER Sprint_s'] + \
    [u'PERSON Safari_s'] + \
    [u'EITHER Summit_s'] + \
    [u'PERSON Venture_s']

transitive = \
    [u'PERSON Acclaim_s PERSON'] * 3 + \
    [u'PERSON Accent_s EITHER'] * 2 + \
    [u'PERSONS Club Wagon'] + \
    [u'NONMALE Cougar_s PERSON'] + \
    [u'ENTRANT Courier_s Passport'] + \
    [u'PERSON Dodge_s WEAPON'] * 3 + \
    [u'PERSON Echo_es TEXT'] + \
    [u'EITHER Eclipse_s EITHER'] + \
    [u'PERSON Escort_s PERSON'] * 3 + \
    [u'PERSON Esteem_s PERSON'] * 2 + \
    [u'TEXT Express_es PERSON'] + \
    [u'POINTS Fit Matrix Axiom'] + \
    [u'PERSON Focus_es POINTER'] * 2 + \
    [u'PERSON Ford_s Rio'] + \
    [u'PERSON Laser_s LASERABLE'] * 2 + \
    [u'PERSON Intrigue_s PERSON'] + \
    [u'PERSON Pilot_s VEHICLE'] * 2 + \
    [u'PERSON Probe_s PERSON'] * 2 + \
    [u'EITHER Ram_s EITHER'] * 3 + \
    [u'PERSONS Rendezvous'] * 2 + \
    [u'PERSON Shadow_s PERSON'] + \
    [u'PERSON Spark_s SPARKABLE'] + \
    [u'PERSON Storm_s PLACE'] + \
    [u'PERSON Vibe_s PERSON']

template = intransitive + transitive

parts = { # All names are uniformly distributed/equally likely
# Adjectives
    u'ADJ' : [u'Azure', u'Cavalier', u'Civic', u'Continental', u'Graduate',
    u'Imperial', u'Intrepid', u'Neon', u'Noble', u'Phantom', u'Premier',
    u'Regal', u'Reliant', u'Sable', u'Sienna', u'Smart', u'Suburban', u'Superb',
    u'Swift'],

# Names for people, by profession or otherwise, either gender-neutral or female
    u'NONMALE' : [u'Avenger_s', u'Aviator_s', u'Brat_s', u'Challenger_s',
    u'Champ_s', u'Cherokee_s', u'Comanche_s', u'Cooper_s', u'Cougar_s',
    u'Courier_s', u'Dakota_s', u'Dasher_s', u'Defender_s', u'Diplomat_s',
    u'Envoy_s', u'Escort_s', u'Explorer_s', u'Forester_s', u'Freelander_s',
    u'Graduate_s', u'Grand Cherokee_s', u'Highlander_s', u'Lancer_s',
    u'Mountaineer_s', u'Navajo_s', u'Navigator_s', u'New Yorker_s',
    u'Pacer_s', u'Pathfinder_s', u'Pilot_s', u'Prefect_s', u'Prowler_s',
    u'Raider_s', u'Ranger_s', u'Rebel_s', u'Roadmaster_s', u'Scion_s',
    u'Sidekick_s', u'Starlet_s', u'Tracker_s', u'Trooper_s', u'Uplander_s',
    u'Villager_s', u'Voyager_s', u'Wrangler_s'],

# Names for people indicating males only
    u'MALE' : [u'Amigo_s', u'Caballero_s', u'Hombre_s', u'Jimmy_s',
    u'Marquis_es', u'Matador_s', u'Protégé_s'],

# Non-human animals, mobile/intentional things, including some abstractions
    u'ANIMATE' : [u'Beetle_s', u'Bronco_s', u'Charger_s', u'Colt_s',
    u'Conquest_s', u'Diablo_s', u'Eagle_s', u'Falcon_s', u'Firebird_s',
    u'Fox_es', u'Gremlin_s', u'Hornet_s', u'Impala_s', u'Kitten_s', u'Lynx_es',
    u'Mustang_s', u'Phoenix_es', u'Pinto_s', u'Rabbit_s', u'Ram_s', u'Robin_s',
    u'Shadow_s', u'Silhouette_s', u'Skyhawk_s', u'Skylark_s', u'Spider_s',
    u'Spirit_s', u'Sunbird_s', u'Taurus_es', u'Thunderbird_s', u'Titan_s',
    u'Viper_s'],

# People (singular) who sound like they may be entering a country
    u'ENTRANT' : [u'Diplomat', u'Envoy', u'Voyager'],

# Things that could possibly go nova
    u'NOVABLE' : [u'Sunbird_s', u'Windstar_s'],

# Sets of points (plural)
    u'POINTS' : [u'Contours', u'Maxima', u'Optima', u'Vectors'],

# Place names (proper, singular)
    u'PLACE' : [u'Aspen', u'Austin', u'Avalon', u'Baja', u'Colorado',
    u'Fairmont', u'Fifth Avenue', u'Monaco', u'Newport', u'Plymouth',
    u'Riviera', u'Sierra', u'Silverado', u'Sonoma', u'Tacoma', u'Tahoe',
    u'Tundra', u'Yukon'],

# Different sorts of texts or writings (singular)
    u'TEXT': [u'Axiom', u'Citation', u'Odyssey', u'Legend', u'Passport',
    u'Prelude', u'Sonata', u'Stanza'],

# Things which could be sparked (singular)
    u'SPARKABLE': [u'Encore', u'Firebird', u'Intrigue', u'Nova', u'Vision'],

# Vehicles, or in one case a group of vehicles
    u'VEHICLE' : [u'Armada_s', u'Caravan_s', u'Concord_s', u'Corvette_s',
    u'Cruiser_s'],

# Weapons and weapon-like things
    u'WEAPON' : [u'Arrow_s', u'Beretta_s', u'Cutlass_es', u'Dart_s', u'Edge_s',
    u'Javelin_s', u'Laser_s', u'Probe_s', u'Scimitar_s']
}

# All people, regardless of gender
parts[u'PERSON'] = parts[u'NONMALE'] + parts[u'MALE']

# Plural form only of people
parts[u'PERSONS'] = [p.replace('_', '') for p in parts[u'PERSON']]

# Either a person or a different animate entity
parts[u'EITHER'] = parts[u'PERSON'] + parts[u'ANIMATE']

# Things that can escape include EITHER and a few others
parts[u'ESCAPABLE'] = parts[u'EITHER'] + [u'Proton_s'] + [u'Liberty_@ies']

# Things that can be pointed include weapons and a compass
parts[u'POINTER'] = parts[u'WEAPON'] + [u'Compass_es']

# Things that can be lasered; almost anything including the horizon
parts[u'LASERABLE'] = parts[u'EITHER'] + parts[u'PLACE'] + parts[u'POINTER'] + \
    [u'Horizon', u'Lotus']

columns = 80

print(u'-' * columns)
while True:
    if random() < .3:
        print(u'-' * columns)
    phrase = choice(template)
    for slot in parts:
        if slot in phrase and phrase.index(slot) == 0:
            adjective = choice([choice(parts[u'ADJ']) + u' ', u''])
            np = adjective + choice(parts[slot])
            number = u'SINGULAR'
            if u'_' in np:
                number = choice([u'SINGULAR', u'PLURAL'])
            if number == u'SINGULAR':
                np = np.split(u'_')[0]
                phrase = u''.join(phrase.split(u'_'))
            else:
                np = u''.join(np.split(u'_'))
                phrase = re.sub(r'_\S+', u'', phrase)
            phrase = phrase.replace(slot, np, 1)
        if slot in phrase:
            adjective = choice([choice(parts[u'ADJ']) + u' ', u'', u''])
            np = adjective + choice(parts[slot])
            if choice([u'SINGULAR', u'PLURAL']) == u'SINGULAR':
                np = np.split(u'_')[0]
            else:
                np = u''.join(np.split(u'_'))
            phrase = phrase.replace(slot, np, 1)
    phrase = re.sub(u'.@', u'', phrase).strip().upper()
    before = int((columns - len(phrase) - 1) * random()) + 1
    line = (u'-' * before) + phrase + (u'-' * (columns - before - len(phrase)))
    print(line)
#    sleep(.65)
