/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mytime.gui.controller;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXMasonryPane;
import com.jfoenix.controls.JFXScrollPane;
import com.jfoenix.controls.JFXSnackbar;
import com.jfoenix.controls.JFXSpinner;
import com.jfoenix.controls.JFXTextField;
import javafx.scene.paint.Color;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import mytime.be.Location;
import javafx.stage.Stage;
import mytime.be.Person;
import mytime.gui.model.ManagerModel;
import mytime.gui.model.Model;
import mytime.gui.model.VolunteerModel;
/**
* FXML Controller class
*
* @author Stefan-VpcEB3J1E
*/
public class ManagerMainViewController implements Initializable, ChangeListener<Boolean>
{
@FXML
private JFXTextField txtFieldSearch;
@FXML
private JFXScrollPane scrollPane;
@FXML
private JFXMasonryPane masonryPane;
private ManagerModel mgrModel;
private Executor exec;
private ExecutorService execService;
@FXML
private JFXButton btnShowSidePanel;
@FXML
private BorderPane mainBorderPane;
private Task<Node> getPane;
private Node centerNode;
private String oldValue;
@FXML
private StackPane stackPane;
private SlidePanelAnimation slide;
private Menu menuSort;
private JFXSnackbar snackBar, undoSnackbar;
private EventHandler undoChangesHandler;
@FXML
private JFXComboBox<Location> comboBoxNewLocation;
@FXML
private JFXButton btnDeleteSavedLocation;
// @FXML
// private JFXButton btnBackMan;
private Node volunteerViewNode;
//private VBox parentOfMason;
private JFXScrollPane scrollPaneToSwap;
@FXML
private BorderPane borderPaneVolunteer;
public ManagerMainViewController()
{
}
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb)
{
initHeaderPane();
// JFXScrollPane.smoothScrolling(scrollPane);
snackBar = new JFXSnackbar(mainBorderPane);
undoSnackbar = new JFXSnackbar(mainBorderPane);
undoChangesHandler = (EventHandler) (Event event)
->
{
// try
// {
snackBar.close();
try
{
// volunteerModel.undoLastChanges();
Node lastNode = getNodeForVolunteer(mgrModel.undoLastDeletedPerson());
mgrModel.getAllPersonNodes().add(lastNode);
masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes());
} catch (SQLException ex)
{
ex.printStackTrace();
} catch (IOException ex)
{
ex.printStackTrace();
}
undoSnackbar.show(" Genskabte sidst slettede person med success.", 3000);
// } catch (SQLException ex)
// {
// ex.printStackTrace();
// }
};
oldValue = "";
//mgrModel.getTextfieldSearchText().bindBidirectional(txtFieldSearch.textProperty());
centerNode = mainBorderPane.getCenter();
mainBorderPane.setCenter(null);
JFXSpinner spinner = new JFXSpinner();
spinner.setRadius(40);
mainBorderPane.setCenter(spinner);
txtFieldSearch.setVisible(false);
btnShowSidePanel.setVisible(false);
// btnBackMan.setVisible(false);
mgrModel = ManagerModel.getInstance();
mgrModel.getSnackbarMessage().addListener(new ListChangeListener<String>()
{
@Override
public void onChanged(ListChangeListener.Change<? extends String> c)
{
String name = mgrModel.getSnackbarMessage().get(mgrModel.getSnackbarMessage().size() - 1);
if (name.startsWith("Slettede"))
{
snackBar.show(" " + name, "Fortryd?", undoChangesHandler);
} else
{
snackBar.show(" " + name, 3500);
}
setOnActionCloseClick();
}
});
mgrModel.getShowRightPanel().addListener(this);
mgrModel.getReloadNodes().addListener(new ChangeListener<Boolean>()
{
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue)
{
if (newValue)
{
masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes());
mgrModel.getReloadNodes().set(false);
}
}
});
exec = Executors.newCachedThreadPool(runnable
->
{
Thread t = new Thread(runnable);
t.setDaemon(true);
return t;
});
execService = Executors.newFixedThreadPool(4, (Runnable r)
->
{
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
});
setUpTask();
Platform.runLater(() -> loadAllPersonsIntoListAsNodes());
mgrModel.getObjectProperty().addListener(new ChangeListener()
{
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue)
{
try
{
mgrModel.getAllPersonNodes().add(getNodeForVolunteer((Person) newValue));
masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes());
} catch (IOException ex)
{
Logger.getLogger(ManagerMainViewController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
//mgrModel.setCurrentPerson(masonryPane.get);
FXMLLoader loader = new FXMLLoader(getClass().getResource("/mytime/gui/view/ManagerOneVolunteerInformation.fxml"));
try
{
volunteerViewNode = loader.load();
} catch (IOException ex)
{
Logger.getLogger(ManagerMainViewController.class.getName()).log(Level.SEVERE, null, ex);
}
//parentOfMason = (VBox) masonryPane.getParent();
List<Node> nodes = borderPaneVolunteer.getChildren();
for (Node node : nodes)
{
if (node.getClass().getName() == JFXScrollPane.class.getName())
{
System.out.println("SUCCES");
scrollPaneToSwap = (JFXScrollPane) node;
}
}
mgrModel.getClickedVolunteer().addListener(new ChangeListener()
{
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue)
{
if (newValue != null)
{
borderPaneVolunteer.setCenter(volunteerViewNode);
} else
{
borderPaneVolunteer.setCenter(scrollPaneToSwap);
}
}
});
setLocationsInComboBox();
}
/**
* Scrollpane header.
*/
private void initHeaderPane()
{
ImageView imgV = new ImageView(new Image("/mytime/gui/view/back.png"));
imgV.setPreserveRatio(true);
imgV.setSmooth(true);
imgV.setCache(true);
JFXButton button = new JFXButton("");
button.setOnAction(e
->
{
handleGoBack(new ActionEvent());
});
button.setGraphic(imgV);
Node topNode = mainBorderPane.getTop();
mainBorderPane.setTop(null);
scrollPane.getTopBar().getChildren().add(button);
// scrollPane.getTopBar().getChildren().add(topNode);
try
{
FXMLLoader lblLoader = new FXMLLoader(getClass().getResource("/mytime/gui/view/header.fxml"));
Node lblNode = lblLoader.load();
Label lblHeader = (Label) lblNode;
// lblHeader.setFont(Font.font(45));
// lblHeader.setTextFill(Color.rgb(252, 252, 252, .99));
scrollPane.getBottomBar().getChildren().add(lblHeader);
StackPane.setMargin(lblHeader, new Insets(0, 0, 0, 80));
StackPane.setAlignment(lblHeader, Pos.CENTER_LEFT);
StackPane.setAlignment(button, Pos.CENTER_LEFT);
StackPane.setMargin(button, new Insets(0, 0, 0, 20));
} catch (IOException ex)
{
ex.printStackTrace();
}
}
/**
* Sets the locations in the combobox in the manger view
*/
private void setLocationsInComboBox()
{
try
{
ObservableList<Location> items = FXCollections.observableArrayList();
items.addAll(Model.getInstance().getAllLocations());
Image img = new Image("mytime/gui/view/css/Delete.png");
ImageView imv = new ImageView(img);
imv.setPreserveRatio(true);
imv.setSmooth(true);
imv.setCache(true);
imv.setFitHeight(8);
imv.setFitWidth(8);
btnDeleteSavedLocation.setGraphic(imv);
btnDeleteSavedLocation.setText("");
comboBoxNewLocation.setItems(items);
for (Location item : comboBoxNewLocation.getItems())
{
if (item.getId().get() == VolunteerModel.getInstance().getCurrentLocation().getId().get())
{
comboBoxNewLocation.getSelectionModel().clearAndSelect(comboBoxNewLocation.getItems().indexOf(item));
}
}
comboBoxNewLocation.setVisible(false);
btnDeleteSavedLocation.setVisible(false);
comboBoxNewLocation.setOnAction(e
->
{
if (comboBoxNewLocation.getSelectionModel().getSelectedItem() != null)
{
try
{
if (snackBar.isVisible())
{
snackBar.close();
}
Model.getInstance().saveLocationLocally(comboBoxNewLocation.getSelectionModel().getSelectedItem().getId().get());
snackBar.show(" " + comboBoxNewLocation.getSelectionModel().getSelectedItem().getName().get() + " blev valgt som lokation på denne computer. \n Kun en manager kan ændre denne indstilling.", 7500);
} catch (IOException ex)
{
ex.printStackTrace();
}
}
});
} catch (SQLException ex)
{
Logger.getLogger(ManagerMainViewController.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Sets a timer when you click in the document hours window, and closes the
* snackbar after 3.5sec.
*/
private void setOnActionCloseClick()
{
masonryPane.setOnMouseClicked(e
->
{
runTimerTask();
});
mainBorderPane.getTop().setOnMouseClicked(a
->
{
runTimerTask();
});
comboBoxNewLocation.setOnMouseClicked(e
->
{
runTimerTask();
});
btnShowSidePanel.setOnMouseClicked(e
->
{
runTimerTask();
});
}
/**
* Timer task
*/
private void runTimerTask()
{
TimerTask clearActions = new TimerTask()
{
@Override
public void run()
{
masonryPane.setOnMouseClicked(null);
}
};
Timer timer2 = new Timer(true);
timer2.schedule(clearActions, 3600);
TimerTask timerTask = new TimerTask()
{
@Override
public void run()
{
snackBar.close();
}
};
Timer timer = new Timer(true);
timer.schedule(timerTask, 3500);
}
@FXML
private void handleOpenRightSidePanel(ActionEvent event)
{
handleOpenCloseRightSide();
}
/**
* Sets up the task that should be executed by our Executor, when you click
* on add a new volunteer.
*/
private void setUpTask()
{
getPane = new Task<Node>()
{
@Override
protected Node call() throws Exception
{
FXMLLoader newLoadedPane = new FXMLLoader(getClass().getResource("/mytime/gui/view/ManagerCreateVolunteer.fxml"));
Node node = newLoadedPane.load();
return node;
}
};
getPane.setOnSucceeded(e
->
{
Node paneToLoad = getPane.getValue();
if (paneToLoad != null)
{
Platform.runLater(()
->
{
slide = new SlidePanelAnimation(209, paneToLoad);
mgrModel.setRightSideNode(paneToLoad);
// stackPane.setAlignment(slide, Pos.CENTER_RIGHT);
stackPane.getChildren().add(slide);
mgrModel.getShowRightPanel().set(true);
});
}
});
}
/**
* Handles the open & close side panel.
*/
private void handleOpenCloseRightSide()
{
if (mainBorderPane.getRight() == null)
{
if (mgrModel.getRightSideView() == null)
{
exec.execute(getPane);
mainBorderPane.getCenter().setEffect(new GaussianBlur());
} else
{
if (slide == null)
{
Node node = mgrModel.getRightSideView();
slide = new SlidePanelAnimation(209, node);
// mainBorderPane.setRight(slide);
}
stackPane.getChildren().add(slide);
mgrModel.getShowRightPanel().set(true);
mainBorderPane.getCenter().setEffect(new GaussianBlur());
// mainBorderPane.getBottom().setEffect(new GaussianBlur());
}
} else
{
// mainBorderPane.setRight(null);
stackPane.getChildren().remove(slide);
mainBorderPane.getCenter().setEffect(null);
// mainBorderPane.getBottom().setEffect(null);
}
}
/**
* Method for getting a volunteer as a node, so that we can load it in our
* view as a JAVAFX component.
*
* @param volunteer
* @return
* @throws IOException
*/
private Node getNodeForVolunteer(Person volunteer) throws IOException
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/mytime/gui/view/ManagerOneVolunteer.fxml"));
Node node = loader.load();
Button button = (Button) node;
ManagerOneVolunteerController controller = loader.getController();
controller.setVolunteer(volunteer);
// load the image
Image image = new Image(volunteer.getProfilePicture().get());
// simple displays ImageView the image as is
ImageView iv1 = new ImageView();
//
iv1.setFitWidth(70);
iv1.setFitHeight(50);
Circle clip = new Circle(iv1.getFitHeight() / 2, iv1.getFitWidth() / 3, 26);
iv1.setClip(clip);
iv1.setImage(image);
iv1.setPreserveRatio(true);
iv1.setSmooth(true);
iv1.setCache(true);
button.setPrefHeight(40);
button.setPrefWidth(150);
button.getStyleClass().add("VolunteerBtn");
String firstName = volunteer.getFirstName().get();
String lastName = volunteer.getLastName().get();
button.setText("");
StackPane grap = new StackPane();
HBox vbox = new HBox();
vbox.setAlignment(Pos.CENTER_LEFT);
vbox.setSpacing(4);
Label lblName = new Label();
lblName.setText(firstName + "\n" + lastName);
vbox.getChildren().addAll(iv1, lblName);
grap.setAlignment(Pos.CENTER_LEFT);
grap.getChildren().add(vbox);
button.setGraphic(grap);
button.setContentDisplay(ContentDisplay.LEFT);
button.setUserData(volunteer);
// Timeline animation = new Timeline(new KeyFrame(Duration.millis(240), new KeyValue(button.scaleXProperty(), 1, Interpolator.EASE_BOTH),
// new KeyValue(button.scaleYProperty(), 1, Interpolator.EASE_BOTH)));
// animation.setDelay(Duration.millis(100 * 2 + (2000)));
// animation.play();
return node;
}
/**
* Loads all the persons with the same Location ID in as nodes in a list in
* the Volunteer Model.
*/
private void loadAllPersonsIntoListAsNodes()
{
Task<List<Person>> loadPersonAsGUIComponentsTask = new Task<List<Person>>()
{
@Override
protected List<Person> call() throws Exception
{
return mgrModel.loadAllPersons();
}
};
loadPersonAsGUIComponentsTask.setOnSucceeded(e
->
{
if (loadPersonAsGUIComponentsTask.getValue() != null)
{
List<Person> allPersons = loadPersonAsGUIComponentsTask.getValue();
Task<Boolean> updateGUITask = new Task<Boolean>()
{
@Override
protected Boolean call() throws Exception
{
// mgrModel.setAllPersonsPlain(allPersons);
List<Node> list = mgrModel.getAllPersonNodes();
list.clear();
allPersons.stream().parallel().forEach(n
->
{
try
{
list.add(getNodeForVolunteer(n));
} catch (IOException ex)
{
ex.printStackTrace();
}
});
mgrModel.setAllPersons(list);
// for (Person personsToLoadInAsNode : allPersons)
// {
// try
// {
// mgrModel.getAllPersonNodes().add(getNodeForVolunteer(personsToLoadInAsNode));
// } catch (IOException ex)
// {
// ex.printStackTrace();
// }
// }
return true;
}
};
updateGUITask.setOnSucceeded(j
->
{
Task<Void> anotherTask = new Task<Void>()
{
@Override
protected Void call() throws Exception
{
//
Platform.runLater(()
->
{
mainBorderPane.setCenter(null);
mainBorderPane.setCenter(centerNode);
//Clears loading icon here
masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes());
}
);
return null;
}
};
anotherTask.setOnSucceeded(o
->
{
txtFieldSearch.setVisible(true);
btnShowSidePanel.setVisible(true);
comboBoxNewLocation.setVisible(true);
btnDeleteSavedLocation.setVisible(true);
// btnBackMan.setVisible(true);
Platform.runLater(()
->
{
scrollPane.requestFocus();
});
scrollPane.requestLayout();
masonryPane.requestLayout();
});
execService.execute(anotherTask);
// System.out.println("done");
// System.out.println("here");
// masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes());
// scrollPane.requestLayout();
});
execService.execute(updateGUITask);
}
});
execService.execute(loadPersonAsGUIComponentsTask);
}
/**
* Closes the side panel.
*
* @param observable
* @param oldValue
* @param newValue
*/
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue)
{
if (!newValue)
{
stackPane.getChildren().remove(slide);
mainBorderPane.getCenter().setEffect(null);
}
}
/**
* Filters the volunteers shown in the masonrypane
*
* @param event
*/
@FXML
private void searchAction(KeyEvent event)
{
String newValue = txtFieldSearch.getText();
if (!newValue.equals(oldValue))
{
List<Node> filteredList = mgrModel.filterList(newValue);
masonryPane.getChildren().setAll(filteredList);
}
oldValue = txtFieldSearch.getText();
}
/**
* Go back man
*
* @param event
*/
private void handleGoBack(ActionEvent event)
{
VolunteerModel vmodel = VolunteerModel.getInstance();
// mgrModel.setRightSideNode(null);
// mgrModel.getAllPersonNodes().clear();
// mgrModel.setCurrentToggle(10);
// mgrModel.setAllPersons(null);
Stage mainView = (Stage) scrollPane.getScene().getWindow();
snackBar.close();
undoSnackbar.close();
mainView.close();
Parent mainViewLoad = null;
try
{
ResourceBundle bundle = ResourceBundle.getBundle("mytime.gui.UIResources", vmodel.getLocale());
mainViewLoad = FXMLLoader.load(getClass().getResource("/mytime/gui/view/LoginMainView.fxml"), bundle);
} catch (IOException ex)
{
Logger.getLogger(LoginOneVolunteerController.class.getName()).log(Level.SEVERE, null, ex);
}
Scene scene = new Scene(mainViewLoad);
mainView.setScene(scene);
mainView.setResizable(true);
mainView.show();
}
@FXML
private void handleDeleteSavedLocation(ActionEvent event)
{
try
{
snackBar.show(" Slettede 'husk denne lokation's-indstilling på denne computer. \n Brugeren skal vælge en ny lokation næste gang programmet starter.", 7500);
comboBoxNewLocation.getSelectionModel().clearSelection();
mgrModel.clearSavedLocationInFile();
} catch (IOException ex)
{
ex.printStackTrace();
}
}
}