package objects;

import java.util.AbstractMap.SimpleEntry;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import controllers.DatabaseController;
import controllers.NewTab.DriverController;
import controllers.NewTab.EkipageController;
import controllers.NewTab.HorseController;
import database.Database;
import database.DriverDB;
import database.Ekipage;
import database.Horse;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TableView.TableViewSelectionModel;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.util.Callback;

public class NewTabRaceTableView extends Tab {

    private final List<HorseRaceData> trackRaces;

    TabPane racesTabs = new TabPane();

    private ComparingResultsData firstSelection;

    private final boolean updateSelection = true;

    private int backupIndex;

    private ComparingResultsData lastSelected;

    private VBox betSlip;

    public NewTabRaceTableView(SimpleEntry<String, List<HorseRaceData>> trackRaces) {

        setText(trackRaces.getKey());
        this.trackRaces = trackRaces.getValue();
        final List<Integer> raceNumbers
                = this.trackRaces.stream().map(m -> m.getRaceNumber()).distinct().collect(Collectors.toList());

        racesTabs.setTabMinWidth(30.0);
        this.setContent(racesTabs);

        for (final Integer rn : raceNumbers) {
            addRaceNumberTab(rn,
                    ComparingResultsData.convertHorseRaceDataList(
                            this.trackRaces.stream().filter(p -> p.getRaceNumber() == rn).collect(Collectors.toList())));
        }
    }

    private void addRaceNumberTab(Integer rn, List<ComparingResultsData> races) {
        final DatabaseController db = DatabaseController.getInstance();
        final List<Integer> distances = races.stream().map(m -> m.getDistance()).distinct().collect(Collectors.toList());

        final List<LaneWinObject> laneWinPercents;
        if (races.get(0).getTimeModifier().contains("a")) {
            laneWinPercents = db.getAutostartWinPercents(distances);
        } else {
            laneWinPercents = db.getVoltstartWinPercents(distances);
        }

        for (final ComparingResultsData data : races) {
            final Optional<LaneWinObject> laneWin = laneWinPercents.stream()
                    .filter(p -> p.getDistance() == data.getDistance() && p.getLane() == data.getLane()).findFirst();
            if (laneWin.isPresent()) {
                data.setLaneWin(laneWin.get().getPercent());
            } else {
                data.setLaneWin(0);
            }
        }

        final Tab raceNumTab = new Tab(rn.toString());
        raceNumTab.setClosable(false);
        raceNumTab.setStyle("");

        final TableView<ComparingResultsData> theTable = createTable();

        theTable.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
            final TableViewSelectionModel<ComparingResultsData> selectionModel = theTable.getSelectionModel();
            final ObservableList<ComparingResultsData> selectedItems = selectionModel.getSelectedItems();

            if (selectedItems.size() > 2) {
                selectionModel.clearSelection(theTable.getItems().indexOf(lastSelected));
            }

            lastSelected = newSelection;

            final HorseController horseController = HorseController.getController();
            final DriverController driverController = DriverController.getController();
            final EkipageController ekipageController = EkipageController.getController();

            driverController.setDriverName(newSelection.getDriverName());
            horseController.setHorseName(newSelection.getHorseName());
            final Horse horseDb = Horse.getInstance();
            final DriverDB driverDb = DriverDB.getInstance();
            final Ekipage ekipageDb = Ekipage.getInstance();

            final Database databaseb = Database.getDatabase();

            if (selectedItems.size() == 2) {
                final ComparingResultsData firstSel
                        = selectedItems.stream().filter(p -> !p.equals(newSelection)).collect(Collectors.toList()).get(0);

                horseController.setAvgTimeLabel(horseDb.avarageTime(firstSel.getHorseId(), firstSel.getRaceDate()),
                        databaseb.getAvgTime(),
                        horseDb.avarageTime(newSelection.getHorseId(), newSelection.getRaceDate()));

                horseController.setAvgTimeLimit5Label(
                        horseDb.avarageTimeWithLimit(firstSel.getHorseId(), 5, firstSel.getRaceDate()),
                        horseDb.getAvgTimeWithLimit(5),
                        horseDb.avarageTimeWithLimit(newSelection.getHorseId(), 5, newSelection.getRaceDate()));

                horseController.setAvgTimeLimit10Label(
                        horseDb.avarageTimeWithLimit(firstSel.getHorseId(), 10, firstSel.getRaceDate()),
                        horseDb.getAvgTimeWithLimit(10),
                        horseDb.avarageTimeWithLimit(newSelection.getHorseId(), 10, newSelection.getRaceDate()));

                horseController.setAvgTimeLimit15Label(
                        horseDb.avarageTimeWithLimit(firstSel.getHorseId(), 15, firstSel.getRaceDate()),
                        horseDb.getAvgTimeWithLimit(15),
                        horseDb.avarageTimeWithLimit(newSelection.getHorseId(), 15, newSelection.getRaceDate()));

                horseController.setAvgTimeDistanceLabel(
                        horseDb.avarageTimeByDistance(firstSel.getHorseId(), firstSel.getDistance(), firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistance(newSelection.getDistance()),
                        horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                newSelection.getRaceDate()));

                horseController.setAvgTimeDistance5LabelWithCompare(
                        horseDb.avarageTimeByDistance(firstSel.getHorseId(), firstSel.getDistance(), 5, firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 5),
                        horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()));

                horseController.setAvgTimeDistanceLimit10Label(
                        horseDb.avarageTimeByDistance(firstSel.getHorseId(), firstSel.getDistance(), 10, firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 10),
                        horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()));
                horseController.setAvgTimeDistanceLimit15Label(
                        horseDb.avarageTimeByDistance(firstSel.getHorseId(), firstSel.getDistance(), 15, firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 15),
                        horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()));

                horseController.setAvgPosition(horseDb.avaragePlacement(firstSel.getHorseId(), firstSel.getRaceDate()),
                        horseDb.avaragePlacement(newSelection.getHorseId(), newSelection.getRaceDate()));
                horseController.setAvgPositionLast5(
                        horseDb.avaragePlacementWithLimit(firstSel.getHorseId(), 5, firstSel.getRaceDate()),
                        horseDb.avaragePlacementWithLimit(newSelection.getHorseId(), 5, newSelection.getRaceDate()));

                horseController.setAvgPositionLast10(
                        horseDb.avaragePlacementWithLimit(firstSel.getHorseId(), 10, firstSel.getRaceDate()),
                        horseDb.avaragePlacementWithLimit(newSelection.getHorseId(), 10, newSelection.getRaceDate()));
                horseController.setAvgPositionLast15(
                        horseDb.avaragePlacementWithLimit(firstSel.getHorseId(), 15, firstSel.getRaceDate()),
                        horseDb.avaragePlacementWithLimit(newSelection.getHorseId(), 15, newSelection.getRaceDate()));

                horseController.setAvgPositionDistanceLast5(horseDb
                        .avaragePlacementByDistance(firstSel.getHorseId(), firstSel.getDistance(), 5, firstSel.getRaceDate()),
                        horseDb.avaragePlacementByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()));

                horseController.setAvgPositionDistanceLast10(horseDb
                        .avaragePlacementByDistance(firstSel.getHorseId(), firstSel.getDistance(), 10, firstSel.getRaceDate()),
                        horseDb.avaragePlacementByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()));

                horseController.setAvgPositionDistanceLast15(horseDb
                        .avaragePlacementByDistance(firstSel.getHorseId(), firstSel.getDistance(), 15, firstSel.getRaceDate()),
                        horseDb.avaragePlacementByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()));

                // Driver

                driverController.setAvgTimeLabel(driverDb.avarageTime(firstSel.getDriverId(), firstSel.getRaceDate()),
                        databaseb.getAvgTime(),
                        driverDb.avarageTime(newSelection.getDriverId(), newSelection.getRaceDate()));

                driverController.setAvgTimeLimit5Label(
                        driverDb.avarageTimeWithLimit(firstSel.getDriverId(), 5, firstSel.getRaceDate()),
                        driverDb.getAvgTimeWithLimit(5),
                        driverDb.avarageTimeWithLimit(newSelection.getDriverId(), 5, newSelection.getRaceDate()));

                driverController.setAvgTimeLimit10Label(
                        driverDb.avarageTimeWithLimit(firstSel.getDriverId(), 10, firstSel.getRaceDate()),
                        driverDb.getAvgTimeWithLimit(10),
                        driverDb.avarageTimeWithLimit(newSelection.getDriverId(), 10, newSelection.getRaceDate()));

                driverController.setAvgTimeLimit15Label(
                        driverDb.avarageTimeWithLimit(firstSel.getDriverId(), 15, firstSel.getRaceDate()),
                        driverDb.getAvgTimeWithLimit(15),
                        driverDb.avarageTimeWithLimit(newSelection.getDriverId(), 15, newSelection.getRaceDate()));

                driverController.setAvgTimeDistanceLabel(
                        driverDb.avarageTimeByDistance(firstSel.getDriverId(), firstSel.getDistance(), firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistance(newSelection.getDistance()),
                        driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                newSelection.getRaceDate()));

                driverController.setAvgTimeDistance5LabelWithCompare(
                        driverDb.avarageTimeByDistance(firstSel.getDriverId(), firstSel.getDistance(), 5, firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 5),
                        driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()));

                driverController.setAvgTimeDistanceLimit10Label(driverDb
                        .avarageTimeByDistance(firstSel.getDriverId(), firstSel.getDistance(), 10, firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 10),
                        driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()));
                driverController.setAvgTimeDistanceLimit15Label(driverDb
                        .avarageTimeByDistance(firstSel.getDriverId(), firstSel.getDistance(), 15, firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 15),
                        driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()));

                driverController.setAvgPosition(driverDb.avaragePlacement(firstSel.getDriverId(), firstSel.getRaceDate()),
                        driverDb.avaragePlacement(newSelection.getDriverId(), newSelection.getRaceDate()));
                driverController.setAvgPositionLast5(
                        driverDb.avaragePlacementWithLimit(firstSel.getDriverId(), 5, firstSel.getRaceDate()),
                        driverDb.avaragePlacementWithLimit(newSelection.getDriverId(), 5, newSelection.getRaceDate()));
                driverController.setAvgPositionLast10(
                        driverDb.avaragePlacementWithLimit(firstSel.getDriverId(), 10, firstSel.getRaceDate()),
                        driverDb.avaragePlacementWithLimit(newSelection.getDriverId(), 10, newSelection.getRaceDate()));
                driverController.setAvgPositionLast15(
                        driverDb.avaragePlacementWithLimit(firstSel.getDriverId(), 15, firstSel.getRaceDate()),
                        driverDb.avaragePlacementWithLimit(newSelection.getDriverId(), 15, newSelection.getRaceDate()));

                driverController.setAvgPositionDistanceLast5(driverDb
                        .avaragePlacementByDistance(firstSel.getDriverId(), firstSel.getDistance(), 5, firstSel.getRaceDate()),
                        driverDb.avaragePlacementByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()));

                driverController.setAvgPositionDistanceLast10(driverDb
                        .avaragePlacementByDistance(firstSel.getDriverId(), firstSel.getDistance(), 10, firstSel.getRaceDate()),
                        driverDb.avaragePlacementByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()));

                driverController.setAvgPositionDistanceLast15(driverDb
                        .avaragePlacementByDistance(firstSel.getDriverId(), firstSel.getDistance(), 15, firstSel.getRaceDate()),
                        driverDb.avaragePlacementByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()));

                // Ekipage

                ekipageController.setAvgTimeLabel(
                        ekipageDb.avarageTime(firstSel.getDriverId(), firstSel.getHorseId(), firstSel.getRaceDate()),
                        databaseb.getAvgTime(),
                        ekipageDb.avarageTime(newSelection.getDriverId(), newSelection.getHorseId(), newSelection.getRaceDate()));

                ekipageController.setAvgTimeLimit5Label(
                        ekipageDb.avarageTimeWithLimit(firstSel.getDriverId(), firstSel.getHorseId(), 5, firstSel.getRaceDate()),
                        databaseb.getAvgTimeWithLimit(5),
                        ekipageDb.avarageTimeWithLimit(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                5,
                                newSelection.getRaceDate()));

                ekipageController.setAvgTimeLimit10Label(
                        ekipageDb.avarageTimeWithLimit(firstSel.getDriverId(), firstSel.getHorseId(), 10, firstSel.getRaceDate()),
                        databaseb.getAvgTimeWithLimit(10),
                        ekipageDb.avarageTimeWithLimit(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                10,
                                newSelection.getRaceDate()));

                ekipageController.setAvgTimeLimit15Label(
                        ekipageDb.avarageTimeWithLimit(firstSel.getDriverId(), firstSel.getHorseId(), 15, firstSel.getRaceDate()),
                        databaseb.getAvgTimeWithLimit(15),
                        ekipageDb.avarageTimeWithLimit(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                15,
                                newSelection.getRaceDate()));

                ekipageController.setAvgTimeDistanceLabel(
                        ekipageDb.avarageTimeByDistance(firstSel.getDriverId(),
                                firstSel.getHorseId(),
                                firstSel.getDistance(),
                                firstSel.getRaceDate()),
                        databaseb.getAvgTimeByDistance(newSelection.getDistance()),
                        ekipageDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                newSelection.getRaceDate()));

                ekipageController.setAvgTimeDistance5LabelWithCompare(
                        ekipageDb.avarageTimeByDistance(firstSel
                                .getDriverId(), firstSel.getHorseId(), firstSel.getDistance(), 5, newSelection.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 5),
                        ekipageDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                5,
                                firstSel.getRaceDate()));

                ekipageController.setAvgTimeDistanceLimit10Label(
                        ekipageDb.avarageTimeByDistance(firstSel
                                .getDriverId(), firstSel.getHorseId(), firstSel.getDistance(), 10, newSelection.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 10),
                        ekipageDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                10,
                                firstSel.getRaceDate()));
                ekipageController.setAvgTimeDistanceLimit15Label(
                        ekipageDb.avarageTimeByDistance(firstSel
                                .getDriverId(), firstSel.getHorseId(), firstSel.getDistance(), 15, newSelection.getRaceDate()),
                        databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 15),
                        ekipageDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                15,
                                firstSel.getRaceDate()));

                ekipageController.setAvgPosition(
                        ekipageDb.avaragePlacement(firstSel.getDriverId(), firstSel.getHorseId(), firstSel.getRaceDate()),
                        ekipageDb.avaragePlacement(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getRaceDate()));
                ekipageController.setAvgPositionLast5(ekipageDb
                        .avaragePlacementWithLimit(firstSel.getDriverId(), firstSel.getHorseId(), 5, firstSel.getRaceDate()),
                        ekipageDb.avaragePlacementWithLimit(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                5,
                                newSelection.getRaceDate()));
                ekipageController.setAvgPositionLast10(ekipageDb
                        .avaragePlacementWithLimit(firstSel.getDriverId(), firstSel.getHorseId(), 10, firstSel.getRaceDate()),
                        ekipageDb.avaragePlacementWithLimit(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                10,
                                newSelection.getRaceDate()));
                ekipageController.setAvgPositionLast15(ekipageDb
                        .avaragePlacementWithLimit(firstSel.getDriverId(), firstSel.getHorseId(), 15, firstSel.getRaceDate()),
                        ekipageDb.avaragePlacementWithLimit(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                15,
                                newSelection.getRaceDate()));

                ekipageController.setAvgPositionDistanceLast5(
                        ekipageDb.avaragePlacementByDistance(firstSel
                                .getDriverId(), firstSel.getHorseId(), firstSel.getDistance(), 5, firstSel.getRaceDate()),
                        ekipageDb.avaragePlacementByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()));

                ekipageController.setAvgPositionDistanceLast10(
                        ekipageDb.avaragePlacementByDistance(firstSel
                                .getDriverId(), firstSel.getHorseId(), firstSel.getDistance(), 10, firstSel.getRaceDate()),
                        ekipageDb.avaragePlacementByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()));

                ekipageController.setAvgPositionDistanceLast15(
                        ekipageDb.avaragePlacementByDistance(firstSel
                                .getDriverId(), firstSel.getHorseId(), firstSel.getDistance(), 15, firstSel.getRaceDate()),
                        ekipageDb.avaragePlacementByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()));
            } else {
                horseController.setAvgTimeLabel(
                        String.valueOf(horseDb.avarageTime(newSelection.getHorseId(), newSelection.getRaceDate())) + "("
                                + String.valueOf(databaseb.getAvgTime()) + ")");

                horseController.setAvgTimeLimit5Label(
                        horseDb.avarageTimeWithLimit(newSelection.getHorseId(), 5, newSelection.getRaceDate()));
                horseController.setAvgTimeLimit10Label(
                        horseDb.avarageTimeWithLimit(newSelection.getHorseId(), 10, newSelection.getRaceDate()));
                horseController.setAvgTimeLimit15Label(
                        horseDb.avarageTimeWithLimit(newSelection.getHorseId(), 15, newSelection.getRaceDate()));

                horseController.setAvgTimeDistanceLabel(String.valueOf(horseDb
                        .avarageTimeByDistance(newSelection.getHorseId(), newSelection.getDistance(), newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistance(newSelection.getDistance())) + ")");
                horseController.setAvgTimeDistanceLimit5Label(String
                        .valueOf(horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 5)) + ")");
                horseController.setAvgTimeDistanceLimit10Label(String
                        .valueOf(horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 10)) + ")");
                horseController.setAvgTimeDistanceLimit15Label(String
                        .valueOf(horseDb.avarageTimeByDistance(newSelection.getHorseId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 15)) + ")");

                horseController.setAvgPosition(
                        String.valueOf(horseDb.avaragePlacement(newSelection.getHorseId(), newSelection.getRaceDate())));

                horseController.setAvgPositionLast5(String
                        .valueOf(horseDb.avaragePlacementWithLimit(newSelection.getHorseId(), 5, newSelection.getRaceDate())));
                horseController.setAvgPositionLast10(String
                        .valueOf(horseDb.avaragePlacementWithLimit(newSelection.getHorseId(), 10, newSelection.getRaceDate())));
                horseController.setAvgPositionLast15(String
                        .valueOf(horseDb.avaragePlacementWithLimit(newSelection.getHorseId(), 15, newSelection.getRaceDate())));

                horseController.setAvgPositionDistanceLast5(String.valueOf(horseDb.avaragePlacementByDistance(newSelection
                        .getHorseId(), newSelection.getDistance(), 5, newSelection.getRaceDate())));
                horseController.setAvgPositionDistanceLast10(String.valueOf(horseDb.avaragePlacementByDistance(newSelection
                        .getHorseId(), newSelection.getDistance(), 10, newSelection.getRaceDate())));
                horseController.setAvgPositionDistanceLast15(String.valueOf(horseDb.avaragePlacementByDistance(newSelection
                        .getHorseId(), newSelection.getDistance(), 15, newSelection.getRaceDate())));

                driverController.setAvgTimeLabel(
                        String.valueOf(driverDb.avarageTime(newSelection.getDriverId(), newSelection.getRaceDate())) + "("
                                + String.valueOf(databaseb.getAvgTime()) + ")");

                driverController.setAvgTimeLimit5Label(
                        driverDb.avarageTimeWithLimit(newSelection.getDriverId(), 5, newSelection.getRaceDate()));
                driverController.setAvgTimeLimit10Label(
                        driverDb.avarageTimeWithLimit(newSelection.getDriverId(), 10, newSelection.getRaceDate()));
                driverController.setAvgTimeLimit15Label(
                        driverDb.avarageTimeWithLimit(newSelection.getDriverId(), 15, newSelection.getRaceDate()));

                driverController.setAvgTimeDistanceLabel(String
                        .valueOf(driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistance(newSelection.getDistance())) + ")");
                driverController.setAvgTimeDistanceLimit5Label(String
                        .valueOf(driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                5,
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 5)) + ")");
                driverController.setAvgTimeDistanceLimit10Label(String
                        .valueOf(driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                10,
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 10)) + ")");
                driverController.setAvgTimeDistanceLimit15Label(String
                        .valueOf(driverDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getDistance(),
                                15,
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 15)) + ")");

                driverController.setAvgPosition(
                        String.valueOf(driverDb.avaragePlacement(newSelection.getDriverId(), newSelection.getRaceDate())));

                driverController.setAvgPositionLast5(String
                        .valueOf(driverDb.avaragePlacementWithLimit(newSelection.getDriverId(), 5, newSelection.getRaceDate())));
                driverController.setAvgPositionLast10(String
                        .valueOf(driverDb.avaragePlacementWithLimit(newSelection.getDriverId(), 10, newSelection.getRaceDate())));
                driverController.setAvgPositionLast15(String
                        .valueOf(driverDb.avaragePlacementWithLimit(newSelection.getDriverId(), 15, newSelection.getRaceDate())));

                driverController.setAvgPositionDistanceLast5(String.valueOf(driverDb.avaragePlacementByDistance(newSelection
                        .getDriverId(), newSelection.getDistance(), 5, newSelection.getRaceDate())));
                driverController.setAvgPositionDistanceLast10(String.valueOf(driverDb.avaragePlacementByDistance(newSelection
                        .getDriverId(), newSelection.getDistance(), 10, newSelection.getRaceDate())));
                driverController.setAvgPositionDistanceLast15(String.valueOf(driverDb.avaragePlacementByDistance(newSelection
                        .getDriverId(), newSelection.getDistance(), 15, newSelection.getRaceDate())));

                ekipageController.setAvgTimeLabel(String.valueOf(
                        ekipageDb.avarageTime(newSelection.getDriverId(), newSelection.getHorseId(), newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTime()) + ")");

                ekipageController.setAvgTimeLimit5Label(ekipageDb.avarageTimeWithLimit(newSelection.getDriverId(),
                        newSelection.getHorseId(),
                        5,
                        newSelection.getRaceDate()));
                ekipageController.setAvgTimeLimit10Label(ekipageDb.avarageTimeWithLimit(newSelection.getDriverId(),
                        newSelection.getHorseId(),
                        10,
                        newSelection.getRaceDate()));
                ekipageController.setAvgTimeLimit15Label(ekipageDb.avarageTimeWithLimit(newSelection.getDriverId(),
                        newSelection.getHorseId(),
                        15,
                        newSelection.getRaceDate()));

                ekipageController.setAvgTimeDistanceLabel(String
                        .valueOf(ekipageDb.avarageTimeByDistance(newSelection.getDriverId(),
                                newSelection.getHorseId(),
                                newSelection.getDistance(),
                                newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistance(newSelection.getDistance())) + ")");
                ekipageController.setAvgTimeDistanceLimit5Label(String.valueOf(ekipageDb.avarageTimeByDistance(newSelection
                        .getDriverId(), newSelection.getHorseId(), newSelection.getDistance(), 5, newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 5)) + ")");
                ekipageController.setAvgTimeDistanceLimit10Label(String.valueOf(ekipageDb.avarageTimeByDistance(newSelection
                        .getDriverId(), newSelection.getHorseId(), newSelection.getDistance(), 10, newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 10)) + ")");
                ekipageController.setAvgTimeDistanceLimit15Label(String.valueOf(ekipageDb.avarageTimeByDistance(newSelection
                        .getDriverId(), newSelection.getHorseId(), newSelection.getDistance(), 15, newSelection.getRaceDate()))
                        + "(" + String.valueOf(databaseb.getAvgTimeByDistanceLimit(newSelection.getDistance(), 15)) + ")");

                ekipageController.setAvgPosition(String.valueOf(ekipageDb
                        .avaragePlacement(newSelection.getDriverId(), newSelection.getHorseId(), newSelection.getRaceDate())));

                ekipageController.setAvgPositionLast5(String.valueOf(ekipageDb.avaragePlacementWithLimit(newSelection
                        .getDriverId(), newSelection.getHorseId(), 5, newSelection.getRaceDate())));
                ekipageController.setAvgPositionLast10(String.valueOf(ekipageDb.avaragePlacementWithLimit(newSelection
                        .getDriverId(), newSelection.getHorseId(), 10, newSelection.getRaceDate())));
                ekipageController.setAvgPositionLast15(String.valueOf(ekipageDb.avaragePlacementWithLimit(newSelection
                        .getDriverId(), newSelection.getHorseId(), 15, newSelection.getRaceDate())));

                ekipageController.setAvgPositionDistanceLast5(String.valueOf(ekipageDb.avaragePlacementByDistance(newSelection
                        .getDriverId(), newSelection.getHorseId(), newSelection.getDistance(), 5, newSelection.getRaceDate())));
                ekipageController.setAvgPositionDistanceLast10(String.valueOf(ekipageDb.avaragePlacementByDistance(newSelection
                        .getDriverId(), newSelection.getHorseId(), newSelection.getDistance(), 10, newSelection.getRaceDate())));
                ekipageController.setAvgPositionDistanceLast15(String.valueOf(ekipageDb.avaragePlacementByDistance(newSelection
                        .getDriverId(), newSelection.getHorseId(), newSelection.getDistance(), 15, newSelection.getRaceDate())));

            }

        });
        // Add extra columns

        theTable.getItems().addAll(races);
        raceNumTab.setContent(theTable);
        racesTabs.getTabs().add(raceNumTab);

    }

    private TableView<ComparingResultsData> createTable() {

        final TableView<ComparingResultsData> table = new TableView<>();
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        final TableColumn<ComparingResultsData, String> horseNameColumn = new TableColumn<>("Horse name");
        horseNameColumn.setCellValueFactory(new PropertyValueFactory<>("horseName"));
        final TableColumn<ComparingResultsData, Integer> laneColumn = new TableColumn<>("Lane");
        laneColumn.setCellValueFactory(new PropertyValueFactory<>("lane"));
        final TableColumn<ComparingResultsData, Integer> distanceColumn = new TableColumn<>("Distance");
        distanceColumn.setCellValueFactory(new PropertyValueFactory<>("distance"));
        final TableColumn<ComparingResultsData, String> timeModifierColumn = new TableColumn<>("Time modifier");
        timeModifierColumn.setCellValueFactory(new PropertyValueFactory<>("timeModifier"));
        final TableColumn<ComparingResultsData, String> driverNameColumn = new TableColumn<>("Driver name");
        driverNameColumn.setCellValueFactory(new PropertyValueFactory<>("driverName"));
        final TableColumn<ComparingResultsData, String> trainerNameColumn = new TableColumn<>("Trainer name");
        trainerNameColumn.setCellValueFactory(new PropertyValueFactory<>("trainerName"));
        final TableColumn<ComparingResultsData, String> laneWinColumn = new TableColumn<>("Lane win %");
        laneWinColumn.setCellValueFactory(new PropertyValueFactory<>("laneWin"));
        final TableColumn<ComparingResultsData, Integer> resultColumn = new TableColumn<>("Result");
        resultColumn.setCellValueFactory(new PropertyValueFactory<>("result"));
        final TableColumn<ComparingResultsData, Boolean> betOnColumn = new TableColumn<>("BetOn");
        betOnColumn.setCellValueFactory(new PropertyValueFactory<>("betOn"));

        final Callback<TableColumn<ComparingResultsData, Boolean>, TableCell<ComparingResultsData, Boolean>> booleanCellFactory
                = new Callback<>() {
                    @Override
                    public TableCell<ComparingResultsData, Boolean> call(TableColumn<ComparingResultsData, Boolean> p) {
                        return new BooleanCell();
                    }

                };

        betOnColumn.setCellFactory(booleanCellFactory);

        table.getColumns().add(horseNameColumn);
        table.getColumns().add(driverNameColumn);
        table.getColumns().add(trainerNameColumn);
        table.getColumns().add(distanceColumn);
        table.getColumns().add(laneColumn);
        table.getColumns().add(timeModifierColumn);
        table.getColumns().add(laneWinColumn);
        table.getColumns().add(resultColumn);
        table.getColumns().add(betOnColumn);

        return table;
    }

    protected <T> void addToBong(TableRow<T> row) {
        final ComparingResultsData item = (ComparingResultsData) row.getItem();

        final BongObject betOnRaceObject = new BongObject();
        betOnRaceObject.addDriver(item.getDriverName());
        betOnRaceObject.addHorse(item.getHorseName());
        betOnRaceObject.addLane(item.getLane());
        betOnRaceObject.setRaceNumber(item.getRaceNumber());
        this.betSlip.getChildren().add(betOnRaceObject.getContent());
    }

    protected <T> void removeFromBong(TableRow<T> row) {
        final ComparingResultsData item = (ComparingResultsData) row.getItem();
        Optional<Node> found = null;
        for (final Node data : betSlip.getChildren()) {
            final HBox test = ((HBox) data);
            found = test.getChildren().stream()
                    .filter(p -> ((TextField) ((Pane) p).getChildren().get(0)).getText().equals(item.getHorseName())).findFirst();

        }

        if (found != null && found.isPresent()) {
            final Node node = found.get();
            final Iterator<Node> iterator = betSlip.getChildren().iterator();
            while (iterator.hasNext()) {
                if (iterator.next().equals(node.getParent())) {
                    iterator.remove();
                }
            }

        }
    }

    class BooleanCell extends TableCell<ComparingResultsData, Boolean> {
        private final CheckBox checkBox;

        public BooleanCell() {
            checkBox = new CheckBox();

            checkBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
                @SuppressWarnings({ "rawtypes", "unchecked" })
                @Override
                public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                    if (newValue) {
                        addToBong((TableRow) checkBox.getParent().getParent());
                    } else {
                        removeFromBong((TableRow) checkBox.getParent().getParent());
                    }
                    if (isEditing()) {
                        commitEdit(newValue == null ? false : newValue);
                    }
                }
            });
            this.setGraphic(checkBox);
            this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            this.setEditable(true);
        }

        @Override
        public void startEdit() {
            super.startEdit();
            if (isEmpty()) {
                return;
            }
            checkBox.requestFocus();
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
        }

        @Override
        public void commitEdit(Boolean value) {
            super.commitEdit(value);
        }

        @Override
        public void updateItem(Boolean item, boolean empty) {
            super.updateItem(item, empty);
            if (!isEmpty()) {
                checkBox.setSelected(item);
            }
        }
    }

    public void setBongObject(VBox betOnContent) {
        betSlip = betOnContent;
    }

}
