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

from rowers.views.statements import *

@login_required
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_comment_view(request,id=0,userid=0):
    r = getrequestplanrower(request,userid=userid)
    ps = get_object_or_404(PlannedSession,pk=id)

    comments = PlannedSessionComment.objects.filter(plannedsession=ps).order_by("created")

    if request.method == 'POST':
        manager = ps.manager
        form = PlannedSessionCommentForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            comment = cd['comment']
            comment = bleach.clean(comment)
            try:
                if isinstance(comment,unicode):
                    comment = comment.encode('utf8')
                elif isinstance(comment, str):
                    comment = comment.decode('utf8')
            except:
                pass

            notification = cd['notification']
            c = PlannedSessionComment(plannedsession=ps,user=request.user,comment=comment,
                               notification=notification)
            c.save()
            url = reverse('plannedsession_comment_view',
                          kwargs={
                              'id':id
                              })
            message = '{name} says: <a href="{url}">{comment}</a>'.format(
                name = request.user.first_name,
                comment = comment,
                url = url,
            )
            if request.user != manager:
                a_messages.info(r.user,message.encode('ascii','ignore'))

            sessiontype = 'training session'
            if ps.sessiontype == 'race':
                sessiontype = 'online virtual race'
            elif ps.sessiontype == 'indoorrace':
                sessiontype = 'indoor online virtual race'

            res = myqueue(queuehigh,
                          handle_sendemailnewcomment,r.user.first_name,
			  r.user.last_name,
			  r.user.email,
                          request.user.first_name,
                          request.user.last_name,
                          comment,ps.name,ps.id,
                          emailbounced = r.emailbounced,
                          sessiontype = sessiontype,
                          commentlink = url
            )

            commenters = {oc.user for oc in comments if oc.notification}
            if ps.sessiontype=='race':
                registrations = VirtualRaceResult.objects.filter(
                    race__id=ps.id,
                    emailnotifications=True)
                ids = [rg.userid for rg in registrations]
                rwrs = Rower.objects.filter(id__in= ids)
                rowers = {u.user for u in rwrs}
            elif ps.sessiontype=='indoorrace':
                registrations = IndoorVirtualRaceResult.objects.filter(
                    race__id=ps.id,
                    emailnotifications=True)
                ids = [rg.userid for rg in registrations]
                rwrs = Rower.objects.filter(id__in= ids)
                rowers = {u.user for u in rwrs}
            else:
                rowers = {r.user for r in ps.rower.all()}
            commenters = set(list(commenters)+list(rowers))
            for u in commenters:
                a_messages.info(u,message)
                if u != request.user and u != r.user:
                    ocr = Rower.objects.get(user=u)
                    res = myqueue(queuelow,
                                  handle_sendemailnewresponse,
                                  u.first_name,
                                  u.last_name,
                                  u.email,
                                  request.user.first_name,
                                  request.user.last_name,
                                  comment,
                                  ps.name,
                                  ps.id,
                                  c.id,
                                  emailbounced = ocr.emailbounced,
                                  sessiontype = sessiontype,
                                  commentlink = url
                    )

            url = reverse('plannedsession_comment_view',kwargs={'id':ps.id})
            return HttpResponseRedirect(url)


    form = WorkoutCommentForm()

    rower = getrower(request.user)

    if ps.sessiontype in ['race','indoorrace']:
        breadcrumbs = [
            {
                'url':reverse('virtualevents_view'),
                'name': 'Races'
                },
            {
                'url': reverse('virtualevent_view',kwargs={'id':ps.id}),
                'name': ps.name
                },
            {
                'url':reverse('plannedsession_comment_view',kwargs={'id':ps.id}),
                'name': 'Comments'
                }
            ]

        active = 'nav-racing'

    else:
        breadcrumbs = [
            {
                'url':reverse('plannedsessions_view'),
                'name': 'Sessions'
                },
            {
                'url': reverse('plannedsession_view',kwargs={'id':ps.id}),
                'name': ps.name
                },
            {
                'url':reverse('plannedsession_comment_view',kwargs={'id':ps.id}),
                'name': 'Comments'
                }
            ]

        active = 'nav-plan'

    return render(request,
           'plannedsession_comments.html',
           {'plannedsession':ps,
            'rower':rower,
            'breadcrumbs':breadcrumbs,
            'active':active,
            'comments':comments,
            'form':form,
            })

# Cloning sessions
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_multiclone_view(
        request,
        userid=0,):

    r = getrequestplanrower(request,userid=userid)


    startdate,enddate = get_dates_timeperiod(request)
    teamid = get_team(request)

    if request.method == 'POST' and 'daterange' in request.POST:
        dateform = DateRangeForm(request.POST)
        if dateform.is_valid():
            startdate = dateform.cleaned_data['startdate']
            enddate = dateform.cleaned_data['enddate']
            startdatestring = startdate.strftime('%Y-%m-%d')
            enddatestring = enddate.strftime('%Y-%m-%d')
            request.session['startdate'] = startdatestring
            request.session['enddate'] = enddatestring
    else:
        dateform = DateRangeForm(initial={
            'startdate':startdate,
            'enddate':enddate,
            })

    if request.method == 'POST' and 'plannedsessions' in request.POST:
        form = PlannedSessionMultipleCloneForm(request.POST)
        dateshiftform = SessionDateShiftForm(request.POST)
        if form.is_valid() and dateshiftform.is_valid():
            cd = form.cleaned_data
            sps = cd['plannedsessions']
            std = min([ps.startdate for ps in sps])
            shiftstartdate = dateshiftform.cleaned_data['shiftstartdate']
            delta = shiftstartdate-std
            lastdate = shiftstartdate
            for ps in sps:
                rowers = ps.rower.all()
                teams = ps.team.all()
                ps.pk = None
                ps.startdate += delta
                ps.preferreddate += delta
                ps.enddate += delta
                if ps.enddate > lastdate:
                    lastdate = ps.enddate
                ps.save()
                for rower in rowers:
                    add_rower_session(rower,ps)
                for team in teams:
                    add_team_session(team,ps)

            startdatestring = shiftstartdate.strftime('%Y-%m-%d')
            enddatestring = lastdate.strftime('%Y-%m-%d')

            url = reverse(plannedsessions_view,
                          kwargs = {
                              'userid':r.user.id,
                              })


            url+='?when='+startdatestring+'/'+enddatestring

            return HttpResponseRedirect(url)

    sps = PlannedSession.objects.filter(
        manager=request.user,
        rower__in=[r],
        is_template=False,
        startdate__lte=enddate,
        enddate__gte=startdate).order_by(
            "startdate","preferreddate","enddate").exclude(
                sessiontype='race')

    if teamid:
        sps = sps.filter(team__in=[teamid])
        try:
            team = Team.objects.get(id=teamid)
            if team.manager != request.user:
                team = None
        except Team.DoesNotExist:
            team = None
    else:
        team = None

    query = request.GET.get('q')
    if query:
        query_list = query.split()
        sps = sps.filter(
            reduce(operator.and_,
                   (Q(name__icontains=q) for q in query_list)) |
            reduce(operator.and_,
                   (Q(comment__icontains=q) for q in query_list))
            )

    form = PlannedSessionMultipleCloneForm()
    form.fields["plannedsessions"].queryset = sps

    dateshiftform = SessionDateShiftForm()

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    breadcrumbs = [
        {
            'url': reverse(plannedsessions_view),
            'name': 'Planned Sessions'
            },
        {
            'url': reverse(plannedsession_multiclone_view),
            'name': 'Clone Multiple Sessions'
            }
        ]

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate,
        })

    if Team.objects.filter(manager=request.user).count()>=1:
        teamform = RowerTeamForm(request.user)
        if teamid:
            teamform = RowerTeamForm(request.user,initial={'team':teamid})
    else:
        teamform = None

    return render(request, 'plannedsessions_multiclone_select.html',
                  {'plannedsessions':sps,
                   'breadcrumbs':breadcrumbs,
                   'plan':trainingplan,
                   'dateform':dateform,
                   'startdate':startdate,
                   'enddate':enddate,
                   'form':form,
                   'dateshiftform':dateshiftform,
                   'rower':r,
                   'active':'nav-plan',
                   'timeperiod':timeperiod,
                   'team':team,
                   'teamform':teamform,
                   }
                  )

# Individual user creates training for himself
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_create_view(request,
                               userid=0,
                               startdatestring='',
                               enddatestring=''):

    r = getrequestplanrower(request,userid=userid)

    startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
                                             enddatestring=enddatestring)



    if request.method == 'POST':
        sessioncreateform = PlannedSessionForm(request.POST)
        if sessioncreateform.is_valid():
            cd = sessioncreateform.cleaned_data
            startdate = cd['startdate']
            enddate = cd['enddate']
            preferreddate = cd['preferreddate']
            sessiontype = cd['sessiontype']
            sessionmode = cd['sessionmode']
            criterium = cd['criterium']
            sessionvalue = cd['sessionvalue']
            sessionunit = cd['sessionunit']
            comment = cd['comment']
            course = cd['course']
            name = cd['name']

            if sessionunit == 'min':
                sessionmode = 'time'
            elif sessionunit in ['km','m']:
                sessionmode = 'distance'

            ps = PlannedSession(
                name=name,
                startdate=startdate,
                enddate=enddate,
                preferreddate=preferreddate,
                course=course,
                sessiontype=sessiontype,
                sessionmode=sessionmode,
                sessionvalue=sessionvalue,
                sessionunit=sessionunit,
                comment=comment,
                criterium=criterium,
                manager=request.user)

            ps.save()

            add_rower_session(r,ps)


            request.session['fstartdate'] = str(arrow.get(startdate))
            request.session['fenddate'] = str(arrow.get(enddate))
            request.session['fprefdate'] = str(arrow.get(preferreddate))

    else:
        if 'fstartdate' in request.session:
            try:
                fstartdate = arrow.get(request.session['fstartdate']).date()
            except KeyError:
                fstartdate = timezone.now().date()
                if fstartdate < startdate:
                    fstartdate = startdate
            try:
                fenddate = arrow.get(request.session['fenddate']).date()
            except KeyError:
                fenddate = timezone.now().date()
                if fenddate > enddate:
                    fenddate = enddate
            try:
                fprefdate = arrow.get(request.session['fprefdate']).date()
            except KeyError:
                fprefdate = timezone.now().date()

            if fprefdate < startdate:
                fprefdate = startdate

            if fprefdate > enddate:
                fprefdate = enddate


            forminitial = {
                'startdate':fstartdate,
                'enddate':fenddate,
                'preferreddate':fprefdate
                }
        else:
            try:
                preferreddate = startdate.date()
            except AttributeError:
                preferreddate = startdate
            if preferreddate < timezone.now().date():
                preferreddate = timezone.now().date()

            try:
                enddate = enddate.date()
            except AttributeError:
                pass

            if preferreddate > enddate:
                preferreddate = enddate

            forminitial = {
                'startdate':startdate,
                'enddate':enddate,
                'preferreddate':preferreddate,
            }

        sessioncreateform = PlannedSessionForm(initial=forminitial)

    if request.GET.get('startdate') or request.GET.get('when'):
        startdate, enddate = get_dates_timeperiod(request)

    sps = get_sessions(r,startdate=startdate,enddate=enddate).exclude(
                sessiontype='race')

    sessiontemplates = PlannedSession.objects.filter(
        manager=request.user,
        is_template=True).order_by("name")

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate,
        })

    return render(request,'plannedsessioncreate.html',
                  {
                      'teams':get_my_teams(request.user),
                      'plan':trainingplan,
                      'dateform':dateform,
                      'form':sessioncreateform,
                      'active':'nav-plan',
                      'plannedsessions':sps,
                      'sessiontemplates':sessiontemplates,
                      'rower':r,
                      'timeperiod':timeperiod,
                  })

@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_multicreate_view(request,
                                    teamid=0,userid=0,extrasessions=0):

    extrasessions=int(extrasessions)

    r = getrequestplanrower(request,userid=userid)


    startdate,enddate = get_dates_timeperiod(request)
    teamid = get_team(request)
    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

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

    qset = PlannedSession.objects.filter(
        rower__in=[r],
        manager = request.user,
        startdate__lte=enddate,
        enddate__gte=startdate,
    ).order_by("startdate","preferreddate","enddate").exclude(
        sessiontype='race')

    if teamid:
        qset = qset.filter(team__in=[teamid])
        try:
            team = Team.objects.get(id=teamid)
            if team.manager != request.user:
                team = None
        except Team.DoesNotExist:
            team = None
    else:
        team = None


    initial = {
        'startdate':startdate,
        'enddate':enddate,
        'sessionvalue':60,
        'manager':request.user,
        'name': 'NEW SESSION'
    }



    initials = [initial for i in range(extrasessions)]

    PlannedSessionFormSet = modelformset_factory(
        PlannedSession,
        form=PlannedSessionFormSmall,
        can_delete=True,
        extra=extrasessions,
    )
    if request.method == "POST":
        ps_formset = PlannedSessionFormSet(queryset = qset,
                                           data = request.POST)
        if ps_formset.is_valid():
            instances = ps_formset.save(commit=False)
            for ps in instances:
                ps.save()
                add_rower_session(r,ps)
                if team:
                    add_team_session(team,ps)
                messages.info(request,"Saved changes for Planned Session "+str(ps))
            for obj in ps_formset.deleted_objects:
                messages.info(request,"Deleted Planned Session "+str(obj))
                obj.delete()

        url = reverse(plannedsession_multicreate_view,
                      kwargs = {
                          'userid':r.user.id,
                          }
                      )


        startdatestring = startdate.strftime('%Y-%m-%d')
        enddatestring = enddate.strftime('%Y-%m-%d')
        url += '?when='+startdatestring+'/'+enddatestring

        if team:
            url += '&team={teamid}'.format(teamid=team.id)

        return HttpResponseRedirect(url)

    ps_formset = PlannedSessionFormSet(queryset = qset,
                                       initial=initials)
    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    breadcrumbs = [
        {
            'url': reverse(plannedsessions_view),
            'name': 'Planned Sessions'
            },
        {
            'url': reverse(plannedsession_multicreate_view),
            'name': 'Plan MicroCycle'
            }
        ]

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate
        })

    if Team.objects.filter(manager=request.user).count()>=1:
        teamform = RowerTeamForm(request.user)
        if teamid:
            teamform = RowerTeamForm(request.user,initial={'team':teamid})
    else:
        teamform = None

    context = {
        'ps_formset':ps_formset,
        'breadcrumbs':breadcrumbs,
        'rower':r,
        'active':'nav-plan',
        'dateform':dateform,
        'teamform':teamform,
        'plan':trainingplan,
        'timeperiod':timeperiod,
        'teams':get_my_teams(request.user),
        'extrasessions': extrasessions+1,
        'team':team,
        }


    return render(request,'plannedsession_multicreate.html',context)

# Manager creates sessions for entire team
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_teamcreate_view(request,
                                   teamid=0,userid=0):

    therower = getrequestplanrower(request,userid=userid)



    teams = Team.objects.filter(manager=request.user)
    if teams.count()>0:
        teamchoices = [(team.id, team.name) for team in teams]
        teaminitial = [str(teams[0].id)]
    else:
        messages.info(request,"You have no teams established yet. We are redirecting you to the Team Management page.")
        url = reverse('rower_teams_view')
        return HttpResponseRedirect(url)

    startdate,enddate = get_dates_timeperiod(request)

    trainingplan = None

    sps = []
    for team in teams:
        res = get_sessions_manager(request.user,startdate=startdate,enddate=enddate)
        sps += res

    sps = list(set(sps))
    ids = [ps.id for ps in sps]
    sps = PlannedSession.objects.filter(id__in=ids).order_by(
        "preferreddate","startdate","enddate")

    sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)

    if request.method == 'POST':
        sessioncreateform = PlannedSessionForm(request.POST)
        sessionteamselectform = PlannedSessionTeamForm(
            request.user,request.POST
        )

        if sessioncreateform.is_valid() and sessionteamselectform.is_valid():
            cd = sessioncreateform.cleaned_data
            startdate = cd['startdate']
            enddate = cd['enddate']
            preferreddate = cd['preferreddate']
            sessiontype = cd['sessiontype']
            sessionmode = cd['sessionmode']
            criterium = cd['criterium']
            sessionvalue = cd['sessionvalue']
            sessionunit = cd['sessionunit']
            comment = cd['comment']
            course = cd['course']
            name = cd['name']

            if sessionunit == 'min':
                sessionmode = 'time'
            elif sessionunit in ['km','m']:
                sessionmode = 'distance'

            ps = PlannedSession(
                name=name,
                startdate=startdate,
                enddate=enddate,
                preferreddate=preferreddate,
                sessiontype=sessiontype,
                sessionmode=sessionmode,
                sessionvalue=sessionvalue,
                sessionunit=sessionunit,
                comment=comment,
                criterium=criterium,
                course=course,
                manager=request.user)

            ps.save()

            cd = sessionteamselectform.cleaned_data
            teams = cd['team']
            request.session['teams'] = [team.id for team in teams]
            for team in teams:
                add_team_session(team,ps)
                rs = Rower.objects.filter(team__in=[team]).exclude(rowerplan='freecoach')
                for r in rs:
                    add_rower_session(r,ps)


            url = reverse(plannedsession_teamcreate_view)
            startdatestring = startdate.strftime('%Y-%m-%d')
            enddatestring = enddate.strftime('%Y-%m-%d')
            url += '?when='+startdatestring+'/'+enddatestring

            next = request.GET.get('next', url)

            return HttpResponseRedirect(next)
        else:
            timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
            breadcrumbs = [
                {
                    'url': reverse(plannedsessions_view),
                    'name': 'Planned Sessions'
                },
                {
                    'url': reverse(plannedsession_teamcreate_view),
                    'name': 'Add Team Session'
                }
            ]

            return render(request,'plannedsessionteamcreate.html',
                          {
                              'teams':get_my_teams(request.user),
                              'plan':trainingplan,
                              'breadcrumbs':breadcrumbs,
                              'form':sessioncreateform,
                              'sessiontemplates':sessiontemplates,
                              'teamform':sessionteamselectform,
                              'timeperiod':timeperiod,
                              'plannedsessions':sps,
                              'rower':therower,
                              'active':'nav-plan'
                          })

    else:
        initial = {
            'startdate':startdate,
            'enddate':enddate,
            'preferreddate':startdate,
            }

        if 'teams' in request.session:
            teams = request.session['teams']
            theteams = Team.objects.filter(id__in=teams)
            initialteam = {
                'team':theteams
                }
        else:
            initialteam = {}

        sessioncreateform = PlannedSessionForm(initial=initial)
        sessionteamselectform = PlannedSessionTeamForm(
            request.user,initial=initialteam
        )

        timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
        breadcrumbs = [
        {
            'url': reverse(plannedsessions_view),
            'name': 'Planned Sessions'
            },
        {
            'url': reverse(plannedsession_teamcreate_view),
            'name': 'Add Team Session'
            }
        ]

        dateform = DateRangeForm(initial={
            'startdate':startdate,
            'enddate':enddate,
            })

        return render(request,'plannedsessionteamcreate.html',
                  {
                      'teams':get_my_teams(request.user),
                      'plan':trainingplan,
                      'dateform':dateform,
                      'breadcrumbs':breadcrumbs,
                      'form':sessioncreateform,
                      'sessiontemplates':sessiontemplates,
                      'teamform':sessionteamselectform,
                      'timeperiod':timeperiod,
                      'plannedsessions':sps,
                      'rower':therower,
                      'active':'nav-plan'
                  })

# Manager edits sessions for entire team
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_teamedit_view(request,
                                 id=0,userid=0):

    r = getrequestplanrower(request,userid=userid)

    ps = get_object_or_404(PlannedSession,pk=id)

    teams = Team.objects.filter(manager=request.user)
    teamchoices = [(team.id, team.name) for team in teams]

    teaminitial = ps.team.all()

    startdate,enddate = get_dates_timeperiod(request)

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    sps = []
    rowers = []
    for team in teams:
        res = get_sessions_manager(request.user,startdate=startdate,enddate=enddate)
        sps += res
        rowers += Rower.objects.filter(team__in=[team])

    rowers = list(set(rowers))


    sps = list(set(sps))
    ids = [pps.id for pps in sps]
    sps = PlannedSession.objects.filter(id__in=ids).order_by(
        "preferreddate","startdate","enddate")

    if request.method == 'POST':
        sessioncreateform = PlannedSessionForm(request.POST,instance=ps)
        sessionteamselectform = PlannedSessionTeamForm(
            request.user,request.POST
        )
        sessionrowerform = PlannedSessionTeamMemberForm(ps,request.POST)


        if sessioncreateform.is_valid():
            cd = sessioncreateform.cleaned_data

            if cd['sessionunit'] == 'min':
                cd['sessionmode'] = 'time'
            elif cd['sessionunit'] in ['km','m']:
                cd['sessionmode'] = 'distance'


            res,message = update_plannedsession(ps,cd)

            if res:
                messages.info(request,message)
            else:
                messages.error(request,message)


            # some logic when to add all selected rowers
            if sessionteamselectform.is_valid():
                cd = sessionteamselectform.cleaned_data
                selectedteams = cd['team']
                for team in teams:
                    if team in selectedteams:
                        add_team_session(team,ps)
                        rs = Rower.objects.filter(team__in=[team])
                        for r in rs:
                            add_rower_session(r,ps)
                    else:
                        remove_team_session(team,ps)
            else:
                selectedteams = []
                for team in teams:
                    remove_team_session(team,ps)


            if sessionrowerform.is_valid():
                cd = sessionrowerform.cleaned_data
                selectedrowers = cd['members']
                for r in rowers:
                    if r in selectedrowers:
                        add_rower_session(r,ps)
                    else:
                        remove_rower_session(r,ps)
                        for t in selectedteams:
                            if t in r.team.all():
                                add_rower_session(r,ps)


            url = reverse(plannedsession_teamedit_view,
                          kwargs = {
                              'id':id,
                          })

            startdatestring = startdate.strftime('%Y-%m-%d')
            enddatestring = enddate.strftime('%Y-%m-%d')
            url += '?when='+startdatestring+'/'+enddatestring

            next = request.GET.get('next', url)
            return HttpResponseRedirect(next)
    else:
        sessioncreateform = PlannedSessionForm(instance=ps)
        sessionteamselectform = PlannedSessionTeamForm(
            request.user
        )
        sessionteamselectform.fields['team'].initial = teaminitial
        sessionrowerform = PlannedSessionTeamMemberForm(
            ps
            )


        sessionrowerform.fields['members'].initial = ps.rower.all()

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    breadcrumbs = [
        {
            'url': reverse(plannedsessions_view),
            'name': 'Planned Sessions'
        },
        {
            'url': reverse(plannedsession_teamcreate_view),
            'name': 'Add Team Session'
        }
    ]

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate,
        })

    return render(request,'plannedsessionteamedit.html',
                  {
                      'plannedsession':ps,
                      'plan':trainingplan,
                      'dateform':dateform,
                      'breadcrumbs':breadcrumbs,
                      'rower':r,
                      'active':'nav-plan',
                      'teams':get_my_teams(request.user),
                      'form':sessioncreateform,
                      'teamform':sessionteamselectform,
                      'rowersform':sessionrowerform,
                      'timeperiod':timeperiod,
                      'plannedsessions':sps,
                  })

#@user_passes_test(iscoachmember,login_url="/rowers/paidplans/",
#                  redirect_field_name=None)
@login_required()
def plannedsessions_coach_view(request,
                               teamid=0,userid=0):


    therower = getrequestplanrower(request,userid=userid)


    startdate,enddate = get_dates_timeperiod(request)


    trainingplan = None

    if teamid != 0:
        try:
            theteam = Team.objects.get(id=teamid)
        except Team.DoesNotExist:
            theteam = False
    else:
        theteam = False

    if 'coach' in request.user.rower.rowerplan:
        sps = get_sessions_manager(request.user,teamid=teamid,
                                   enddate=enddate,
                                   startdate=startdate)
    else:
        rteams = therower.team.filter(viewing='allmembers')
        sps = get_sessions(therower,startdate=startdate,enddate=enddate)

    if therower.rowerplan != 'freecoach':
        rowers = [therower]
    else:
        rowers = []

    for ps in sps:
        if 'coach' in request.user.rower.rowerplan:
            rowers += ps.rower.all().exclude(rowerplan='freecoach')
        else:
            rowers += ps.rower.filter(team__in=rteams).exclude(rowerplan='freecoach')

    rowers = list(set(rowers))

    statusdict = []

    for ps in sps:
        rowerstatus = {}
        rowercolor = {}
        for r in rowers:
            ratio, status,completiondate = is_session_complete(r,ps)
            rowerstatus[r.id] = status
            rowercolor[r.id] = cratiocolors[status]
        sessiondict = {
            'id': ps.id,
            'results':rowerstatus,
            'name': ps.name,
            'startdate': ps.startdate,
            'color': rowercolor,
            'preferreddate': ps.preferreddate,
            'enddate': ps.enddate,
            }
        statusdict.append(sessiondict)

    unmatchedworkouts = []
    for r in rowers:
        unmatchedworkouts += Workout.objects.filter(
        user=r,
        plannedsession=None,
        date__gte=startdate,date__lte=enddate)


    myteams = Team.objects.filter(manager=request.user)

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    breadcrumbs = [
        {
            'url': reverse(plannedsessions_view),
            'name': 'Planned Sessions'
            },
        {
            'url': reverse(plannedsessions_coach_view),
            'name': 'Coach View'
            }
        ]

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate,
        })

    ttemplate = 'plannedsessionscoach.html'
    if len(rowers) > 5 and len(rowers) > len(sps):
        ttemplate = 'plannedsessionscoach2.html'


    return render(request,ttemplate,
                  {
                      'myteams':myteams,
                      'plannedsessions':sps,
                      'breadcrumbs':breadcrumbs,
                      'plan':trainingplan,
                      'statusdict':statusdict,
                      'dateform':dateform,
                      'timeperiod':timeperiod,
                      'rowers':rowers,
                      'rower':therower,
                      'active':'nav-plan',
                      'theteam':theteam,
                      'unmatchedworkouts':unmatchedworkouts,
                      'rower':getrower(request.user)
                      }
                  )

from rowers.plannedsessions import cratiocolors,checkscores

@login_required()
def plannedsessions_view(request,
                         userid=0,startdatestring='',enddatestring=''):

    r = getrequestplanrower(request,userid=userid)

    if startdatestring:
        try:
            startdate = iso8601.parse_date(startdatestring)
        except ParseError:
            pass

    if enddatestring:
        try:
            enddate = iso8601.parse_date(enddatestring)
        except ParseError:
            pass



    startdate,enddate = get_dates_timeperiod(
        request,
        startdatestring=startdatestring,
        enddatestring=enddatestring)

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None


    sps = get_sessions(r,startdate=startdate,enddate=enddate)

    completeness = {}
    actualvalue = {}
    completiondate = {}
    sessioncolor = {}

    totals = {
        'trimp':0,
        'rscore':0,
        'distance':0,
        'time':0,
        'plannedtime':0,
        'planneddistance':0,
        'plannedtrimp':0,
        'plannedrscore':0,
        'actualtime':0,
        'actualdistance':0,
        'actualtrimp':0,
        'actualrscore':0,
        }

    ws = Workout.objects.filter(
        user=r,
        date__gte=startdate,date__lte=enddate)

    for w in ws:
        thetrimp,hrtss = dataprep.workout_trimp(w)
        totals['trimp'] += thetrimp
        tss = dataprep.workout_rscore(w)[0]
        if not np.isnan(tss) and tss != 0:
            totals['rscore'] += tss
        elif tss == 0:
            totals['rscore'] += hrtss
            tss = hrtss
        totals['distance'] += w.distance
        totals['time'] += timefield_to_seconds_duration(w.duration)
        if w.plannedsession:
            if w.plannedsession.sessionmode == 'distance':
                totals['actualdistance'] += w.distance
            elif w.plannedsession.sessionmode == 'time':
                totals['actualtime'] += timefield_to_seconds_duration(w.duration)
            elif w.plannedsession.sessionmode == 'rScore':
                totals['actualrscore'] += tss
            elif w.plannedsession.sessionmode == 'TRIMP':
                totals['actualtrimp'] += thetrimp

    if not sps and request.user.rower.rowerplan == 'basic':
        messages.error(request,
                       "You must purchase Coach or Self-coach plans or be part of a team to get planned sessions")

    for ps in sps:
        ratio,status,cdate = is_session_complete(r,ps)
        actualvalue[ps.id] = int(ps.sessionvalue*ratio)
        completeness[ps.id] = status
        sessioncolor[ps.id] = cratiocolors[status]
        ws = Workout.objects.filter(user=r,plannedsession=ps)
        completiondate[ps.id] = cdate
        if ps.sessionmode == 'distance':
            totals['planneddistance'] += ps.sessionvalue
        elif ps.sessionmode == 'time':
            totals['plannedtime'] += ps.sessionvalue
        elif ps.sessionmode == 'rScore':
            totals['plannedrscore'] += ps.sessionvalue
        elif ps.sessionmode == 'TRIMP':
            totals['plannedtrimp'] += ps.sessionvalue

    totals['time'] = int(totals['time']/60.)
    totals['actualtime'] = int(totals['actualtime']/60.)
    totals['plannedtime'] = int(totals['plannedtime'])

    unmatchedworkouts = Workout.objects.filter(
        user=r,
        plannedsession=None,
        date__gte=startdate,date__lte=enddate)

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    breadcrumbs = [
        {
            'url': reverse(plannedsessions_view),
            'name': 'Planned Sessions'
            },
        ]

    initial = {
        'startdate':startdate,
        'enddate':enddate,
        }

    dateform = DateRangeForm(initial=initial)


    return render(request,'plannedsessions.html',
                  {
                      'teams':get_my_teams(request.user),
                      'breadcrumbs':breadcrumbs,
                      'plannedsessions':sps,
                      'plan':trainingplan,
                      'active': 'nav-plan',
                      'dateform':dateform,
                      'totals':totals,
                      'rower':r,
                      'timeperiod':timeperiod,
                      'completeness':completeness,
                      'sessioncolor':sessioncolor,
                      'actualvalue':actualvalue,
                      'completiondate':completiondate,
                      'unmatchedworkouts':unmatchedworkouts,
                  })

@allow_shares
#@login_required()
def plannedsessions_print_view(request,userid=0,startdatestring='',enddatestring=''):

    r = getrequestplanrower(request,userid=userid)



    startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
                                             enddatestring=enddatestring)

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    sps = get_sessions(r,startdate=startdate,enddate=enddate)

    completeness = {}
    actualvalue = {}
    completiondate = {}

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    return render(request,'plannedsessions_print.html',
                  {
                      'teams':get_my_teams(request.user),
                      'plan':trainingplan,
                      'plannedsessions':sps,
                      'rower':r,
                      'active':'nav-plan',
                      'startdate':startdate,
                      'enddate':enddate,
                      'timeperiod':timeperiod,
                  })


@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def plannedsessions_manage_view(request,userid=0,
                                initialsession=0):

    is_ajax = False
    if request.is_ajax():
        is_ajax = True

    r = getrequestrower(request,userid=userid)

    startdate,enddate = get_dates_timeperiod(request)

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    sps = get_sessions(r,startdate=startdate,enddate=enddate)
    if initialsession==0:
        try:
            initialsession=sps[0].id
        except IndexError:
            initialsession=0

    if initialsession:
        try:
            ps0 = PlannedSession.objects.get(id=initialsession)
        except PlannedSession.DoesNotExist:
            ps0 = None
    else:
        ps0 = None

    ws = Workout.objects.filter(
        user=r,date__gte=startdate,
        date__lte=enddate
    ).order_by(
        "date","startdatetime","id"
        )


    initialworkouts = [w.id for w in Workout.objects.filter(user=r,plannedsession=ps0)]

    linkedworkouts = []
    for w in ws:
        if w.plannedsession is not None:
            linkedworkouts.append(w.id)

    plannedsessionstuple = []

    for ps in sps:
        sessiontpl = (ps.id,ps.__str__())
        plannedsessionstuple.append(sessiontpl)

    plannedsessionstuple = tuple(plannedsessionstuple)

    workoutdata = {}
    workoutdata['initial'] = []

    choices = []

    for w in ws:
        wtpl = (w.id, w.__str__())
        choices.append(wtpl)
        if w.id in initialworkouts:
            workoutdata['initial'].append(w.id)

    workoutdata['choices'] = tuple(choices)

    if request.method == 'POST':
        ps_form = PlannedSessionSelectForm(plannedsessionstuple,request.POST)
        w_form = WorkoutSessionSelectForm(workoutdata,request.POST)

        if ps_form.is_valid():
            ps = PlannedSession.objects.get(id=ps_form.cleaned_data['plannedsession'])
            if w_form.is_valid():
                selectedworkouts = w_form.cleaned_data['workouts']
            else:
                selectedworkouts = []

            if len(selectedworkouts)==0:
                for w in ws:
                    remove_workout_plannedsession(w,ps)

            if selectedworkouts:
                workouts = Workout.objects.filter(user=r,id__in=selectedworkouts)
                for w in ws:
                    if w.id not in selectedworkouts:
                        remove_workout_plannedsession(w,ps)

                result,comments,errors = add_workouts_plannedsession(workouts,ps,r)
                for c in comments:
                    messages.info(request,c)
                for er in errors:
                    messages.error(request,er)



    ps_form = PlannedSessionSelectForm(plannedsessionstuple,
                                       initialsession=initialsession)
    w_form = WorkoutSessionSelectForm(workoutdata=workoutdata)


    if is_ajax:
        ajax_workouts = []
        for id,name in workoutdata['choices']:
            ininitial = id in initialworkouts
            inlinked = id in linkedworkouts
            ajax_workouts.append((id,name,ininitial,inlinked))

        ajax_response = {
            'workouts':ajax_workouts,
            'plannedsessionstuple':plannedsessionstuple,
        }


        return JSONResponse(ajax_response)


    breadcrumbs = [
        {
            'url':reverse(plannedsessions_view,
                      kwargs={'userid':userid}),
            'name': 'Plan'
        },
        {
            'url':reverse(plannedsessions_manage_view,
                          kwargs={
                              'userid':userid,
                              'initialsession':initialsession,
                          }
            ),
            'name': 'Link Sessions to Workouts'
            },
    ]

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate,
        })

    return render(request,'plannedsessionsmanage.html',
                  {
                      'teams':get_my_teams(request.user),
                      'plan':trainingplan,
                      'dateform':dateform,
                      'plannedsessions':sps,
                      'workouts':ws,
                      'active':'nav-plan',
                      'breadcrumbs':breadcrumbs,
                      'timeperiod':timeperiod,
                      'rower':r,
                      'ps_form':ps_form,
                      'w_form':w_form,
                  })


# Clone an existing planned session
# need clarity on cloning behavior time shift
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_clone_view(request,id=0,userid=0):

    r = getrequestplanrower(request,userid=userid)


    startdate,enddate = get_dates_timeperiod(request)

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    ps = get_object_or_404(PlannedSession,pk=id)

    rowers = ps.rower.all()
    teams = ps.team.all()

    ps.pk = None
    ps.id = None
    if not ps.is_template:
        ps.name += ' (copy)'
    ps.is_template = False

    deltadays = ps.preferreddate-ps.startdate

    ps.startdate = startdate
    ps.enddate = enddate
    ps.preferreddate = ps.startdate+deltadays


    ps.save()

    if rowers:
        for rower in rowers:
            add_rower_session(rower,ps)
    else:
        add_rower_session(r,ps)
    for team in teams:
        add_team_session(team,ps)

    url = reverse(plannedsession_edit_view,
                  kwargs = {
                      'id':ps.id,
                      'userid':r.user.id,
                      }
    )

    startdatestring = startdate.strftime('%Y-%m-%d')
    enddatestring = enddate.strftime('%Y-%m-%d')
    url += '?when='+startdatestring+'/'+enddatestring

    next = request.GET.get('next', url)
    return HttpResponseRedirect(next)

# Clone an existing planned session
# need clarity on cloning behavior time shift
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_teamclone_view(request,id=0):

    r = getrequestplanrower(request)

    teams = Team.objects.filter(manager=request.user)
    if teams.count()>0:
        teamchoices = [(team.id, team.name) for team in teams]
        teaminitial = [str(teams[0].id)]
    else:
        messages.info(request,"You have no teams established yet. We are redirecting you to the Team Management page.")
        url = reverse('rower_teams_view')
        return HttpResponseRedirect(url)


    startdate,enddate = get_dates_timeperiod(request)

    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    ps = get_object_or_404(PlannedSession,pk=id)


    ps.pk = None
    ps.id = None
    if not ps.is_template:
        ps.name += ' (copy)'
    ps.is_template = False

    deltadays = ps.preferreddate-ps.startdate

    ps.startdate = startdate
    ps.enddate = enddate
    ps.preferreddate = startdate+deltadays

    ps.save()

    url = reverse(plannedsession_teamedit_view,
                  kwargs = {
                      'id':ps.id,
                      'userid':r.user.id,
                      }
    )

    startdatestring = startdate.strftime('%Y-%m-%d')
    enddatestring = enddate.strftime('%Y-%m-%d')
    url += '?when='+startdatestring+'/'+enddatestring

    next = request.GET.get('next', url)
    return HttpResponseRedirect(next)

@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_templateedit_view(request,id=0):
    r = getrequestrower(request)
    startdate,enddate = get_dates_timeperiod(request)
    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    try:
        ps = PlannedSession.objects.get(id=id)
    except PlannedSession.DoesNotExist:
        raise Http404("Planned Session does not exist")

    if ps.manager != request.user:
        raise PermissionDenied("You are not allowed to edit this planned session")

    if ps.sessiontype in ['race','indoorrace']:
        raise PermissionDenied("You are not allowed to edit this planned session because it is a race")

    if not ps.is_template:
        ps.pk = None
        ps.id = None
        ps.is_template = True
        ps.startdate = datetime.date(1970,1,1)
        ps.enddate = datetime.date(1970,1,1)
        ps.team.clear()
        ps.save()

    sessioncreateform = PlannedSessionTemplateForm(instance=ps)

    if request.method == 'POST':
        sessioncreateform = PlannedSessionTemplateForm(request.POST,instance=ps)
        if sessioncreateform.is_valid():
            cd = sessioncreateform.cleaned_data
            if cd['sessionunit'] == 'min':
                cd['sessionmode'] = 'time'
            elif cd['sessionunit'] in ['km','m']:
                cd['sessionmode'] = 'distance'

            res, message = update_plannedsession(ps,cd)

            if res:
                messages.info(request,message)
            else:
                messages.error(request,message)

            url = reverse(plannedsession_templateedit_view,
                    kwargs = {
                    'id':int(ps.id),
                    })

            startdatestring = startdate.strftime('%Y-%m-%d')
            enddatestring = enddate.strftime('%Y-%m-%d')
            url += '?when='+startdatestring+'/'+enddatestring
            next = request.GET.get('next', url)
            return HttpResponseRedirect(next)

    breadcrumbs = [
        {
        'url': reverse(plannedsessions_view),
        'name': 'Sessions'
        },
        {
        'url':reverse(plannedsession_templateedit_view,
        kwargs={
        'id':id,
        }
        ),
        'name': 'Edit'
        }
        ]

    sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)

    return render(request,'plannedsessiontemplateedit.html',
                  {
                      'teams':get_my_teams(request.user),
                      'plan': trainingplan,
                      'breadcrumbs': breadcrumbs,
                      'form': sessioncreateform,
                      'active':'nav-plan',
                      'thesession': ps,
                      'sessiontemplates': sessiontemplates,
                      'rower': r,
                  })


@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_totemplate_view(request,id=0):

    r = getrequestplanrower(request)

    startdate, enddate = get_dates_timeperiod(request)

    ps = get_object_or_404(PlannedSession,pk=id)

    ps.pk = None
    ps.id = None
    ps.is_template = True
    ps.startdate = datetime.date(1970,1,1)
    ps.enddate = datetime.date(1970,1,1)
    ps.save()

    url = reverse(plannedsession_create_view,kwargs={'userid':r.user.id})

    startdatestring = startdate.strftime('%Y-%m-%d')
    enddatestring = enddate.strftime('%Y-%m-%d')
    url += '?when='+startdatestring+'/'+enddatestring

    next = request.GET.get('next', url)

    return HttpResponseRedirect(next)

# Edit an existing planned session
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def plannedsession_edit_view(request,id=0,userid=0):

    r = getrequestplanrower(request,userid=userid)



    startdate,enddate = get_dates_timeperiod(request)


    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    ps = get_object_or_404(PlannedSession,pk=id)

    if ps.team.all() or ps.rower.all().count()>1:
        url = reverse(plannedsession_teamedit_view,
                      kwargs={
                          'id':id,
                          })
        return HttpResponseRedirect(url)

    if request.method == 'POST':
        sessioncreateform = PlannedSessionForm(request.POST,instance=ps)
        if sessioncreateform.is_valid():
            cd = sessioncreateform.cleaned_data

            if cd['sessionunit'] == 'min':
                cd['sessionmode'] = 'time'
            elif cd['sessionunit'] in ['km','m']:
                cd['sessionmode'] = 'distance'



            res,message = update_plannedsession(ps,cd)

            if res:
                messages.info(request,message)
            else:
                messages.error(request,message)

            url = reverse(plannedsession_edit_view,
                          kwargs={
                              'id':int(ps.id),
                              'userid':r.user.id,
                          })

            startdatestring = startdate.strftime('%Y-%m-%d')
            enddatestring = enddate.strftime('%Y-%m-%d')
            url += '?when='+startdatestring+'/'+enddatestring

            return HttpResponseRedirect(url)
    else:
        sessioncreateform = PlannedSessionForm(instance=ps)

    sps = get_sessions(r,startdate=startdate,enddate=enddate)

    breadcrumbs = [
        {
            'url':reverse(plannedsessions_view,
                      kwargs={'userid':userid}),
            'name': 'Plan'
        },
        {
            'url': reverse(plannedsessions_view,
                           kwargs={'userid':userid}),
            'name': 'Sessions'
            },
        {
            'url':reverse(plannedsession_view,
                          kwargs={
                              'userid':userid,
                              'id':id,
                          }
            ),
            'name': ps.id
            },
        {
            'url':reverse(plannedsession_edit_view,
                          kwargs={
                              'userid':userid,
                              'id':id,
                          }
            ),
            'name': 'Edit'
            }
        ]


    sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)

    dateform = DateRangeForm(initial={
        'startdate':startdate,
        'enddate':enddate,
        })

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')

    return render(request,'plannedsessionedit.html',
                  {
                      'teams':get_my_teams(request.user),
                      'plan':trainingplan,
                      'breadcrumbs':breadcrumbs,
                      'form':sessioncreateform,
                      'active':'nav-plan',
                      'plannedsessions':sps,
                      'thesession':ps,
                      'dateform':dateform,
                      'sessiontemplates':sessiontemplates,
                      'rower':r,
                      'timeperiod':timeperiod,
                  })


@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
def plannedsession_detach_view(request,id=0,psid=0):

    r = getrequestrower(request)


    ps = get_object_or_404(PlannedSession,pk=psid)

    w = get_workout(id)

    remove_workout_plannedsession(w,ps)

    url = reverse(plannedsession_view,kwargs={'id':psid})
    next = request.GET.get('next', url)
    return HttpResponseRedirect(next)

@login_required()
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_view(request,id=0,userid=0):

    r = getrequestplanrower(request,userid=userid)

    ps = get_object_or_404(PlannedSession,pk=id)

    if ps.sessiontype in ['race','indoorrace']:
        url = reverse('virtualevent_view',
                      kwargs={'id':ps.id}
                      )
        return HttpResponseRedirect(url)

    if ps.course:
        coursescript,coursediv = course_map(ps.course)
    else:
        coursescript = ''
        coursediv = ''

    m = ps.manager
    mm = Rower.objects.get(user=m)

    resultsdict = get_session_metrics(ps)
    resultsdict = pd.DataFrame(resultsdict).transpose().to_dict()

    psdict = my_dict_from_instance(ps,PlannedSession)

    ws = get_workouts_session(r,ps)

    ratio,status,completiondate = is_session_complete(r,ps)

    ratio = int(100.*ratio)

    # ranking for test
    ranking = []

    if ps.sessiontype in ['test','coursetest']:
        if ps.sessionmode == 'distance':
            rankws = Workout.objects.filter(
                plannedsession=ps).order_by("duration")
        else:
            rankws = Workout.objects.filter(
                plannedsession=ps).order_by("-distance")
        for w in rankws:
            dd = w.duration
            dddelta = datetime.timedelta(hours=dd.hour,
                                         minutes=dd.minute,
                                         seconds=dd.second,
                                         microseconds=dd.microsecond)
            wdict = {
                'name': w.user.user.first_name+' '+w.user.user.last_name,
                'date': w.date,
                'distance': w.distance,
                'time': dddelta,
                'type': w.workouttype,
                'coursecompleted':True,
            }
            if ps.sessiontype == 'coursetest':
                vs = CourseTestResult.objects.filter(plannedsession=ps,
                                                     workoutid=w.id)

                if vs:
                    for record in vs:
                        if record.workoutid == w.id:
                            coursemeters = record.distance
                            coursecompleted = record.coursecompleted
                            t = record.duration
                            wdict['time'] = datetime.timedelta(
                                hours=t.hour,
                                seconds=t.second,
                                minutes=t.minute,
                                microseconds=t.microsecond
                            )
                            wdict['distance'] = int(round(coursemeters))
                            wdict['coursecompleted'] = coursecompleted
                else:
                    record = CourseTestResult(
                        userid=w.user.id,
                        workoutid=w.id,
                        plannedsession=ps,
                        duration=w.duration,
                        coursecompleted=False,
                        )
                    record.save()
                    job = myqueue(queue,handle_check_race_course,
                                  w.csvfilename,w.id,ps.course.id,
                                  record.id,mode='coursetest')

                    intsecs = 0
                    microsecs = 0

                    # taking workout duration plus 1 minute penalty
                    wdict['time'] = w.duration
                    wdict['distance'] = ps.course.distance
                    wdict['coursecompleted'] = False


            ranking.append(wdict)
            if ps.sessiontype == 'coursetest':
                ranking = sorted(ranking, key=lambda k: k['time'])

            # if coursetest, need to reorder the ranking

    startdate,enddate = get_dates_timeperiod(request)
    try:
        trainingplan = TrainingPlan.objects.filter(
            startdate__lte =  startdate,
            rowers = r,
            enddate__gte =  enddate)[0]
    except IndexError:
        trainingplan = None

    timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
    breadcrumbs = [
        {
            'url':reverse(plannedsessions_view,
                      kwargs={'userid':userid}),
            'name': 'Plan'
        },
        {
            'url': reverse(plannedsessions_view,
                           kwargs={'userid':userid}),
            'name': 'Sessions'
            },
        {
            'url':reverse(plannedsession_view,
                          kwargs={
                              'userid':userid,
                              'id':id,
                          }
            ),
            'name': ps.id
            }
        ]

    comments = PlannedSessionComment.objects.filter(plannedsession=ps).order_by("created")

    return render(request,'plannedsessionview.html',
                  {
                      'psdict': psdict,
                      'attrs':[
                          'name','startdate','enddate','preferreddate',
                          'sessiontype',
                          'sessionmode','criterium',
                          'sessionvalue','sessionunit','comment',
                      ],
                      'workouts': ws,
                      'active':'nav-plan',
                      'breadcrumbs':breadcrumbs,
                      'manager':mm,
                      'rower':r,
                      'ratio':ratio,
                      'plan':trainingplan,
                      'status':status,
                      'results':resultsdict,
                      'plannedsession':ps,
                      'timeperiod':timeperiod,
                      'ranking':ranking,
                      'coursescript': coursescript,
                      'coursediv': coursediv,
                      'comments': comments,
                      }
                  )

class PlannedSessionDelete(DeleteView):
    model = PlannedSession
    template_name = 'plannedsessiondeleteconfirm.html'

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(PlannedSessionDelete,self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid = 0

        context['active']= 'nav-plan'
        context['rower'] = getrequestrower(self.request,userid=userid)
        context['ps'] = self.object

        psdict = my_dict_from_instance(self.object,PlannedSession)

        context['psdict'] = psdict

        context['attrs'] = ['name','startdate','enddate','sessiontype']

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url': reverse(plannedsessions_view,
                               kwargs={'userid':userid}),
                'name': 'Sessions'
            },
            {
                'url':reverse(plannedsession_view,
                              kwargs={
                                  'userid':userid,
                                  'id':self.object.pk,
                              }
                ),
                'name': self.object.pk
            },
            {
                'url':reverse('plannedsession_delete_view',
                              kwargs={'pk':self.object.pk}),
                'name': 'Delete'
                }
        ]

        context['breadcrumbs'] = breadcrumbs

        return context

    def get_success_url(self):
        ws = Workout.objects.filter(plannedsession=self.object)
        for w in ws:
            w.plannedsession = None
            w.save()

        url = reverse(plannedsessions_view)
        next = self.request.GET.get('next',url)

        return next

    def get_object(self, *args, **kwargs):
        obj = super(PlannedSessionDelete, self).get_object(*args, **kwargs)
        if not can_delete_session(self.request.user,obj):
            raise PermissionDenied('You are not allowed to delete this planned session')

        return obj


@user_passes_test(can_plan,login_url="/rowers/paidplans",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def rower_create_trainingplan(request,id=0):
    therower = getrequestrower(request,userid=id)
    theuser = therower.user
    themanager = getrower(request.user)

    if request.method == 'POST' and 'date' in request.POST:
        targetform = TrainingTargetForm(request.POST,user=request.user)
        if targetform.is_valid():
            name = targetform.cleaned_data['name']
            date = targetform.cleaned_data['date']
            notes = targetform.cleaned_data['notes']
            try:
                rowers = targetform.cleaned_data['rowers']
            except KeyError:
                rowers = [therower]

            t = TrainingTarget(
                name=name,
                date=date,
                manager=themanager,
                notes=notes)


            t.save()
            for athlete in rowers:
                t.rowers.add(athlete)
            t.save()

    elif request.method == 'POST' and 'startdate' in request.POST:
        form = TrainingPlanForm(request.POST,user=request.user)


        if form.is_valid():
            name = form.cleaned_data['name']
            try:
                target = form.cleaned_data['target']
            except KeyError:
                try:
                    targetid = request.POST['target']
                    if targetid != '':
                        target = TrainingTarget.objects.get(id=int(targetid))
                    else:
                        target = None
                except KeyError:
                    target = None
            startdate = form.cleaned_data['startdate']
            status = form.cleaned_data['status']
            enddate = form.cleaned_data['enddate']
            notes = form.cleaned_data['notes']

            try:
                athletes = form.cleaned_data['rowers']
            except KeyError:
                athletes = [therower]

            p = TrainingPlan(
                name=name,
                target=target,
                manager=themanager,
                startdate=startdate,
                enddate=enddate,status=status,
				notes=notes,
            )

            p.save()

            for athlete in athletes:
                if can_plan_user(request.user,athlete):
                    p.rowers.add(athlete)


    targets = TrainingTarget.objects.filter(
        rowers=therower,
        date__gte=datetime.date.today(),
    ).order_by("date")

    old_targets = TrainingTarget.objects.filter(
        rowers=therower,
        date__lt=datetime.date.today(),
        ).order_by("-date")

    targetform = TrainingTargetForm(user=request.user)

    plans = TrainingPlan.objects.filter(rowers=therower).order_by("-startdate")

    plans_to_deactivate = TrainingPlan.objects.filter(
        rowers=therower,
        enddate__lt=datetime.date.today(),
        status=True,
    ).order_by("-startdate")

    for p in plans_to_deactivate:
        p.status = False
        p.save()


    form = TrainingPlanForm(targets=targets,
                            initial={'status':False,'rowers':[therower]},
                            user=request.user)

    breadcrumbs = [
        {
            'url':reverse(plannedsessions_view,
                          kwargs={'userid':id}),
            'name': 'Plan'
        },
        {
            'url':reverse(rower_create_trainingplan,
                          kwargs={'id':id}),
            'name': 'Manage Plans and Targets'
            }
        ]


    return render(request,'trainingplan_create.html',
                  {
                      'form':form,
                      'rower':therower,
                      'breadcrumbs':breadcrumbs,
                      'plans':plans,
                      'active':'nav-plan',
                      'targets':targets,
                      'targetform':targetform,
                      'old_targets':old_targets,
                      })

@user_passes_test(can_plan,login_url="/rowers/paidplans",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
@permission_required('target.delete_target',fn=get_target_by_pk,raise_exception=True)
def rower_delete_trainingtarget(request,id=0):

    target = get_object_or_404(TrainingTarget,pk=id)
    target.delete()

    url = reverse(rower_create_trainingplan)

    return HttpResponseRedirect(url)


@user_passes_test(can_plan,login_url="/rowers/paidplans",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
@permission_required('target.delete_plan',fn=get_plan_by_pk,raise_exception=True)
def rower_delete_trainingplan(request,id=0):
    plan = get_object_or_404(TrainingPlan,pk=id)
    plan.delete()

    url = reverse(rower_create_trainingplan)

    return HttpResponseRedirect(url)

class TrainingPlanDelete(DeleteView):
    model = TrainingPlan
    template_name = 'trainingplan_delete.html'
    success_url = reverse_lazy(rower_create_trainingplan)

    def get_object(self, *args, **kwargs):
        obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
        if not can_delete_plan(self.request.user,obj):
            raise PermissionDenied('You are not allowed to delete this training plan')

        return obj

class MicroCycleDelete(DeleteView):
    model = TrainingMicroCycle
    template_name = 'trainingplan_delete.html'

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(MicroCycleDelete, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.plan.plan.plan.id}),
                'name': self.object.plan.plan.plan.name
            },
            {
                'url':reverse('macrocycle_update_view',
                              kwargs={'pk':self.object.plan.plan.pk}),
                'name': self.object.plan.plan.name
                },
            {
                'url':reverse('mesocycle_update_view',
                              kwargs={'pk':self.object.plan.pk}),
                'name': self.object.plan.name
                },
            {
                'url':reverse('microcycle_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': self.object.name
                }

        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        plan = self.object.plan.plan.plan
        createmacrofillers(plan)
        thismesoid = self.object.plan.pk
        return reverse(rower_trainingplan_view,
                       kwargs = {
                           'id':plan.id,
                           'thismesoid':thismesoid
                           })

    def get_object(self, *args, **kwargs):
        obj = super(MicroCycleDelete, self).get_object(*args, **kwargs)
        if not can_delete_cycle(self.request.user,obj):
            raise PermissionDenied('You are not allowed to delete this training plan cycle')
        return obj


class MesoCycleDelete(DeleteView):
    model = TrainingMesoCycle
    template_name = 'trainingplan_delete.html'

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(MesoCycleDelete, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.plan.plan.id}),
                'name': self.object.plan.plan.name
            },
            {
                'url':reverse('macrocycle_update_view',
                              kwargs={'pk':self.object.plan.pk}),
                'name': self.object.plan.name
                },
            {
                'url':reverse('mesocycle_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': self.object.name
                }

        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        plan = self.object.plan.plan
        thismacroid = self.object.plan.pk
        createmacrofillers(plan)
        return reverse(rower_trainingplan_view,
                       kwargs = {
                           'id':plan.id,
                           'thismacroid':thismacroid,
                           })

    def get_object(self, *args, **kwargs):
        obj = super(MesoCycleDelete, self).get_object(*args, **kwargs)

        if not can_delete_cycle(self.request.user,obj):
            raise PermissionDenied('You are not allowed to delete this training plan cycle')

        return obj


class MacroCycleDelete(DeleteView):
    model = TrainingMacroCycle
    template_name = 'trainingplan_delete.html'

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(MacroCycleDelete, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.plan.id}),
                'name': self.object.plan.name
            },
            {
                'url':reverse('macrocycle_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': self.object.name
                }
        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        plan = self.object.plan
        createmacrofillers(plan)
        return reverse(rower_trainingplan_view,
                       kwargs = {
                           'id':plan.id
                           })

    def get_object(self, *args, **kwargs):
        obj = super(MacroCycleDelete, self).get_object(*args, **kwargs)
        if not can_delete_cycle(self.request.user,obj):
            raise PermissionDenied('You are not allowed to delete this training plan cycle')

        return obj


@user_passes_test(can_plan,login_url="/rowers/paidplans",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
def rower_trainingplan_execution_view(request,
                                      id=0,
                                      userid=0):

    startdate,enddate = get_dates_timeperiod(request)

    r = getrequestrower(request,userid=userid)


    if int(id)>0:
        try:
            plan = TrainingPlan.objects.get(id=id)
        except TrainingPlan.DoesNotExist:
            raise Http404("Training Plan Does Not Exist")
        if not is_coach_user(request.user,plan.manager.user):
            if request.user.rower not in plan.rowers.all():
                raise PermissionDenied("Access denied")

    if not startdate or not enddate:
        if int(id)>0:
            startdate = plan.startdate
            enddate = plan.enddate
        else:
            startdate,enddate = get_dates_timeperiod(request)
    else:
        startdate,enddate = get_dates_timeperiod(request)


    if int(id)>0:
        data,message = get_execution_report(r,startdate,enddate,plan=plan)
    else:
        data,message = get_execution_report(r,startdate,enddate)

    if not data.empty:
        script, div = interactive_planchart(data,startdate,enddate)
    else:
        script = ''
        div = ''
        messages.error(request,'The plan does not cover this time range')

    if int(id):
        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':id}),
                'name': plan.name
            },
            {
                'url':reverse(rower_trainingplan_execution_view,
                              kwargs={'userid':userid,
                                      'id':id}),
                'name': 'Execution'
            }
        ]
    else:
        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_execution_view,
                              kwargs={'userid':userid,
                                      'id':id}),
                'name': 'Execution'
            }
        ]

    return render(request,'trainingplan_chart.html',
                  {
                      'todays_date': timezone.now().date(),
                      'active': 'nav-plan',
                      'breadcrumbs':breadcrumbs,
                      'rower':r,
                      'the_script':script,
                      'the_div':div
                      }
                  )


#@user_passes_test(can_plan,login_url="/rowers/paidplans",
#                  message="This functionality requires a Coach or Self-Coach plan",
#                  redirect_field_name=None)
@login_required()
@permission_required('plan.view_plan',fn=get_plan_by_pk,raise_exception=True)
def rower_trainingplan_view(request,
                            id=0,
                            userid=0,
                            thismicroid=0,
                            thismacroid=0,
                            thismesoid=0):


    startdate,enddate = get_dates_timeperiod(request)

    plan = get_object_or_404(TrainingPlan,pk=id)
    r = getrequestrower(request,userid=userid)

    createmacrofillers(plan)
    macrocycles = TrainingMacroCycle.objects.filter(
        plan=plan,
        type='userdefined').order_by("startdate")

    checkscores(r,macrocycles)

    createmacrofillers(plan)
    macrocycles = TrainingMacroCycle.objects.filter(plan=plan).order_by("startdate")

    count = 0
    cycles = {}

    for m in macrocycles:
        createmesofillers(m)
        mesocycles = TrainingMesoCycle.objects.filter(plan=m).order_by("startdate")
        mesos = {}
        count2 = 0
        for me in mesocycles:
            createmicrofillers(me)
            microcycles = TrainingMicroCycle.objects.filter(plan=me).order_by("startdate")

            mesos[count2] = (me, microcycles)
            count2 += 1

        cycles[count] = (m,mesos)
        count += 1

    breadcrumbs = [
        {
            'url':reverse(plannedsessions_view,
                          kwargs={'userid':userid}),
            'name': 'Plan'
        },
        {
            'url':reverse(rower_trainingplan_view,
                          kwargs={'userid':userid,
                                  'id':id}),
            'name': plan.name
            }
        ]

    if not thismicroid and not thismacroid and not thismesoid:
        try:
            thismicro = get_todays_micro(plan,thedate=startdate)
            thismicroid = thismicro.pk
        except AttributeError:
            thismicroid = None


    return render(request,'trainingplan.html',
                  {
                      'plan':plan,
                      'todays_date': timezone.now().date(),
                      'active':'nav-plan',
                      'breadcrumbs':breadcrumbs,
                      'rower':r,
                      'cycles':cycles,
                      'thismicroid':thismicroid,
                      'thismacroid':thismacroid,
                      'thismesoid':thismesoid,
                      }
                  )

class TrainingMacroCycleUpdate(UpdateView):
    model = TrainingMacroCycle
    template_name = 'trainingplan_edit.html'
    form_class = TrainingMacroCycleForm

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(TrainingMacroCycleUpdate, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.plan.id}),
                'name': self.object.plan.name
            },
            {
                'url':reverse('macrocycle_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': self.object.name
                }
        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        plan = self.object.plan
        createmacrofillers(plan)
        return reverse(rower_trainingplan_view,
                       kwargs = {
                           'id':plan.id,
                           'thismacroid':self.object.id,
                       }
                       )

    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.post_date = datetime.datetime.now()
        macrocycle = form.save()
        mesocyclecheckdates(macrocycle)
        return super(TrainingMacroCycleUpdate, self).form_valid(form)

    def get_object(self, *args, **kwargs):
        obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs)
        if not can_change_cycle(self.request.user,obj):
            raise PermissionDenied('You are not allowed to edit this training plan cycle')
        else:
            obj.type = 'userdefined'
            obj.save()
        return obj

class TrainingMesoCycleUpdate(UpdateView):
    model = TrainingMesoCycle
    template_name = 'trainingplan_edit.html'
    form_class = TrainingMesoCycleForm

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(TrainingMesoCycleUpdate, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.plan.plan.id}),
                'name': self.object.plan.plan.name
            },
            {
                'url':reverse('macrocycle_update_view',
                              kwargs={'pk':self.object.plan.pk}),
                'name': self.object.plan.name
                },
            {
                'url':reverse('mesocycle_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': self.object.name
                }

        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        plan = self.object.plan
        createmesofillers(plan)
        return reverse(rower_trainingplan_view,
                       kwargs = {
                           'id':plan.plan.id,
                           'thismesoid':self.object.id,
                       }
                       )

    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.post_date = datetime.datetime.now()
        mesocycle = form.save()
        microcyclecheckdates(mesocycle)
        return super(TrainingMesoCycleUpdate, self).form_valid(form)

    def get_object(self, *args, **kwargs):
        obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs)
        if not can_change_cycle(self.request.user,obj):
            raise PermissionDenied('You are not allowed to edit this training plan cycle')

        else:
            obj.type = 'userdefined'
            obj.save()
            obj.plan.type = 'userdefined'
            obj.plan.save()
        return obj

class TrainingMicroCycleUpdate(UpdateView):
    model = TrainingMicroCycle
    template_name = 'trainingplan_edit.html'
    form_class = TrainingMicroCycleForm

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(TrainingMicroCycleUpdate, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.plan.plan.plan.id}),
                'name': self.object.plan.plan.plan.name
            },
            {
                'url':reverse('macrocycle_update_view',
                              kwargs={'pk':self.object.plan.plan.pk}),
                'name': self.object.plan.plan.name
                },
            {
                'url':reverse('mesocycle_update_view',
                              kwargs={'pk':self.object.plan.pk}),
                'name': self.object.plan.name
                },
            {
                'url':reverse('microcycle_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': self.object.name
                }

        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        plan = self.object.plan
        createmicrofillers(plan)
        return reverse(rower_trainingplan_view,
                       kwargs = {
                           'id':plan.plan.plan.id,
                           'thismicroid':self.object.pk
                       }
                       )
    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.post_date = datetime.datetime.now()
        microcycle = form.save()

        return super(TrainingMicroCycleUpdate, self).form_valid(form)

    def get_object(self, *args, **kwargs):
        obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs)
        if not can_change_cycle(self.request.user,obj):
            raise PermissionDenied('You are not allowed to edit this training plan cycle')


        else:
            obj.type = 'userdefined'
            obj.save()
            obj.plan.type = 'userdefined'
            obj.plan.save()
        return obj

class TrainingPlanUpdate(UpdateView):
    model = TrainingPlan
    template_name = 'trainingplan_edit.html'
    form_class = TrainingPlanForm

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(TrainingPlanUpdate, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse(rower_trainingplan_view,
                              kwargs={'userid':userid,
                                      'id':self.object.id}),
                'name': self.object.name
            },
            {
                'url':reverse('trainingplan_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': 'Edit'
                }

        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        return reverse(rower_create_trainingplan)

    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.post_date = datetime.datetime.now()
        plan = form.save()
        plan.manager = self.request.user.rower
        plan.save()
        macrocyclecheckdates(plan)
        return super(TrainingPlanUpdate, self).form_valid(form)

    def get_object(self, *args, **kwargs):
        obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs)
        if not can_change_plan(self.request.user,obj):
            raise PermissionDenied('You are not allowed to edit this training plan cycle')

        return obj

class TrainingTargetUpdate(UpdateView):
    model = TrainingTarget
    template_name = 'trainingplan_edit.html'
    form_class = TrainingTargetForm

    # extra parameters
    def get_context_data(self, **kwargs):
        context = super(TrainingTargetUpdate, self).get_context_data(**kwargs)

        if 'userid' in kwargs:
            userid = kwargs['userid']
        else:
            userid=0

        breadcrumbs = [
            {
                'url':reverse(plannedsessions_view,
                              kwargs={'userid':userid}),
                'name': 'Plan'
            },
            {
                'url':reverse('trainingtarget_update_view',
                              kwargs={'pk':self.object.pk}),
                'name': 'Edit'
                }

        ]

        context['active'] = 'nav-plan'
        context['breadcrumbs'] = breadcrumbs
        context['rower'] = getrequestrower(self.request,userid=userid)

        return context

    def get_success_url(self):
        return reverse(rower_create_trainingplan)

    def form_valid(self, form):
        form.instance.user = self.request.user
        form.instance.post_date = datetime.datetime.now()
        target = form.save()
        return super(TrainingTargetUpdate, self).form_valid(form)

    def get_object(self, *args, **kwargs):
        obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs)
        if not can_change_target(self.request.user,obj):
            raise PermissionDenied('You are not allowed to edit this training plan cycle')

        return obj

from rowers.utils import allsundays

@user_passes_test(can_plan,login_url="/rowers/paidplans",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
@permission_required('cycle.change_cycle',fn=get_meso_by_pk,raise_exception=True)
def planmesocyclebyweek(request,id=0,userid=0):
    cycle = get_object_or_404(TrainingMesoCycle,pk=id)

    micros = TrainingMicroCycle.objects.filter(plan=cycle)
    for m in micros:
        m.delete()

    cycle.type = 'userdefined'
    cycle.save()

    #we're still here. We have permission
    sundays = [s for s in allsundays(cycle.startdate,cycle.enddate)]

    if sundays and sundays[-1] < cycle.enddate:
        sundays = sundays+[cycle.enddate]
    elif not sundays:
        sundays = [cycle.enddate]

    for i in range(len(sundays)):
        if i==0:
            monday = cycle.startdate
        else:
            monday = sundays[i]-timedelta(days=6)
            if monday < cycle.startdate:
                monday = cycle.startdate

        nextsunday = sundays[i]

        micro = TrainingMicroCycle(startdate = monday,
                                   enddate = nextsunday,
                                   plan = cycle,
                                   name = 'Week %s' % monday.isocalendar()[1],
                                   type = 'userdefined')
        micro.save()

    micros = TrainingMicroCycle.objects.filter(plan=cycle)

    url = reverse(rower_trainingplan_view,
                  kwargs = {'userid':str(userid),
                            'id':str(cycle.plan.plan.id),
                            'thismicroid':str(micros[0].id)})

    return HttpResponseRedirect(url)

from rowers.utils import allmonths

@user_passes_test(can_plan,login_url="/rowers/paidplans",
                  message="This functionality requires a Coach or Self-Coach plan",
                  redirect_field_name=None)
@permission_required('cycle.change_cycle',fn=get_macro_by_pk,raise_exception=True)
def planmacrocyclebymonth(request,id=0,userid=0):
    cycle = get_object_or_404(TrainingMacroCycle,pk=id)

    mesos = TrainingMesoCycle.objects.filter(plan=cycle)
    for m in mesos:
        m.delete()

    cycle.type = 'userdefined'
    cycle.save()

    #we're still here. We have permission
    monthstarts = [d for d in allmonths(cycle.startdate,cycle.enddate)]
    monthstarts.append(cycle.enddate)
    for i in range(len(monthstarts)-1):
        firstday = monthstarts[i]
        lastday = monthstarts[i+1]-timedelta(days=1)
        if lastday < cycle.enddate and i == len(monthstarts)-2:
            lastday = cycle.enddate


        meso = TrainingMesoCycle(startdate = firstday,
                                   enddate = lastday,
                                   plan = cycle,
                                   name = '%s' % firstday.strftime("%B"),
                                   type = 'userdefined')
        meso.save()

    mesos = TrainingMesoCycle.objects.filter(plan=cycle)

    url = reverse(rower_trainingplan_view,
                  kwargs = {'userid':str(userid),
                            'id':str(cycle.plan.id),
                            'thismesoid':str(mesos[0].id)})

    return HttpResponseRedirect(url)
