from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from __future__ import unicode_literals, absolute_import
from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from rowers.models import (
    Workout,Rower,Team,PlannedSession,GeoCourse,
    VirtualRace,VirtualRaceResult,IndoorVirtualRaceResult,
    PaidPlan
    )
from rowers.rows import validate_file_extension,must_be_csv,validate_image_extension,validate_kml
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.admin.widgets import AdminDateWidget
from django.forms.widgets import SelectDateWidget
#from django.forms.extras.widgets import SelectDateWidget
from django.utils import timezone,translation
from django.forms import ModelForm, Select
import rowers.dataprep as dataprep
import rowers.mytypes as mytypes
import datetime
from django.forms import formset_factory
from rowers.utils import landingpages
from rowers.metrics import axes, metricsgroups,rowingmetrics
from rowers.metrics import axlabels
from rowers.rower_rules import user_is_not_basic

formaxlabels = axlabels.copy()
formaxlabels.pop('None')
parchoices = list(sorted(formaxlabels.items(), key = lambda x:x[1]))

class SurveyForm(forms.Form):
    surveydone = forms.ChoiceField(
        required=True,
        choices=(('YES','YES'),('NO','NO')),
        label='Will you take a 2 minute survey to help improve rowsandall?',
        widget = forms.RadioSelect)

class FlexibleDecimalField(forms.DecimalField):

    def to_python(self, value):
        # check decimal symbol
        comma_index = 0
        dot_index = 0
        try:
            comma_index = value.index(',')
        except ValueError:
            pass
        try:
            dot_index = value.index('.')
        except ValueError:
            pass
        if value:
            if comma_index > dot_index:
                value = value.replace('.', '').replace(',', '.')
        return super(FlexibleDecimalField, self).to_python(value)

# Video Analysis creation form
class VideoAnalysisCreateForm(forms.Form):
    name = forms.CharField(max_length=255,label='Analysis Name',required=False)
    url = forms.CharField(max_length=255,required=True,label='YouTube Video URL')
    delay = forms.IntegerField(initial=0,label='Delay (seconds)')

def get_metricschoices(mode='water'):
    modes = [mode,'both','basic']
    metricsdescriptions = {}
    for m in metricsgroups:
        metricsdescriptions[m] = m+' ('
        for name,d in rowingmetrics:
            if d['group']==m and d['mode'] in modes:
                metricsdescriptions[m]+=d['verbose_name']+', '
        metricsdescriptions[m]=metricsdescriptions[m][0:-2]+')'

    metricsgroupschoices = ((m,metricsdescriptions[m]) for m in metricsgroups)

    return metricsgroupschoices

class VideoAnalysisMetricsForm(forms.Form):
    groups = forms.MultipleChoiceField(label='Metrics Groups',
                                       choices=get_metricschoices(mode='water'),
                                       widget=forms.CheckboxSelectMultiple,)

    class Meta:
        mode = 'water'

    def __init__(self, *args, **kwargs):
        mode = kwargs.pop('mode','water')
        super(VideoAnalysisMetricsForm, self).__init__(*args, **kwargs)
        self.fields['groups'].choices = get_metricschoices(mode=mode)


# BillingForm form
class BillingForm(forms.Form):
    amount = FlexibleDecimalField(required=True,decimal_places=2,
                                        max_digits=8)
    plan = forms.IntegerField(widget=forms.HiddenInput())
    payment_method_nonce = forms.CharField(max_length=255,required=True)
    paymenttype = forms.CharField(max_length=255,required=True)
    tac= forms.BooleanField(required=True,initial=False)


# login form
class LoginForm(forms.Form):
    username = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput())

# search form
class SearchForm(forms.Form):
    q = forms.CharField(max_length=255,required=False,
                        widget=forms.TextInput(
                            attrs={'placeholder': 'keyword or leave empty'}),
                        label='Filter by Keyword')



# simple form for Contact page. Sends email to info@rowsandall.com
class EmailForm(forms.Form):
    firstname = forms.CharField(max_length=255)
    lastname = forms.CharField(max_length=255)
    email = forms.EmailField()
    subject = forms.CharField(max_length=255)
    message = forms.CharField()

disqualificationreasons = (
    ('noimage','No monitor screenshot or data evidence was included'),
    ('suspicious','The result is not plausible for the boat class or athlete gorup'),
    ('duplicate','Appears to be a duplicate entry'),
    ('other','Other Reason'),
)

disqualifiers = {}
for key, value in disqualificationreasons:
    disqualifiers[key] = value

class DisqualificationForm(forms.Form):

    reason = forms.ChoiceField(required=True,
                               choices=disqualificationreasons,
                               widget = forms.RadioSelect,)

    message = forms.CharField(required=True,widget=forms.Textarea)

class HistorySelectForm(forms.Form):
    typeselectchoices = [("All","All")]
    for wtype,verbose in mytypes.workouttypes_ordered.items():
        typeselectchoices.append((wtype,verbose))
    startdate = forms.DateField(
        initial=timezone.now()-datetime.timedelta(days=15),
        #                               widget=SelectDateWidget(years=range(1990,2050)),
        widget=AdminDateWidget(), #format='%Y-%m-%d'),
        label='Start Date')
    enddate = forms.DateField(
        initial=timezone.now(),
        widget=AdminDateWidget(), #format='%Y-%m-%d'),
        label='End Date')

    workouttype = forms.ChoiceField(initial='All',choices=typeselectchoices)

    class Meta:
        fields = ['startdate','enddate']
        input_formats=("%Y-%m-%d")
        dateTimeOptions = {
            'format': '%Y-%m-%d',
            'autoclose': True,
            }

class MetricsForm(forms.Form):
    avghr = forms.IntegerField(required=False,label='Average Heart Rate')
    avgpwr = forms.IntegerField(required=False,label='Average Power')
    avgspm = forms.FloatField(required=False,label='Average SPM')

# Upload the CrewNerd Summary CSV
class CNsummaryForm(forms.Form):
    file = forms.FileField(required=True,validators=[must_be_csv])

# The little window to type '4x2000m/500m' to update the workout summary
class SummaryStringForm(forms.Form):
    intervalstring = forms.CharField(max_length=255,label='Workout Description')

# little window to type a Team invitation code
class TeamInviteCodeForm(forms.Form):
    code = forms.CharField(max_length=10,label='Team Code',
                           )

# Used for testing the POST API for StrokeData
class StrokeDataForm(forms.Form):
    strokedata = forms.CharField(label='payload',widget=forms.Textarea)

# The form used for uploading images
class ImageForm(forms.Form):
    file = forms.FileField(required=False,
                           validators=[validate_image_extension])

    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        super(ImageForm, self).__init__(*args, **kwargs)


# The form used for uploading images
class CourseForm(forms.Form):
    name = forms.CharField(max_length=150,label='Course Name')
    file = forms.FileField(required=False,
                           validators=[validate_kml])
    notes = forms.CharField(required=False,
                            max_length=200,label='Course Notes',
                            widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        super(CourseForm, self).__init__(*args, **kwargs)

# The form used for uploading files
class StandardsForm(forms.Form):
    name = forms.CharField(max_length=150,label='Course Name')
    file = forms.FileField(required=False,
                           validators=[must_be_csv])
    notes = forms.CharField(required=False,
                            max_length=200,label='Course Notes',
                            widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        super(StandardsForm, self).__init__(*args, **kwargs)

# The form used for uploading files
class DocumentsForm(forms.Form):
    title = forms.CharField(required=False)
    file = forms.FileField(required=False,
                           validators=[validate_file_extension])

    workouttype = forms.ChoiceField(required=True,
                                    choices=Workout.workouttypes)

    boattype = forms.ChoiceField(required=True,
                                 choices=mytypes.boattypes,
                                 label = "Boat Type")


    notes = forms.CharField(required=False,
                            widget=forms.Textarea)

    offline = forms.BooleanField(initial=False,required=False,
                                          label='Process in Background')
    class Meta:
        fields = ['title','file','workouttype','boattype','fileformat','offline']

    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        super(DocumentsForm, self).__init__(*args, **kwargs)
#        self.fields['offline'].widget = HiddenInput()

from rowers.utils import (
    workflowleftpanel,workflowmiddlepanel,
    defaultleft,defaultmiddle
    )



# Form to change Workflow page layout
class WorkFlowLeftPanelForm(forms.Form):
    panels = defaultleft

    leftpanel = forms.MultipleChoiceField(
        label='',
        choices=workflowleftpanel,
        initial=panels,
        widget=FilteredSelectMultiple(
            ('elements'),
            False
        )
    )

    class Media:
        css = {
            'all':['admin/css/widgets.css',]
#                   'css/uid-manage-form.css'],
            }
        js = ['/admin/jsi18n/']


    def __init__(self, *args, **kwargs):
        if 'instance' in kwargs:
            r = kwargs.pop('instance')
            panels = r.workflowleftpanel
            self.base_fields['leftpanel'].initial=panels
        else:
            panels = defaultleft


        super(WorkFlowLeftPanelForm,self).__init__(*args, **kwargs)


class WorkFlowMiddlePanelForm(forms.Form):
    panels = defaultmiddle


    middlepanel = forms.MultipleChoiceField(
        label='',
        choices=workflowmiddlepanel,
        initial=panels,
        widget=FilteredSelectMultiple(
            ('elements'),
            False
        )
    )

    class Media:
        css = {
            'all':['admin/css/widgets.css',]
#                   'css/uid-manage-form.css'],
            }
        js = ['/admin/jsi18n/']

    def __init__(self, *args, **kwargs):
        if 'instance' in kwargs:
            r = kwargs.pop('instance')
            panels = r.workflowmiddlepanel
            self.base_fields['middlepanel'].initial=panels
        else:
            panels = defaultmiddle

        super(WorkFlowMiddlePanelForm,self).__init__(*args, **kwargs)

class WorkFlowLeftPanelElement(forms.Form):
    panelchoices = tuple(list(workflowleftpanel)+[('None','None')])

    panel = forms.ChoiceField(
        label='',
        choices=panelchoices,
        initial='None',
        )

class WorkFlowMiddlePanelElement(forms.Form):
    panelchoices = tuple(list(workflowmiddlepanel)+[('None','None')])

    panel = forms.ChoiceField(
        label='',
        choices=panelchoices,
        initial='None',
        )


# The form to indicate additional actions to be performed immediately
# after a successful upload

nextpages = list(landingpages)
nextpages.append(('workout_upload_view','Upload Another File'))
nextpages = tuple(nextpages)

class LandingPageForm(forms.Form):
    landingpage = forms.ChoiceField(choices=nextpages,
                                    initial='workout_edit_view',
                                    label='After Upload, go to')

class UploadOptionsForm(forms.Form):
    plotchoices = (
        ('timeplot','Time Plot'),
        ('distanceplot','Distance Plot'),
        ('pieplot','Heart Rate Pie Chart'),
        )
    make_plot = forms.BooleanField(initial=False,required=False)
    plottype = forms.ChoiceField(required=False,
                                 choices=plotchoices,
                                 initial='timeplot',
                                 label='Plot Type')
    upload_to_C2 = forms.BooleanField(initial=False,required=False,
                                      label='Export to Concept2 logbook')
    upload_to_Strava = forms.BooleanField(initial=False,required=False,
                                          label='Export to Strava')
    upload_to_SportTracks = forms.BooleanField(initial=False,required=False,
                                               label='Export to SportTracks')
    upload_to_RunKeeper = forms.BooleanField(initial=False,required=False,
                                             label='Export to RunKeeper')
    upload_to_MapMyFitness = forms.BooleanField(initial=False,
                                                required=False,
                                                label='Export to MapMyFitness')
    upload_to_TrainingPeaks = forms.BooleanField(initial=False,
                                                 required=False,
                                                 label='Export to TrainingPeaks')
    # do_physics = forms.BooleanField(initial=False,required=False,label='Power Estimate (OTW)')
    makeprivate = forms.BooleanField(initial=False,required=False,
                                     label='Make Workout Private')

    submitrace = forms.ModelChoiceField(queryset=VirtualRace.objects.all(),
                                        label='Submit as challenge Result',
                                        required=False)

    landingpage = forms.ChoiceField(choices=nextpages,
                                    initial='workout_edit_view',
                                    label='After Upload, go to')

    class Meta:
        fields = ['make_plot','plottype','upload_toc2','makeprivate']

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request',None)
        raceid = kwargs.pop('raceid',0)
        super(UploadOptionsForm, self).__init__(*args, **kwargs)
        r = Rower.objects.get(user=self.request.user)
        races = VirtualRace.objects.filter(
            registration_closure__gt=timezone.now())
        registrations = IndoorVirtualRaceResult.objects.filter(
            race__in = races,
            userid = r.id)

        registrations2 = VirtualRaceResult.objects.filter(
            race__in = races,
            userid = r.id,
        )

        raceids = [r.race.id for r in registrations]
        raceids2 = [r.race.id for r in registrations2]

        raceids = raceids+raceids2

        races = VirtualRace.objects.filter(
            id__in=raceids
            )


        if races:
            self.fields['submitrace'].queryset = races
        else:
            del self.fields['submitrace']

        if int(raceid) in raceids:
            self.fields['submitrace'].initial = VirtualRace.objects.get(id=raceid)



# The form to indicate additional actions to be performed immediately
# after a successful upload. This version allows the Team manager to select
# a team member
class TeamUploadOptionsForm(forms.Form):
    plotchoices = (
        ('timeplot','Time Plot'),
        ('distanceplot','Distance Plot'),
        ('pieplot','Pie Chart'),
        )
    make_plot = forms.BooleanField(initial=False,required=False)
    plottype = forms.ChoiceField(required=False,
                                 choices=plotchoices,
                                 initial='timeplot',
                                 label='Plot Type')

    upload_to_C2 = forms.BooleanField(initial=False,required=False,
                                      label='Export to Concept2 logbook')
    upload_to_Strava = forms.BooleanField(initial=False,required=False,
                                          label='Export to Strava')
    upload_to_SportTracks = forms.BooleanField(initial=False,required=False,
                                               label='Export to SportTracks')
    upload_to_RunKeeper = forms.BooleanField(initial=False,required=False,
                                             label='Export to RunKeeper')
    upload_to_MapMyFitness = forms.BooleanField(initial=False,
                                                required=False,
                                                label='Export to MapMyFitness')
    upload_to_TrainingPeaks = forms.BooleanField(initial=False,
                                                 required=False,
                                                 label='Export to TrainingPeaks')
    # do_physics = forms.BooleanField(initial=False,required=False,label='Power Estimate (OTW)')
    makeprivate = forms.BooleanField(initial=False,required=False,
                                     label='Make Workout Private')



    class Meta:
        fields = ['make_plot','plottype']


# This form is used on the Workout Split page
class WorkoutSplitForm(forms.Form):
    splitchoices = (
        ('keep original','Keep Original'),
        ('keep first','Keep First Part'),
        ('keep second','Keep Second Part'),
        ('firstprivate','Set First Part Private'),
        ('secondprivate','Set Second Part Private'),
        ('originalprivate','Set Original Private'),
        )
    splittime = forms.TimeField(input_formats=['%H:%M:%S.%f',
                                               '%H:%M:%S',
                                               '%H:%M:%S',
                                               '%M:%S.%f',
                                               '%M:%S',
                                               '%M'],
                                label = 'Split Time')
    splitmode = forms.MultipleChoiceField(
        initial=['keep original',
                 'keep first',
                 'keep second',
                 'firstprivate',
                 'secondprivate'],
        label='Split Mode',
        choices=splitchoices,
        widget = forms.CheckboxSelectMultiple())

# This form is used on the Analysis page to add a custom distance/time
# trial and predict the pace
from rowers.utils import rankingdistances,rankingdurations
from time import strftime
class OteWorkoutTypeForm(forms.Form):
    choices = (
        ('rower','Indoor Rower'),
        ('dynamic','Dynamic Indoor Rower'),
        ('slides','Indoor Rower on Slides'),
    )

    workouttypes = forms.MultipleChoiceField(
        required=True,
        choices=choices,
        label='Workout Types',
        initial = [a for a,b in choices],
        )

class PredictedPieceForm(forms.Form):
    unitchoices = (
        ('t','minutes'),
        ('d','meters'),
        )

    rankingdistancechoices = []
    rankingdurationchoices = []
    for d in rankingdistances:
        thetuple = (d,str(d)+' m')
        rankingdistancechoices.append(thetuple)

    for d in rankingdurations:
        timestr = d.strftime("%H:%M:%S")
        thetuple = (timestr,timestr)
        rankingdurationchoices.append(thetuple)

    trankingdistances = forms.MultipleChoiceField(
        required=True,
        choices=rankingdistancechoices,initial=rankingdistances,
        label='Ranking Distances'
    )

    trankingdurations = forms.MultipleChoiceField(
        required=True,
        choices=rankingdurationchoices,
        initial=[a for a,b in rankingdurationchoices],
        label='Ranking Durations'
    )

    value = forms.FloatField(initial=10,label='Free ranking piece (minutes)')
    pieceunit = forms.ChoiceField(required=True,choices=unitchoices,
                                  initial='t',label='Unit')

    class Meta:
        fields = ['value','pieceunit']

class PredictedPieceFormNoDistance(forms.Form):

    rankingdurationchoices = []

    for d in rankingdurations:
        timestr = d.strftime("%H:%M:%S")
        thetuple = (timestr,timestr)
        rankingdurationchoices.append(thetuple)


    trankingdurations = forms.MultipleChoiceField(
        required=True,
        choices=rankingdurationchoices,
        initial=[a for a,b in rankingdurationchoices],
        label='Ranking Durations'
    )

    value = forms.FloatField(initial=10,label='Free ranking piece')


# On the Geeky side, to update stream information for river dwellers
class UpdateStreamForm(forms.Form):
    unitchoices = (
        ('m','m/s'),
        ('f','foot/s'),
        ('k','knots'),
        ('p','pace difference (sec/500m)'),
        )
    dist1 = forms.FloatField(initial=0,label = 'Distance 1')
    dist2 = forms.FloatField(initial=1000,label = 'Distance 2')
    stream1 = forms.FloatField(initial=0,label = 'Stream velocity 1')
    stream2 = forms.FloatField(initial=0,label = 'Stream velocity 2')
    streamunit = forms.ChoiceField(required=True,
                                   choices=unitchoices,
                                   initial='m',
                                   label='Unit')

    class Meta:
        fields = ['dist1','dist2','stream1', 'stream2','streamunit']

# add wind information to your workout
class UpdateWindForm(forms.Form):
    unitchoices = (
        ('m','m/s'),
        ('k','knots'),
        ('b','beaufort'),
        ('kmh','km/h'),
        ('mph','miles/hour'),
        )
    dist1 = forms.FloatField(initial=0,label = 'Distance 1')
    dist2 = forms.FloatField(initial=1000,label = 'Distance 2')
    vwind1 = forms.FloatField(initial=0,required=False,label = 'Wind Speed 1')
    vwind2 = forms.FloatField(initial=0,required=False,label = 'Wind Speed 2')
    windunit = forms.ChoiceField(required=True,
                                 choices=unitchoices,
                                 initial='m',
                                 label='Unit')
    winddirection1 = forms.IntegerField(initial=0,required=False,
                                        label = 'Wind Direction 1')
    winddirection2 = forms.IntegerField(initial=0,required=False,
                                        label = 'Wind Direction 2')

    class Meta:
        fields = ['dist1','dist2',
                  'vwind1','vwind2',
                  'windunit',
                  'winddirection1','winddirection2']

# Form to select a data range to show workouts from a certain time period
class DateRangeForm(forms.Form):
    startdate = forms.DateField(
        initial=timezone.now()-datetime.timedelta(days=365),
        #                               widget=SelectDateWidget(years=range(1990,2050)),
        widget=AdminDateWidget(), #format='%Y-%m-%d'),
        label='Start Date')
    enddate = forms.DateField(
        initial=timezone.now(),
        widget=AdminDateWidget(), #format='%Y-%m-%d'),
        label='End Date')

    class Meta:
        fields = ['startdate','enddate']
        input_formats=("%Y-%m-%d")
        dateTimeOptions = {
            'format': '%Y-%m-%d',
            'autoclose': True,
            }

class FitnessMetricForm(forms.Form):
    startdate = forms.DateField(
        initial=timezone.now()-datetime.timedelta(days=365),
        #                               widget=SelectDateWidget(years=range(1990,2050)),
        widget=AdminDateWidget(),
        label='Start Date')
    enddate = forms.DateField(
        initial=timezone.now(),
        widget=AdminDateWidget(),
        label='End Date')

    modechoices = (
        ('rower','indoor rower'),
        ('water','on the water')
        )

    mode = forms.ChoiceField(required=True,
                             choices=modechoices,
                             initial='rower',
                             label='Workout Mode'
                             )

    class Meta:
        fields = ['startdate','enddate','mode']

class SessionDateShiftForm(forms.Form):
    shiftstartdate = forms.DateField(
        initial=timezone.now(),
        widget=AdminDateWidget(),
        label='Shift to start on')

    class Meta:
        fields = ['shiftstartdate']

# Form used to select workouts for the past N days
class DeltaDaysForm(forms.Form):
    deltadays = forms.IntegerField(initial=7,required=False,label='')

class RegistrationForm(UserCreationForm):
    """
    Form for registering a new user account.
    Validates that the requested username is not already in use, and
    requires the password to be entered twice to catch typos.
    Subclasses should feel free to add any additional validation they
    need, but should avoid defining a ``save()`` method -- the actual
    saving of collected user data is delegated to the active
    registration backend.
    """
    required_css_class = 'required'
    email = forms.EmailField(label="E-mail")

    class Meta:
        model = User
        fields = ("username", "first_name", "last_name", "email", "password1", "password2")

        widgets = {
            'username': forms.TextInput(attrs={'autocomplete':'new-password'}),
            'password1': forms.PasswordInput(attrs={'autocomplete':'new-password'}),
            'password2': forms.PasswordInput(attrs={'autocomplete':'new-password'}),
            }

class RegistrationFormTermsOfService(RegistrationForm):
    """
    Subclass of ``RegistrationForm`` which adds a required checkbox
    for agreeing to a site's Terms of Service.
    """
    tos = forms.BooleanField(widget=forms.CheckboxInput,
                             label='I have read and agree to the Terms of Service',
                             error_messages={'required': "You must agree to the terms to register"})



class RegistrationFormUniqueEmail(RegistrationFormTermsOfService):
    """
    Subclass of ``RegistrationFormTermsOfService`` which enforces uniqueness of
    email addresses.
    """
    def clean_email(self):
        """
        Validate that the supplied email address is unique for the
        site.
        """
        if User.objects.filter(email__iexact=self.cleaned_data['email']):
            raise forms.ValidationError("This email address is already in use. Please supply a different email address.")
        return self.cleaned_data['email']

class RegistrationFormSex(RegistrationFormUniqueEmail):
    sexcategories = (
        ('female','female'),
        ('male','male'),
        ('not specified','not specified'),
        )

    weightcategories = (
        ('hwt','heavy-weight'),
        ('lwt','light-weight'),
    )

    adaptivecategories = mytypes.adaptivetypes

    thisyear = timezone.now().year

    birthdate = forms.DateTimeField(
        widget=SelectDateWidget(years=range(1900,thisyear)),
        initial = datetime.date(year=1970,
                                month=4,
                                day=15))

    def clean_birthdate(self):
        dob = self.cleaned_data['birthdate']
        age = (timezone.now() - dob).days/365
        if age < 16:
            raise forms.ValidationError('Must be at least 16 years old to register')
        return self.cleaned_data['birthdate']

    sex = forms.ChoiceField(required=False,
                            choices=sexcategories,
                            initial='not specified',
                            label='Sex')

    weightcategory = forms.ChoiceField(label='Weight Category',
                                       choices=weightcategories,initial='hwt',required=False)

    adaptiveclass = forms.ChoiceField(label='Adaptive Classification',
                                      choices=adaptivecategories,initial='None',required=False)

#    def __init__(self, *args, **kwargs):
#        self.fields['sex'].initial = 'not specified'

# Time field supporting microseconds. Not used, I believe.
class MyTimeField(forms.TimeField):

    def __init__(self, *args, **kwargs):
        super(MyTimeField, self).__init__(*args, **kwargs)
        supports_microseconds = True

# Form used to automatically define intervals by pace or power
class PowerIntervalUpdateForm(forms.Form):
    selectorchoices = (
        ('power','Power'),
        ('pace','Pace'),
        ('work','Work per Stroke'),
        ('spm','Stroke Rate')
        )

    pace = forms.DurationField(required=False,label='Pace (/500m)')
    power = forms.IntegerField(required=False,label='Power (W)')
    work = forms.IntegerField(required=False,label='Work per Stroke (J)')
    spm = forms.IntegerField(required=False,label='Stroke Rate')
    selector = forms.ChoiceField(choices=selectorchoices,
                                 required=True,
                                 initial='power',
                                 label='Use')
    activeminutesmin = forms.IntegerField(required=False,initial=0,widget=forms.HiddenInput())
    activeminutesmax = forms.IntegerField(required=False,initial=0,widget=forms.HiddenInput())

# Form used to update interval stats
class IntervalUpdateForm(forms.Form):

    def __init__(self, *args, **kwargs):
        typechoices = (
            (1,'single time'),
            (2,'single distance'),
            (3,'rest (time based)'),
            (3,'rest (distance based)'),
            (4,'work (time based)'),
            (5,'work (distance based)'),
            )
        aantal = int(kwargs.pop('aantal'))
        super(IntervalUpdateForm, self).__init__(*args, **kwargs)

        for i in range(aantal):
            self.fields['intervalt_%s' % i] = forms.DurationField(label='Time '+str(i+1))
            self.fields['intervald_%s' % i] = forms.IntegerField(label='Distance '+str(i+1))
            self.fields['type_%s' % i] = forms.ChoiceField(choices=typechoices,
                                                           required=True,
                                                           initial=4,
                                                           label = 'Type '+str(i+1))
            self.fields['intervalt_%s' % i].widget.attrs['style'] = 'width:76px; height: 16px;'
            self.fields['intervald_%s' % i].widget.attrs['style'] = 'width:76px; height: 16px;'
            self.fields['type_%s' % i].widget.attrs['style'] = 'width:156px; height: 22px;'
            self.fields['intervald_%s' % i].widget = forms.TimeInput(format='%H:%M:%S.%f')

boattypes = mytypes.boattypes
workouttypes = mytypes.workouttypes
ww = list(workouttypes)
ww.append(tuple(('all','All')))
workouttypes = tuple(ww)

class DataFrameColumnsForm(forms.Form):
    cols = ['ftime','cumdist','fpace','spm',
            'hr','power','driveenergy','drivelength','averageforce',
            'peakforce','distance','drivespeed','workoutstate',
            'catch','finish','peakforceangle','wash','slip','rhythm',
            'effectiveangle','totalangle','distanceperstroke','velo']

    colchoices = [
        (c, c) for c in cols
        ]

    cols = forms.MultipleChoiceField(choices=colchoices,
                                     label='Table Columns')

class HistoForm(forms.Form):
    includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False)
    histoparam = forms.ChoiceField(choices=parchoices,initial='power',
                               label='Metric')

class AnalysisOptionsForm(forms.Form):
    modality = forms.ChoiceField(choices=workouttypes,
                                 label='Workout Type',
                                 initial='all')
    waterboattype = forms.MultipleChoiceField(choices=boattypes,
                                              label='Water Boat Type',
                                              initial = mytypes.waterboattype)
    rankingonly = forms.BooleanField(initial=False,
                                     label='Only Ranking Pieces',
                                     required=False)


# form to select modality and boat type for trend flex
class TrendFlexModalForm(forms.Form):
    modality = forms.ChoiceField(choices=workouttypes,
                                 label='Workout Type',
                                 initial='all')
    waterboattype = forms.MultipleChoiceField(choices=boattypes,
                                              label='Water Boat Type',
                                              initial = mytypes.waterboattype)
    rankingonly = forms.BooleanField(initial=False,
                                     label='Only Ranking Pieces',
                                     required=False)



# This form sets options for the summary stats page
class StatsOptionsForm(forms.Form):
    includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False)
    rankingonly = forms.BooleanField(initial=False,
                                     label='Only Ranking Pieces',required=False)
    water = forms.BooleanField(initial=False,required=False)
    waterboattype = forms.MultipleChoiceField(choices=boattypes,
                                              label='Water Boat Type',
                                              widget=forms.CheckboxSelectMultiple(),
                                              initial = mytypes.waterboattype)



    def __init__(self, *args, **kwargs):
        super(StatsOptionsForm, self).__init__(*args,**kwargs)

        for type in mytypes.checktypes:
            self.fields[type] = forms.BooleanField(initial=True,required=False)

class PlanSelectForm(forms.Form):
    plan = forms.ModelChoiceField(queryset=PaidPlan.objects.all(),
                                  widget=forms.RadioSelect,required=True)

    def __init__(self, *args, **kwargs):
        paymentprocessor = kwargs.pop('paymentprocessor',None)
        rower = kwargs.pop('rower',None)
        includeall = kwargs.pop('includeall',False)
        super(PlanSelectForm, self).__init__(*args, **kwargs)
        self.fields['plan'].empty_label = None
        if paymentprocessor:
            self.fields['plan'].queryset = PaidPlan.objects.filter(
                paymentprocessor=paymentprocessor,
                active=True
            ).exclude(
                shortname="basic"
            ).order_by(
                "price","shortname"
            )
        if rower and not includeall:
            try:
                amount = rower.paidplan.price
            except AttributeError:
                amount = 0
            self.fields['plan'].queryset = PaidPlan.objects.filter(
                paymentprocessor=rower.paymentprocessor,
                active=True
                ).exclude(
                    price__lte=amount
                ).order_by(
                    "price","shortname"
                )


class CourseSelectForm(forms.Form):
    course = forms.ModelChoiceField(queryset=GeoCourse.objects.all())

class WorkoutSingleSelectForm(forms.Form):
    workout = forms.ModelChoiceField(
        queryset=Workout.objects.filter(),
        widget=forms.RadioSelect
        )

    def __init__(self, *args, **kwargs):
        workouts = kwargs.pop('workouts',Workout.objects.filter().order_by('-date'))
        super(WorkoutSingleSelectForm,self).__init__(*args,**kwargs)
        self.fields['workout'].queryset =  workouts

class WorkoutMultipleCompareForm(forms.Form):
    workouts = forms.ModelMultipleChoiceField(
        queryset=Workout.objects.filter(),
        widget=forms.CheckboxSelectMultiple())

    def __init__(self, *args, **kwargs):
        super(WorkoutMultipleCompareForm,self).__init__(*args,**kwargs)
        self.fields['workouts'].queryset =  Workout.objects.filter()


class PlannedSessionMultipleCloneForm(forms.Form):
    plannedsessions = forms.ModelMultipleChoiceField(
        queryset=PlannedSession.objects.all(),
        widget=forms.CheckboxSelectMultiple(),
        label='Planned Sessions'
        )


grouplabels = axlabels.copy()
grouplabels['date'] = 'Date'
grouplabels['workoutid'] = 'Workout'
grouplabels.pop('None')
grouplabels.pop('time')
groupchoices = list(sorted(grouplabels.items(), key = lambda x:x[1]))
formaxlabelsmultiflex = formaxlabels.copy()
formaxlabelsmultiflex.pop('time')
formaxlabelsmultiflex.pop('distance')
formaxlabelsmultiflex['workoutid'] = 'Workout'
parchoicesmultiflex = list(sorted(formaxlabelsmultiflex.items(), key = lambda x:x[1]))

from rowers.utils import palettes

palettechoices = tuple((p,p) for p in palettes.keys())

analysischoices = (
    ('boxplot','Box Chart'),
    ('trendflex','Trend Flex'),
    ('histo','Histogram'),
    ('flexall','Cumulative Flex Chart'),
    ('stats','Statistics'),
    ('compare','Compare'),
    )



class AnalysisChoiceForm(forms.Form):
    axchoices = list(
        (ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','None']
        )
    axchoices = dict((x,y) for x,y in axchoices)
    axchoices = list(sorted(axchoices.items(), key = lambda x:x[1]))


    yaxchoices = list((ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time'])
    yaxchoices = dict((x,y) for x,y in yaxchoices)
    yaxchoices = list(sorted(yaxchoices.items(), key = lambda x:x[1]))

    plotchoices = (
        ('line','Line Plot'),
        ('scatter','Scatter Plot'),
        )

    yaxchoices2 = list(
        (ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']
        )
    yaxchoices2 = dict((x,y) for x,y in yaxchoices2)
    yaxchoices2 = list(sorted(yaxchoices2.items(), key = lambda x:x[1]))

    function = forms.ChoiceField(choices=analysischoices,initial='boxplot',
                                 label='Analysis')
    xaxis = forms.ChoiceField(
        choices=axchoices,label='X-Axis',required=True,initial='spm')
    yaxis1 = forms.ChoiceField(
        choices=yaxchoices,label='Left Axis',required=True,initial='power')
    yaxis2 = forms.ChoiceField(
        choices=yaxchoices2,label='Right Axis',required=True,initial='None')
    plottype = forms.ChoiceField(choices=plotchoices,initial='scatter')

    plotfield = forms.ChoiceField(choices=parchoices,initial='spm',
                               label='Metric')
    xparam = forms.ChoiceField(choices=parchoicesmultiflex,
                               initial='hr',
                               label='X axis')
    yparam = forms.ChoiceField(choices=parchoicesmultiflex,
                               initial='pace',
                               label='Y axis')

    groupby = forms.ChoiceField(choices=groupchoices,initial='spm',
                                label='Group By')
    binsize = forms.FloatField(initial=1,required=False,label = 'Bin Size')

    ploterrorbars = forms.BooleanField(initial=False,
                                       required=False,
                                       label='Plot Error Bars')

    palette = forms.ChoiceField(choices=palettechoices,
                                label = 'Color Scheme',
                                initial='monochrome_blue')

    spmmin = forms.FloatField(initial=15,
                              required=False,label = 'Min SPM')
    spmmax = forms.FloatField(initial=55,
                              required=False,label = 'Max SPM')
    workmin = forms.FloatField(initial=0,
                              required=False,label = 'Min Work per Stroke')
    workmax = forms.FloatField(initial=1500,
                              required=False,label = 'Max Work per Stroke')

    includereststrokes = forms.BooleanField(initial=False,
                                            required=False,
                                            label='Include Rest Strokes')

class BoxPlotChoiceForm(forms.Form):
    yparam = forms.ChoiceField(choices=parchoices,initial='spm',
                               label='Metric')
    spmmin = forms.FloatField(initial=15,
                              required=False,label = 'Min SPM')
    spmmax = forms.FloatField(initial=55,
                              required=False,label = 'Max SPM')
    workmin = forms.FloatField(initial=0,
                              required=False,label = 'Min Work per Stroke')
    workmax = forms.FloatField(initial=1500,
                              required=False,label = 'Max Work per Stroke')

    includereststrokes = forms.BooleanField(initial=False,
                                            required=False,
                                            label='Include Rest Strokes')

class MultiFlexChoiceForm(forms.Form):
    xparam = forms.ChoiceField(choices=parchoicesmultiflex,
                               initial='hr',
                               label='X axis')
    yparam = forms.ChoiceField(choices=parchoicesmultiflex,
                               initial='pace',
                               label='Y axis')
    groupby = forms.ChoiceField(choices=groupchoices,initial='spm',
                                label='Group By')
    binsize = forms.FloatField(initial=1,required=False,label = 'Bin Size')
    spmmin = forms.FloatField(initial=15,
                              required=False,label = 'Min SPM')
    spmmax = forms.FloatField(initial=55,
                              required=False,label = 'Max SPM')
    workmin = forms.FloatField(initial=0,
                              required=False,label = 'Min Work per Stroke')
    workmax = forms.FloatField(initial=1500,
                              required=False,label = 'Max Work per Stroke')
    ploterrorbars = forms.BooleanField(initial=False,
                                       required=False,
                                       label='Plot Error Bars')
    includereststrokes = forms.BooleanField(initial=False,
                                            required=False,
                                            label='Include Rest Strokes')
    palette = forms.ChoiceField(choices=palettechoices,
                                label = 'Color Scheme',
                                initial='monochrome_blue')

class ChartParamChoiceForm(forms.Form):
    plotchoices = (
        ('line','Line Plot'),
        ('scatter','Scatter Plot'),
        )
    xparam = forms.ChoiceField(choices=parchoices,initial='distance')
    yparam = forms.ChoiceField(choices=parchoices,initial='hr')
    plottype = forms.ChoiceField(choices=plotchoices,initial='scatter')
    teamid = forms.IntegerField(widget=forms.HiddenInput())

formaxlabels.pop('time')
metricchoices = list(sorted(formaxlabels.items(), key = lambda x:x[1]))

class WorkoutJoinParamForm(forms.Form):
    workout_name = forms.CharField(required = True, initial = 'Joined Workout')
    set_private = forms.BooleanField(initial=False, required = False)
    killparents = forms.BooleanField(initial=False, required = False,
                                     label='Delete original workouts')

class FusionMetricChoiceForm(ModelForm):
    class Meta:
        model = Workout
        fields = []

    posneg = (
        ('pos','Workout 2 starts after Workout 1'),
        ('neg','Workout 2 starts before Workout 1'),
        )
    columns = forms.MultipleChoiceField(choices=metricchoices,
                                        initial=[],
                                        widget=forms.CheckboxSelectMultiple())
    posneg = forms.ChoiceField(choices=posneg,initial='pos')
    offset = forms.DurationField(label='Time Offset',initial=datetime.timedelta())

    def __init__(self, *args, **kwargs):
        super(FusionMetricChoiceForm, self).__init__(*args, **kwargs)
        formaxlabels2 = formaxlabels.copy()
        # need to add code to remove "empty" fields

        if self.instance.id is not None:
            id = self.instance.id
            df = dataprep.getrowdata_db(id=id)[0]

            labeldict = {key:value for key,value in self.fields['columns'].choices}

            for label in labeldict:
                if df.ix[:,label].std() == 0:
                    try:
                        formaxlabels2.pop(label)
                    except KeyError:
                        pass

                    metricchoices = list(sorted(formaxlabels2.items(), key = lambda x:x[1]))
                    self.fields['columns'].choices = metricchoices

class PlannedSessionSelectForm(forms.Form):

    def __init__(self, sessionchoices, *args, **kwargs):
        initialsession = kwargs.pop('initialsession',None)
        super(PlannedSessionSelectForm, self).__init__(*args,**kwargs)

        self.fields['plannedsession'] = forms.ChoiceField(
            label='Sessions',
            choices = sessionchoices,
            widget = forms.RadioSelect,
            initial=initialsession
        )


class WorkoutSessionSelectForm(forms.Form):

    def __init__(self, workoutdata, *args, **kwargs):

        super(WorkoutSessionSelectForm, self).__init__(*args, **kwargs)

        self.fields['workouts'] = forms.MultipleChoiceField(
            label='Workouts',
            choices = workoutdata['choices'],
            initial=workoutdata['initial'],
            widget = forms.CheckboxSelectMultiple,
            )



class RaceResultFilterForm(forms.Form):
    boatclasses = (type for type in mytypes.workouttypes if type[0] in mytypes.rowtypes)
    boatclassinitial = [t for t in mytypes.rowtypes]
    sexchoices = (
        ('female','Female'),
        ('male','Male'),
        ('mixed','Mixed'),
        )

    weightcategories = (
        ('hwt','heavy-weight'),
        ('lwt','light-weight'),
    )

    adaptivecategories = mytypes.adaptivetypes

    sex = forms.MultipleChoiceField(
        choices=sexchoices,
        initial=['male','female','mixed'],
        label='Gender',
        widget=forms.CheckboxSelectMultiple())

    boatclass = forms.MultipleChoiceField(
        choices=boatclasses,
        initial=boatclassinitial,
        label='Boat/Erg Class',
        widget=forms.CheckboxSelectMultiple())

    boattype = forms.MultipleChoiceField(
        choices=boattypes,
        label='Boat Type',
        initial=mytypes.waterboattype,
        widget=forms.CheckboxSelectMultiple())

    age_min = forms.IntegerField(label='Min Age',initial=16)
    age_max = forms.IntegerField(label='Max Age',initial=100)

    weightcategory = forms.MultipleChoiceField(
        choices=weightcategories,
        label='Weight Category',
        initial=['hwt','lwt'],
        widget=forms.CheckboxSelectMultiple())

    adaptivecategory = forms.MultipleChoiceField(
        choices=adaptivecategories,
        label='Adaptive Class',
        initial=['None','PR1','PR2','PR3','FES'],
        widget=forms.CheckboxSelectMultiple())

    entrycategory = forms.MultipleChoiceField(
        choices = [],
        label = 'Groups',
        widget=forms.CheckboxSelectMultiple()
    )

    def __init__(self, *args, **kwargs):
        if 'records' in kwargs:
            records = kwargs.pop('records',None)

        super(RaceResultFilterForm,self).__init__(*args,**kwargs)

        if records:
            # group
            thecategories = [record.entrycategory for record in records]
            thecategories = list(set(thecategories))
            if len(thecategories) <= 1:
                del self.fields['entrycategory']
            else:
                categorychoices = []
                for category in thecategories:
                    if category is not None:
                        categorychoices.append(
                            (category.id,category)
                            )
                self.fields['entrycategory'].choices = categorychoices
                self.fields['entrycategory'].initial = [cat[0] for cat in categorychoices]

            # sex
            thesexes = [record.sex for record in records]
            thesexes = list(set(thesexes))

            if len(thesexes)<= 1:
                del self.fields['sex']
            else:
                sexchoices = []
                for choice in self.fields['sex'].choices:
                    if choice[0] in thesexes:
                        sexchoices.append(choice)
                self.fields['sex'].choices = sexchoices

            # boatclass
            theboatclasses = [record.boatclass for record in records]
            theboatclasses = list(set(theboatclasses))

            if len(theboatclasses)<= 1:
                del self.fields['boatclass']
            else:
                boatclasschoices = []
                for choice in self.fields['boatclass'].choices:
                    if choice[0] in theboatclasses:
                        boatclasschoices.append(choice)
                self.fields['boatclass'].choices = boatclasschoices

            # boattype
            try:
                theboattypees = [record.boattype for record in records]
                theboattypees = list(set(theboattypees))
            except AttributeError:
                theboattypees = []

            if len(theboattypees)<= 1:
                del self.fields['boattype']
            else:
                boattypechoices = []
                for choice in self.fields['boattype'].choices:
                    if choice[0] in theboattypees:
                        boattypechoices.append(choice)
                self.fields['boattype'].choices = boattypechoices

            # weightcategory
            theweightcategoryes = [record.weightcategory for record in records]
            theweightcategoryes = list(set(theweightcategoryes))

            if len(theweightcategoryes)<= 1:
                del self.fields['weightcategory']
            else:
                weightcategorychoices = []
                for choice in self.fields['weightcategory'].choices:
                    if choice[0] in theweightcategoryes:
                        weightcategorychoices.append(choice)
                self.fields['weightcategory'].choices = weightcategorychoices

            # adaptivecategory
            theadaptivecategoryes = [record.adaptiveclass for record in records]
            theadaptivecategoryes = list(set(theadaptivecategoryes))

            if len(theadaptivecategoryes)<= 1:
                del self.fields['adaptivecategory']
            else:
                adaptivecategorychoices = []
                for choice in self.fields['adaptivecategory'].choices:
                    if choice[0] in theadaptivecategoryes:
                        adaptivecategorychoices.append(choice)
                self.fields['adaptivecategory'].choices = adaptivecategorychoices

class WorkoutRaceSelectForm(forms.Form):
#    evaluate_after = forms.TimeField(
#        input_formats=['%H:%M:%S.%f',
#                       '%H:%M:%S',
#                       '%H:%M:%S',
#                       '%M:%S.%f',
#                       '%M:%S',
#                       '%M'],
#        label = 'Only Evaluate After:',
#        required=False)

    def __init__(self, workoutdata,entries, *args, **kwargs):

        super(WorkoutRaceSelectForm, self).__init__(*args, **kwargs)

        self.fields['workouts'] = forms.ChoiceField(
            label='Workouts',
            choices = workoutdata['choices'],
            initial=workoutdata['initial'],
            widget=forms.RadioSelect,
            )

        self.fields['record'] = forms.ChoiceField(
            label = 'Entry',
            choices = entries['choices'],
            initial = entries['initial'],
            )

#        self.fields['evaluate_after'] =

# form to send messages to team members
class TeamMessageForm(forms.Form):
    message = forms.CharField(required=True,
                              initial='',
                              widget=forms.Textarea()
                              )

# Form to select team by rower
class RowerTeamForm(forms.Form):
    team = forms.ModelChoiceField(
        queryset=Team.objects.all(),
        required=False,
        )

    def __init__(self, user, *args, **kwargs):
        super(RowerTeamForm, self).__init__(*args, **kwargs)

        self.fields['team'].queryset = Team.objects.filter(manager=user)


class PlannedSessionTeamForm(forms.Form):
    team = forms.ModelMultipleChoiceField(
        queryset=Team.objects.all(),
        required=False,
        widget=forms.CheckboxSelectMultiple())

    def __init__(self, user, *args, **kwargs):
        super(PlannedSessionTeamForm,self).__init__(*args, **kwargs)

        self.fields['team'].queryset = Team.objects.filter(manager=user)

    def clean(self):
        if any(self.errors):
            return

        cd = self.cleaned_data
        if not cd['team']:
            raise forms.ValidationError(
                'You must select at least one team'
                )

        return cd


class PlannedSessionTeamMemberForm(forms.Form):
    members = forms.ModelMultipleChoiceField(
        queryset=Rower.objects.all(),
        widget=forms.CheckboxSelectMultiple())

    def __init__(self, thesession, *args, **kwargs):
        super(PlannedSessionTeamMemberForm,self).__init__(*args,**kwargs)

        self.fields['members'].queryset = thesession.rower.all()

from rowers.models import VirtualRace,GeoCourse

def get_countries():
    try:
        countries = VirtualRace.objects.order_by('country').values_list('country').distinct()
        countries = tuple([(c[0],c[0]) for c in countries])
        countries = countries+(('All','All'),)
    except:
        countries = (('All','All'))
    return countries



class VirtualRaceSelectForm(forms.Form):
    regattatypechoices = (
        ('upcoming','Upcoming Challenges'),
        ('ongoing','Ongoing Challenges'),
        ('previous','Previous Challenges'),
        ('my','My Challenges'),
        ('all','All Challenges'),
        )

    regattatype = forms.ChoiceField(
        label='Type',
        choices = regattatypechoices,
        initial = 'upcoming',
        )

    country = forms.ChoiceField(
        label='Country',
        choices = get_countries()
    )


    def __init__(self, *args, **kwargs):
        super(VirtualRaceSelectForm, self).__init__(*args, **kwargs)
        self.fields['country'] = forms.ChoiceField(
            choices = get_countries(),initial='All'
            )

class FlexOptionsForm(forms.Form):
    includereststrokes = forms.BooleanField(initial=True, required = False,
                                         label='Include Rest Strokes')
    plotchoices = (
        ('line','Line Plot'),
        ('scatter','Scatter Plot'),
        )
    plottype = forms.ChoiceField(choices=plotchoices,initial='line',
                                 label='Chart Type')

class ForceCurveOptionsForm(forms.Form):
    includereststrokes = forms.BooleanField(initial=False, required = False,
                                         label='Include Rest Strokes')
    plotchoices = (
        ('line','Force Curve Collection Plot'),
        ('scatter','Peak Force Scatter Plot'),
        ('none','Only aggregrate data')
        )
    plottype = forms.ChoiceField(choices=plotchoices,initial='line',
                                 label='Individual Stroke Chart Type')


class FlexAxesForm(forms.Form):
    axchoices = list(
        (ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','None']
        )
    axchoices = dict((x,y) for x,y in axchoices)
    axchoices = list(sorted(axchoices.items(), key = lambda x:x[1]))


    yaxchoices = list((ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time'])
    yaxchoices = dict((x,y) for x,y in yaxchoices)
    yaxchoices = list(sorted(yaxchoices.items(), key = lambda x:x[1]))


    yaxchoices2 = list(
        (ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']
        )
    yaxchoices2 = dict((x,y) for x,y in yaxchoices2)
    yaxchoices2 = list(sorted(yaxchoices2.items(), key = lambda x:x[1]))

    xaxis = forms.ChoiceField(
        choices=axchoices,label='X-Axis',required=True)
    yaxis1 = forms.ChoiceField(
        choices=yaxchoices,label='Left Axis',required=True)
    yaxis2 = forms.ChoiceField(
        choices=yaxchoices2,label='Right Axis',required=True)

    def __init__(self,request,*args,**kwargs):
        extrametrics = kwargs.pop('extrametrics',[])
        super(FlexAxesForm, self).__init__(*args, **kwargs)


        rower = Rower.objects.get(user=request.user)

        axchoicespro = (
            ('',ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0],ax[1]) for ax in axes
            )

        axchoicesbasicx = []
        axchoicesbasicy = []

        for ax in axes:
            if ax[4] != 'pro' and ax[0] != 'cumdist':
                if ax[0] != 'None':
                    axchoicesbasicx.insert(0,(ax[0],ax[1]))
                if ax[0] not in ['cumdist','distance','time']:
                    axchoicesbasicy.insert(0,(ax[0],ax[1]))
            else:
                if ax[0] != 'None':
                    axchoicesbasicx.insert(0,('None',ax[1]+' (PRO)'))
                if ax[0] not in ['cumdist','distance','time']:
                    axchoicesbasicy.insert(0,('None',ax[1]+' (PRO)'))


        if not user_is_not_basic(rower.user):
            self.fields['xaxis'].choices = axchoicesbasicx
            self.fields['yaxis1'].choices = axchoicesbasicy
            self.fields['yaxis2'].choices = axchoicesbasicy
