# Code for the non-GUI RoutePlanner
#
# Copyright (C) 1996-2001 Chris Lawrence
# This file may be freely distributed under the terms of the RoutePlanner
# license.  A copy should appear as 'LICENSE' in the archive that this
# file was included in.

import rpdbase, string, sys, os, rpunits

# If readline works, import it; else, don't worry about it
try:
    import readline
except:
    pass

def ChooseCity(prompt, db):
    while 1:
        cities = []
        while not cities:
            try:
                stuff = raw_input(prompt+'\n> ')
            except EOFError:
                return None

            if not stuff:
                return None
            cities = db.CitiesMatching(stuff)
            if not cities:
                print 'No cities matching '+stuff
                
            if len(cities) == 1:
                return cities[0]
            
            while cities:
                count = 1
                for city in cities:
                    print '%2d: %s' % (count, city)
                    count = count + 1
                    if count > 15:
                        print '(More...)'
                        break
                try:
                    stuff = raw_input('Choose a city (by number or name)\n> ')
                except EOFError:
                    return None
                if not stuff:
                    return None
                
                try:
                    num = int(stuff)
                except:
                    num = 0

                if 0 < num < count:
                    return cities[num-1]
                elif num:
                    print 'Invalid choice (must be between 1 and %d).' % \
                          (count - 1)
                    continue
                else:
                    cities = db.CitiesMatching(stuff)
                    if not cities:
                        print 'No cities matching '+stuff
                        continue
                    elif len(cities) == 1:
                        return cities[0]
# End of ChooseCity

def NicerTime(min):
    return '%2d:%02d' % (min / 60, min % 60)

def mainloop(database='Basic-USA.rpl3.gz'):
    print rpdbase.VERSION
    print rpdbase.COPYRIGHT
    
    units = rpdbase.UNITS_METRIC
    if database and not os.path.exists(database):
        database = '/usr/pkg/lib/routeplanner/'+database
        
    if database:
        print 'Loading database '+database+'...',
        db = rpdbase.RPDatabase(database)
        units = db.units
    else:
        print 'No database specified.'
        return 1
    print '%d cities, %d routes' % (len(db.cities), len(db.routes))
    print 'Created by %s <%s>' % (db.author, db.author_email)
    print
    
    while 1:
        city = ChooseCity('Please enter the name of the city you want '
                          'to start at:', db)
        if not city:
            return 1
        print 'Selected: '+str(city)
        
        path = [city]
        while city:
            city = ChooseCity('Enter destination for next leg (or an empty '
                              'destination to plan route):', db)
            if city:
                print 'Selected: '+str(city)
                path.append(city)
        
        if len(path) < 2:
            print 'You really need to specify two or more cities.'
            continue

        method = 0
        while method == 0:
            print 'Choose routing method:'
            for i in range(len(rpdbase.methods)):
                print '%2d: %s' % (i+1, rpdbase.methods[i])

            junk = raw_input('> ')
            try:
                method = int(junk)
            except:
                pass
            if not (1 <= method <= len(rpdbase.methods)):
                method = 0
        
        method = method - 1
        print 'Planning route ('+rpdbase.methods[method]+'):'
        for entry in path:
            print '  '+str(entry)

        try:
            import timing
        except ImportError:
            timing = None
        print "Running new Navigate()...",
        sys.stdout.flush()
        trail = []
        if timing:
            timing.start()
            for i in range(len(path)-1):
                trail.append( db.NewNavigate(path[i], path[i+1],
                                             method=method) )
            timing.finish()
            print "done in %d ms." % timing.milli()
        else:
            for i in range(len(path)-1):
                trail.append( db.NewNavigate(path[i], path[i+1],
                                             method=method) )
            print "done."
        
        mpgs = rpdbase.defeff
        defmpg = rpdbase.defmpg
        speeds = rpdbase.defspeed
        if units != rpunits.UNITS_US:
            defmpg = rpunits.ConvertEfficiency(defmpg, rpunits.UNITS_US, units)
            mpgs = map(rpunits.ConvertEfficiency, mpgs,
                       rpunits.UNITS_US, units)
            speeds = map(lambda x, y=units: rpunits.Distance(x).AsUnit(y),
                         speeds)

        displist = rpdbase.ProduceTrail(trail, db, units, mpgs, defmpg, speeds)
        print rpdbase.FormatRoute(displist, path, units)
        # We is done

    # End of while
# End of mainloop
