#!/usr/bin/python

# Metarace : Cycle Race Abstractions
# Copyright (C) 2012  Nathan Fraser
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Convenience program to build stage race intermediates
#
# Add a file called 'stagedata.csv' to the event directory. 
# File should contain lines as follows:

#
# id, type, descr, cat
#
# Where type is one of:
#
# scody			scody cup stage points
# scstart		scody cup start points
# scfin			scody cup finish points
# crit			criterium championship
# bon			stage bonus
# aggr			aggressor
# sprint		intermediate sprint	*
# climb			intermediate climb	**
#
# Other fields are ignored except for sprint and climb.
#
# sprint examples:
#
# 22, sprint, ,			for crits: 'Lap 22 sprint'
# 44, sprint, Merbien PS,	for RR: 'm44 Merbien PS Sprint'
# m58, sprint, M58 Crossroad, 	Manual override on id and comment
#
# climb examples:
#
# 17, climb, ,			'Lap 17 climb HC4'
# 20, climb, Johnson St,2	m20 cat 2: 'm20 Johnson St HC2'
# m33, climb, Jake St, 1	manual, with cat 1: 'Jake St'
#
import os
import sys
import csv
import ConfigParser

import metarace
from metarace import roadmeet
from metarace import tod

CATPTS={ 1 : [10, 6, 4],
         2 : [7, 5, 3],
         3 : [5, 3, 2],
         4 : [3, 2, 1],
         'sprint': [3, 2, 1],
         'crit': [10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
         'scody': [10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
         'scstart': [2],
         'scfin': [3],
         'bon': [10, 8, 6, 4, 2, 1],
         'aggr':[2],
  }
CATBON={}
for c in CATPTS:
    bvec = []
    for p in CATPTS[c]:
        bvec.append(tod.tod(p))
    CATBON[c] = bvec

def main():
    """Run the stage build application."""
    configpath = None

    # expand configpath on cmd line to realpath _before_ doing chdir
    if len(sys.argv) > 2:
        print('usage: stagebuild [configdir]\n')
        sys.exit(1)
    elif len(sys.argv) == 2:
        rdir = sys.argv[1]
        if not os.path.isdir(rdir):
            rdir = os.path.dirname(rdir)
        configpath = os.path.realpath(rdir)

    metarace.init()
    app = roadmeet.roadmeet(configpath)
    app.loadconfig()
    if app.curevent is not None:
        evt = app.curevent
        print('Opened Event: ' + app.title_str)
        stagefile = os.path.join(app.configpath, 'stagedata.csv')
        if os.path.isfile(stagefile):
            with open(stagefile, 'rb') as f:
                cr = csv.reader(f)
                for r in cr: 
                    if len(r) > 2 and r[0].lower() != 'id':
                        if r[1] == 'crit':
                            # add a criterium contest and tally
                            print('Adding Criterium...')
                            if 'crit' not in evt.contests:
                                print('\tContest.')
                                evt.contests.append('crit')
                                evt.contestmap['crit'] = {
                                       'tally':'crit', 'source':'fin',
                                       'bonuses':[],
                                       'points':CATPTS['crit'],
                                       'all_source':False}
                            if 'crit' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('crit')
                                evt.tallymap['crit'] = {
                                        'descr':'Criterium Championship',
                                        'keepdnf':False}
                        elif r[1] == 'aggr':
                            # Add aggressor
                            print('Adding aggressor...')
                            if 'aggr' not in evt.intermeds:
                                print('\tIntermediate.')
                                evt.intermeds.append('aggr')
                                evt.intermap['aggr'] = {
                                           'descr':'Aggressor', 'places':''}
                            if 'aggr' not in evt.contests:
                                print('\tContest.')
                                evt.contests.append('aggr')
                                evt.contestmap['aggr'] = {
                                           'tally':'aggr', 'source':'aggr',
                                           'bonuses':[],
                                           'points':CATPTS['aggr'],
                                           'all_source':True}
                            if 'aggr' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('aggr')
                                evt.tallymap['aggr'] = {
                                      'descr':'Most Aggressive Rider',
                                      'keepdnf':True}
                        elif r[1] == 'scody':
                            # Add scody cup
                            print('Adding Scody Cup pts...')
                            if 'scody' not in evt.contests:
                                print('\tContest.')
                                evt.contests.append('scody')
                                evt.contestmap['scody'] = {
                                       'tally':'scody', 'source':'fin',
                                       'bonuses':[],
                                       'points':CATPTS['scody'],
                                       'all_source':False}
                            if 'scody' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('scody')
                                evt.tallymap['scody'] = {'descr':'Scody Cup',
                                                        'keepdnf':True}
                        elif r[1] == 'bon':
                            # Add stage bonus
                            print('Adding stage bonus...')
                            if 'bon' not in evt.contests:
                                print('\tContest.')
                                evt.contests.append('bon')
                                evt.contestmap['bon'] = {
                                           'tally':'', 'source':'fin',
                                           'bonuses':CATBON['bon'],
                                           'points':[],
                                           'all_source':False}
                        elif r[1] == 'scstart':
                            # add a scody cup start allocation
                            print('Adding Scody cup start points...')
                            if 'scody' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('scody')
                                evt.tallymap['scody'] = {'descr':'Scody Cup',
                                                        'keepdnf':True}
                            if 'scstart' not in evt.contests:
                                print('\tContest.')
                                evt.contests.append('scstart')
                                evt.contestmap['scstart'] = {
                                    'tally':'scody', 'source':'start',
                                           'bonuses':[],
                                           'points':CATPTS['scstart'],
                                           'all_source':True}
                        elif r[1] == 'scfin':
                            # add a scody cup finish allocation
                            print('Adding Scody cup finish points...')
                            if 'scody' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('scody')
                                evt.tallymap['scody'] = {'descr':'Scody Cup',
                                                        'keepdnf':True}
                            if 'scfin' not in evt.contests:
                                print('\tContest.')
                                evt.contests.append('scfin')
                                evt.contestmap['scfin'] = {
                                    'tally':'scody', 'source':'fin',
                                           'bonuses':[],
                                           'points':CATPTS['scfin'],
                                           'all_source':True}
                        elif r[1] == 'sprint':
                            print('Adding intermediate sprint...')
                            # check for sprint tally, then add contest/int
                            if 'sprint' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('sprint')
                                evt.tallymap['sprint'] = {
                                        'descr':'Sprint Championship',
                                        'keepdnf':False}
                            sid = r[0]
                            stxt = r[2].strip()
                            if sid.isdigit():
                                if stxt == '':
                                    # assume lap
                                    stxt = 'Lap ' + sid + ' Sprint'
                                    #stxt = 'Sprint at ' + sid + ' to go'
                                else:
                                    # assume mocka
                                    stxt = 'm' + sid + ' ' + stxt + ' Sprint'
                                sid = 's' + sid
                            if sid not in evt.intermeds:
                                print('\tIntermediate.')
                                evt.intermeds.append(sid)
                                evt.intermap[sid] = {
                                    'descr':stxt, 'places':''}
                            if sid not in evt.contests:
                                print('\tContest.')
                                evt.contests.append(sid)
                                evt.contestmap[sid] = {
                                          'tally':'sprint', 'source':sid,
                                          'bonuses':CATBON['sprint'],
                                          'points':CATPTS['sprint'],
                                          'all_source':False}
                        elif r[1] == 'climb':
                            # check for climb tally, then add contest/int
                            print('Adding hill climb...')
                            if 'climb' not in evt.tallys:
                                print('\tTally.')
                                evt.tallys.append('climb')
                                evt.tallymap['climb'] = {
                                        'descr':'Hill Climb Championship',
                                        'keepdnf':False}
                            sid = r[0]
                            stxt = r[2].strip()
                            scatno = 4	# default cat4
                            scat = r[3]
                            if scat.isdigit():
                                scatno = int(scat)
                                if scatno not in CATPTS:
                                    scatno = 4
                                    print('WARNING: Invalid HC ingnored.')
                            if sid.isdigit():
                                if stxt == '':
                                    # assume lap
                                    # stxt = 'Lap ' + sid + ' HC'+ str(scatno)
                                    stxt = 'Lap ' + sid + ' Climb' #+str(scatno)
                                else:
                                    # assume mocka
                                    stxt = 'm' + sid + ' ' + stxt + ' HC'+ str(scatno)
                                sid = 'h' + sid
                            if sid not in evt.intermeds:
                                print('\tIntermediate.')
                                evt.intermeds.append(sid)
                                evt.intermap[sid] = {
                                    'descr':stxt, 'places':''}
                            if sid not in evt.contests:
                                print('\tContest.')
                                evt.contests.append(sid)
                                evt.contestmap[sid] = {
                                          'tally':'climb', 'source':sid,
                                          'bonuses':CATBON[scatno],
                                          'points':CATPTS[scatno],
                                          'all_source':False}
            print('Saving event data.')
            app.saveconfig()
        else:
            print ('No stage data to load.')
    app.shutdown()

if __name__ == '__main__':
    main()
