/*
 * 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 Controllers.Stock;

import Models.Stock.ListeMouvement;
import Models.Stock.StockDB;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.print.JobSettings;
import javafx.print.PageRange;
import javafx.print.PrinterJob;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;

/**
 * FXML Controller class
 *
 * @author Maher
 */
public class MouvementStockController implements Initializable {

    @FXML private ProgressIndicator ProgressLoading;
    
    @FXML private Text TextReference ;
    @FXML private Text TextDesignation ;
    
    @FXML private TableView<ListeMouvement> TableViewMouvement ;
    @FXML private TableColumn<ListeMouvement, String> TabColCode;
    @FXML private TableColumn<ListeMouvement, String> TabColType;
    @FXML private TableColumn<ListeMouvement, String> TabColMouvement;
    @FXML private TableColumn<ListeMouvement, String> TabColQuantite;
    @FXML private TableColumn<ListeMouvement, String> TabColDate;
    
    @FXML private DatePicker DatePickerDebut;
    @FXML private Button BtnPrintMouvement;
    @FXML private Button BtnExportPDFMouvement;
    
    @FXML private StackPane ListerPages;
    @FXML private Text ActuellePage ;
    @FXML private Text NbrPage ;
    @FXML private Group nextgroupe ;
    @FXML private Group avancergroupe ;
    @FXML private Group lastgroupe ;        
    @FXML private Group retourgroupe ;
    @FXML private Label count ;
    @FXML private ChoiceBox NbrLigne ;
    ObservableList cursors = FXCollections.observableArrayList("10","15","20");
    private Integer nbrligne = 10 ;
    private Integer totalcount ;
    private Integer nbrpage = 0;
    private Integer actuellepage;
    Integer position ;
    
    
    private String StringLocal;
    private String StringReference;
    private String StringDateDebut = "";
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        
        NbrLigne.setItems(cursors);
        NbrLigne.getSelectionModel().selectFirst();
        
        TabColCode.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColCode.getStyleClass().add("Center");
        TabColCode.setCellValueFactory(new PropertyValueFactory<ListeMouvement, String>("Code"));
        
        TabColType.setCellValueFactory(new PropertyValueFactory<ListeMouvement, String>("Type"));
        
        TabColMouvement.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColMouvement.getStyleClass().add("Center");
        TabColMouvement.setCellValueFactory(new PropertyValueFactory<ListeMouvement, String>("Mouvement"));
        
        TabColQuantite.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColQuantite.getStyleClass().add("Center");
        TabColQuantite.setCellValueFactory(new PropertyValueFactory<ListeMouvement, String>("Quantite"));
        
        TabColDate.setStyle( "-fx-alignment: CENTER; -fx-font-weight:bold; -fx-font-size: 10pt;");
        TabColDate.getStyleClass().add("Center");
        TabColDate.setCellValueFactory(new PropertyValueFactory<ListeMouvement, String>("Date"));
        
        DatePickerDebut.setOnAction(new EventHandler<ActionEvent>() {
            @Override 
            public void handle(ActionEvent actionEvent) {
                try{
                    StringDateDebut = DatePickerDebut.getValue().toString();
                    MouvementStockGestion("Models.Stock.StockDB", "getDataStockDetail", "getNbrStockDetail", StringDateDebut);
                }catch(Exception ex){}
            }
        });
        DatePickerDebut.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent ke) {
                try{
                    StringDateDebut = DatePickerDebut.getConverter().fromString(DatePickerDebut.getEditor().getText()).toString();
                    MouvementStockGestion("Models.Stock.StockDB", "getDataStockDetail", "getNbrStockDetail", StringDateDebut);
                }catch(Exception ex){}
            }
        });
        
        BtnPrintMouvement.setOnAction(new EventHandler<ActionEvent>(){ //Action when the button is pressed
            @Override
            public void handle(ActionEvent t) {
                PrintMouvement();
            }
        });
        
        
        BtnExportPDFMouvement.setOnAction(new EventHandler<ActionEvent>(){ //Action when the button is pressed
            @Override
            public void handle(ActionEvent t) {
                ExportPDFMouvement();
            }
        });
        
    } 
    
    public void SetData(String Reference, String Designation, String Local) {
        TextReference.setText(Reference);
        TextDesignation.setText(Designation);
        StringLocal = Local;
        StringReference = Reference;
        
        MouvementStockGestion("Models.Stock.StockDB", "getDataStockDetail", "getNbrStockDetail", "");
    }
    
    
    /**
     * Print Mouvement
     */
    private void PrintMouvement() {
        try {
            ObservableList<ListeMouvement> listMouvement = new StockDB().getDataStockDetail(StringLocal, StringReference, "", null, null);
            
            int SizelistMouvement = listMouvement.size();
            int total = SizelistMouvement / 25 + 1 ;
            int page = 0;
            
            PrinterJob jobPrint = PrinterJob.createPrinterJob();  
            jobPrint.getJobSettings().setPageRanges(new PageRange(1, total));
            
            if (jobPrint.showPrintDialog(null)) {
                JobSettings jsPrint = jobPrint.getJobSettings();
                for (int i=0; i<SizelistMouvement; i+=25){
                    ObservableList<ListeMouvement> listMouvTemp = FXCollections.observableArrayList();
                    for (int j=i; (j<(i+25)) && (j<SizelistMouvement); j++){
                        listMouvTemp.add(listMouvement.get(j));
                    }
                    FXMLLoader fxmlLoaderMouvement = new FXMLLoader(getClass().getResource("/Views/Stock/PrintMouvementProduit.fxml"));
                    final Node ParentFxmlMouvement = (Node)fxmlLoaderMouvement.load();
                    PrintMouvementProduitController PrintMouvementProd = fxmlLoaderMouvement.getController();
                    page++;
                    PrintMouvementProd.setMouvements(listMouvTemp, StringLocal, StringDateDebut, StringReference, TextDesignation.getText(), page+"/"+total);
                    jobPrint.printPage(ParentFxmlMouvement);
                }
                jobPrint.endJob();
            }
        } catch (IOException ex) {
            System.err.println("FactureFrsGestionController PrintAllProduit ! \n"+ex.getMessage());
        }
    }
    
    /**
     * Export PDF Mouvement
     */
    private void ExportPDFMouvement() {
        try {
            ObservableList<ListeMouvement> listMouvement = new StockDB().getDataStockDetail(StringLocal, StringReference, "", null, null);
            PrinterJob jobExportPDF = PrinterJob.createPrinterJob();
            int SizelistMouvement = listMouvement.size();
            int total = SizelistMouvement / 25 + 1 ;
            int page = 0;
            for (int i=0; i<SizelistMouvement; i+=25){
                ObservableList<ListeMouvement> listMouvTemp = FXCollections.observableArrayList();
                for (int j=i; (j<(i+25)) && (j<SizelistMouvement); j++){
                    listMouvTemp.add(listMouvement.get(j));
                }
                FXMLLoader fxmlLoaderMouvement = new FXMLLoader(getClass().getResource("/Views/Stock/PrintMouvementProduit.fxml"));
                final Node ParentFxmlMouvement = (Node)fxmlLoaderMouvement.load();
                PrintMouvementProduitController PrintMouvementProd = fxmlLoaderMouvement.getController();
                page++;
                PrintMouvementProd.setMouvements(listMouvTemp, StringLocal, StringDateDebut, StringReference, TextDesignation.getText(), page+"/"+total);
                jobExportPDF.printPage(ParentFxmlMouvement);
            }
            jobExportPDF.endJob();
        } catch (IOException ex) {
            System.err.println("FactureFrsGestionController PrintAllProduit ! \n"+ex.getMessage());
        }
    }
    
    /*****************************************************************************                                                                             *
    *                                                                            *
    *               Methode last Next TableView client  Entreprise               * 
    *                                                                            *
    ******************************************************************************/  
    
    //une methode qui permet modifier  le nom et methode d'une classe
    private void setFunctiongetDetailStock(final String NomClass, final String NomMethode, final String DateDebut, final Integer Position, final Integer Nbrligne){
        try {
            ProgressLoading.setVisible(true);
            TableViewMouvement.setVisible(false);

            // Create a Runnable
            Runnable task = new Runnable(){
                public void run(){
                    Platform.runLater(new Runnable(){
                        @Override
                        public void run(){
                            try {
                                Class c = Class.forName(NomClass);
                                Object o = c.newInstance();

                                Class[] paramTypes = {String.class, String.class, String.class, Integer.class, Integer.class};

                                Method m = c.getDeclaredMethod(NomMethode, paramTypes);

                                TableViewMouvement.setItems((ObservableList<ListeMouvement>) (m.invoke(o, StringLocal, StringReference, DateDebut, Position, Nbrligne)));

                                ProgressLoading.setVisible(false);
                                TableViewMouvement.setVisible(true);

                            } catch (Exception ex) {
                                System.err.println("Erreur SQL ! \n"+ex.getMessage());
                            }
                        }
                    });	
                }
            };

            Thread backgroundThread = new Thread(task); // Run the task in a background thread
            backgroundThread.setDaemon(true);   // Terminate the running thread if the application exits
            backgroundThread.start();   // Start the thread
            
        }catch (Exception ex) {
            System.err.println(ex.getMessage());
        } 
    }
    private void MouvementStockGestion(final String NomClass, final String NomMethode, String NomMethodeCount, final String DateDebut){
        try {
            Class c = Class.forName(NomClass);
            Object o = c.newInstance();
            Class[] paramTypes = {String.class, String.class, String.class};
            Method m = c.getDeclaredMethod(NomMethodeCount, paramTypes);
            //System.out.println("method = " + m.toString());
            String nbr = (String) m.invoke(o, StringLocal, StringReference, DateDebut);
            count.setText(nbr);
            totalcount = Integer.parseInt(nbr) ;
        } catch (Exception ex) {
            System.err.println("Exception MouvementStockGestion "+ex.getMessage());
        }
    
        ActuellePage.setText("1");
        actuellepage=1;
        position = 0;
        setFunctiongetDetailStock(NomClass, NomMethode, DateDebut, position, nbrligne);
    
    
        NbrLigne.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue ov,  Number value, Number new_value) {
                nbrligne= Integer.parseInt((String) cursors.get(new_value.intValue()));
                if(totalcount % nbrligne==0){ nbrpage = totalcount / nbrligne ;}
                else{ nbrpage = (totalcount / nbrligne) + 1 ; }
                NbrPage.setText(Integer.toString(nbrpage));
                position=0;
                ActuellePage.setText("1");
                actuellepage=1;
                setFunctiongetDetailStock(NomClass, NomMethode, DateDebut, position, nbrligne);
            }
        });
    
        if(totalcount % nbrligne==0){ nbrpage = totalcount / nbrligne ;}
        else{ nbrpage = (totalcount / nbrligne) + 1 ; }
        NbrPage.setText(Integer.toString(nbrpage));
                    
                    
        //next page
        nextgroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage<nbrpage){
                    position=position+nbrligne;
                    setFunctiongetDetailStock(NomClass, NomMethode, DateDebut, position, nbrligne);
                    actuellepage=actuellepage+1 ;
                    ActuellePage.setText(Integer.toString(actuellepage));
                    //System.out.println("position "+position+"     "+"nbrligne "+nbrligne);
                }
            }
        }); 
    
        //last page
        lastgroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage>1){
                    position=position-nbrligne;
                    setFunctiongetDetailStock(NomClass, NomMethode, DateDebut, position, nbrligne);
                    actuellepage=actuellepage-1 ;
                    ActuellePage.setText(Integer.toString(actuellepage));
                }
            }
        }); 
    
        //next page avec pas de 5
        avancergroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage+3<nbrpage){
                    position=(position+4)+nbrligne;
                    setFunctiongetDetailStock(NomClass, NomMethode, DateDebut, position, nbrligne);
                    actuellepage=actuellepage+3 ;
                    ActuellePage.setText(Integer.toString(actuellepage));
                     //System.out.println("position "+position+"     "+"nbrligne "+nbrligne);
                }
            }
        });
    
        //last page avec un pas de -5
        retourgroupe.setOnMousePressed(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                if(actuellepage-3>1){
                    position=(position-4)-nbrligne;
                    setFunctiongetDetailStock(NomClass, NomMethode, DateDebut, position, nbrligne);
                    actuellepage=actuellepage-3 ;
                    ActuellePage.setText(Integer.toString(actuellepage));
                }
            }
        });
    
    }
    
    
}
