#!/usr/bin/env python

""" SchwarzerWolf.cc

**************************
*date = '2017-10-30'     *
*module_version = '0.0.3'*
**************************

***********************************************************************
*[KSFH - Kraftsport und Fitness Helfer]                               *
*Module -> './modules/one_rep_max.py'                                 *
*                                                                     *
*Copyleft [2017] - [SchwarzerWolf.cc]                                 *
*This program is free software: you can redistribute it and/or modify *
*it under the terms of the GNU General Public License as published by *
*the Free Software Foundation, either version 3 of the License, or    *
*(at your option) any later version.                                  *
*                                                                     *
*This program is distributed in the hope that it will be useful,      *
*but WITHOUT ANY WARRANTY; without even the implied warranty of       *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
*GNU General Public License for more details.                         *
*                                                                     *
*You should have received a copy of the GNU General Public License    *
*along with this program.  If not, see <http://www.gnu.org/licenses/>.*
***********************************************************************
"""


# Imports
# ******************
import tkinter as tk
# ******************


class OneRepMax(tk.Frame):
    def __init__(self, nb):
        tk.Frame.__init__(self, master=nb)

        # Center text
        self.grid_columnconfigure(0, weight=1)
        self.configure(background='#000000')

        # Inputs
        self.train_weight_input = tk.Entry()
        self.train_reps_input = tk.Entry()

        # Outputs
        self.var_one = tk.StringVar()
        self.var_five = tk.StringVar()
        self.var_ten = tk.StringVar()
        self.var_twelve = tk.StringVar()
        self.var_fifteen = tk.StringVar()

        var_tuple = self.var_tuple()
        reps_tuple = self.reps_tuple()

        # Output data
        for x_one, x_two in (zip(var_tuple, reps_tuple)):
            x_one.set('{0:2d}: {1:10.2f} kg'.format(x_two, 0.0))

        # Methods
        self.gui()

    def gui(self):
        """ Starts all gui methods.

        :return:
        """

        # Methods
        self.gui_main()
        self.gui_training_data()
        self.gui_result()

    def gui_main(self):
        """ The main gui.

        Contains everything that is not in a frame (except the
        frames themselves).

        :return:
        """

        title = tk.Label(master=self,
                         text='1RM - Maximalkraftrechner',
                         font=('Helvetica', 18),
                         bg='#000000',
                         fg='#ffffff',
                         pady=15)

        analyse = tk.Button(master=self,
                            text='Analyse',
                            bg='#000000',
                            fg='#ffffff',
                            font=('Helvetica', 11),
                            command=self.button_analyse)

        # Grids
        title.grid(row=0)
        analyse.grid(row=10)

    def gui_training_data(self):
        """ Framework for training data.

        :return:
        """

        training_data_frame = tk.LabelFrame(master=self,
                                            font=('Helvetica', 11),
                                            text='Trainingsdaten',
                                            bg='#000000',
                                            fg='#ffffff',
                                            pady=10,
                                            padx=10)

        training_weight_label = tk.Label(master=training_data_frame,
                                         text='Gewicht (kg): ',
                                         bg='#000000',
                                         fg='#ffffff',
                                         font=('Helvetica', 11))

        self.train_weight_input = tk.Entry(master=training_data_frame,
                                           width=8,
                                           bg='#000000',
                                           fg='#ffffff',
                                           font=('Helvetica', 11),
                                           insertbackground='#ffffff')

        training_reps_label = tk.Label(master=training_data_frame,
                                       text='Wiederholungen: ',
                                       bg='#000000',
                                       fg='#ffffff',
                                       font=('Helvetica', 11))

        self.train_reps_input = tk.Entry(master=training_data_frame,
                                         font=('Helvetica', 11),
                                         width=8,
                                         bg='#000000',
                                         fg='#ffffff',
                                         insertbackground='#ffffff')

        # Grids
        training_data_frame.grid(row=1)
        training_weight_label.grid(row=2, column=0, sticky=tk.W)
        self.train_weight_input.grid(row=2, column=1)
        training_reps_label.grid(row=3, column=0)
        self.train_reps_input.grid(row=3, column=1)

    def gui_result(self):
        """ Shows the result of the analysis

        :return:
        """

        rep_max_frame = tk.LabelFrame(
            master=self,
            font=('Helvetica', 11),
            text='Statische Maximalkraft\nbei X Wiederholungen',
            bg='#000000',
            fg='#ffffff',
            pady=10,
            padx=10)

        output_one = tk.Label(master=rep_max_frame,
                              textvariable=self.var_one,
                              bg='#000000',
                              fg='#ffffff',
                              font=('Helvetica', 11))

        output_five = tk.Label(master=rep_max_frame,
                               textvariable=self.var_five,
                               bg='#000000',
                               fg='#ffffff',
                               font=('Helvetica', 11))

        output_ten = tk.Label(master=rep_max_frame,
                              textvariable=self.var_ten,
                              bg='#000000',
                              fg='#ffffff',
                              font=('Helvetica', 11))

        output_twelve = tk.Label(master=rep_max_frame,
                                 textvariable=self.var_twelve,
                                 bg='#000000',
                                 fg='#ffffff',
                                 font=('Helvetica', 11))

        output_fifteen = tk.Label(master=rep_max_frame,
                                  textvariable=self.var_fifteen,
                                  bg='#000000',
                                  fg='#ffffff',
                                  font=('Helvetica', 11))

        # Grids
        rep_max_frame.grid(row=4, pady=15)
        output_one.grid(row=5)
        output_five.grid(row=6)
        output_ten.grid(row=7)
        output_twelve.grid(row=8)
        output_fifteen.grid(row=9)

    def button_analyse(self):
        """ Executes methods after the button is pressed.

        :return:
        """

        self.calculate()
        self.output()

    def var_tuple(self):
        """ Includes a tuple of the complete 'tk.Stringvars'

        :return: var_list
        """

        var_tuple = (self.var_one, self.var_five, self.var_ten,
                     self.var_twelve, self.var_fifteen)

        return var_tuple

    @staticmethod
    def reps_tuple():
        """ Returns a tuple with the reps.

        :return: reps_tuple
        """

        reps_tuple = (1, 5, 10, 12, 15)

        return reps_tuple

    def calculate(self):
        """  calculates the rep max.

        calculates the rep max from the given user data for
        1, 5, 10, 12, 15 repetitions and ->

        :return: Rep max list with the values.
        """

        # Table for the rep max values
        rep_max = []

        # Get values
        try:
            weight = float(self.train_weight_input.get().replace(',', '.'))
        except ValueError:
            weight = 0.0

        try:
            reps = int(self.train_reps_input.get().replace(',', '.'))
        except ValueError:
            reps = 0

        # Get repetitions
        reps_tuple = self.reps_tuple()

        # Brzycki formula for rep max statistic
        brzycki_formula = weight / (1.0278 - (0.0278 * reps))

        # Calculation for the various repetitions
        for value in reps_tuple:
            rep_max.append(brzycki_formula * (1.0278 - (0.0278 * value)))

        return rep_max

    def output(self):
        """ Output the data.

        :return:
        """

        # Get the calculated and reps_set data for the output
        rep_max = self.calculate()
        reps_tuple = self.reps_tuple()

        # Get var_tuple
        var_tuple = self.var_tuple()

        # Output data
        for x_one, x_two, x_three in (zip(rep_max, var_tuple, reps_tuple)):
            x_two.set('{0:2d}: {1:8.2f} kg'.format(x_three, x_one))
