/*
 * 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 SchedulesRecovery;

import AbsenceSchedules.AbsenceSchedulesArray;
import InitialSchedules.ParametersInitialSchedules;

/**
 *
 * @author frabe
 */

// classe statique pour mettre fonction utilitaire
class ValidationRecoveringAction {
    
        //Toutes les fonctions sont dedoublees.  On devrait faire du polymorphisme.
    static boolean isPartTimeEmployeeAvailableForAbsenceRecovering(boolean[][] currentPartTimeSchedule, ParametersInitialSchedules myScheduleParameters, 
            AbsenceSchedulesArray myabsenceSchedule, int employee, int workPeriod){
        return !currentPartTimeSchedule[employee][workPeriod] && !myabsenceSchedule.isPartTimeEmployeeAbsent(employee, workPeriod) 
                && isValidPartTimeEmployeeWorkPeriod(currentPartTimeSchedule[employee], workPeriod, myScheduleParameters);
    }
    
    private static boolean isValidPartTimeEmployeeWorkPeriod(boolean[] currentPartTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
        return isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(currentPartTimeEmployeeSchedule, myScheduleParameters) &&
                isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod, myScheduleParameters) && 
                isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod, myScheduleParameters);
    }
    
    private static boolean isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(boolean[] currentPartTimeEmployeeSchedule, ParametersInitialSchedules myScheduleParameters){
        int employeeWorkingPeriods = 0;
        for ( int workPeriod = 0 ; workPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
            if (currentPartTimeEmployeeSchedule[workPeriod]){
                employeeWorkingPeriods +=1 ;
            }
        }
        return employeeWorkingPeriods < myScheduleParameters.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule();
    }

    private static boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
        int consecutiveWorkingPeriods = 1;
        int compteurWorkPeriod = workPeriod - 1;
        while ( compteurWorkPeriod >= 0 && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutiveWorkingPeriods += 1;
            compteurWorkPeriod--;
        }
        compteurWorkPeriod = workPeriod + 1;
        while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutiveWorkingPeriods += 1;
            compteurWorkPeriod++;
        }
        return consecutiveWorkingPeriods <= myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork();
    }

    private static boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
        int consecutivePreviousNonWorkingPeriods = 0;
        int compteurWorkPeriod = workPeriod - 1;
        while ( compteurWorkPeriod >= 0 && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutivePreviousNonWorkingPeriods += 1;
            compteurWorkPeriod--;
        }
        boolean validConsecutivePreviousNonWorkingPeriods = false;
        if (compteurWorkPeriod == -1) {
            validConsecutivePreviousNonWorkingPeriods = true;
        } else if (consecutivePreviousNonWorkingPeriods == 0) {
            validConsecutivePreviousNonWorkingPeriods = true;
        } else if (consecutivePreviousNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
            validConsecutivePreviousNonWorkingPeriods = true;
        }
        int consecutiveNextNonWorkingPeriods = 0;
        compteurWorkPeriod = workPeriod + 1;
        while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutiveNextNonWorkingPeriods += 1;
            compteurWorkPeriod++;
        }
        boolean validConsecutiveNextNonWorkingPeriods = false;
        if (compteurWorkPeriod == myScheduleParameters.getWorkPeriodsPerSchedule()) {
            validConsecutiveNextNonWorkingPeriods = true;
        } else if (consecutiveNextNonWorkingPeriods == 0) {
            validConsecutiveNextNonWorkingPeriods = true;
        } else if (consecutiveNextNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
            validConsecutiveNextNonWorkingPeriods = true;
        }
        return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
    }
    
    public static boolean isFullTimeEmployeeAvailableForAbsenceRecovering(boolean[][] currentFullTimeSchedule, ParametersInitialSchedules myScheduleParameters, 
                                AbsenceSchedulesArray myabsenceSchedule, int employee, int workPeriod){
        
        return !currentFullTimeSchedule[employee][workPeriod] && !myabsenceSchedule.isFullTimeEmployeeAbsent(employee, workPeriod) 
                && isValidFullTimeEmployeeWorkPeriod(currentFullTimeSchedule[employee], workPeriod, myScheduleParameters);
    }
    
    private static boolean isValidFullTimeEmployeeWorkPeriod(boolean[] currentFullTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
        return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentFullTimeEmployeeSchedule, myScheduleParameters) &&
                isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod, myScheduleParameters) && 
                isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod, myScheduleParameters);
    }
    
    private static boolean isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(boolean[] currentFullTimeEmployeeSchedule, ParametersInitialSchedules myScheduleParameters){
        int employeeWorkingPeriods = 0;
        for ( int workPeriod = 0 ; workPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
            if (currentFullTimeEmployeeSchedule[workPeriod]){
                employeeWorkingPeriods +=1 ;
            }
        }
        return employeeWorkingPeriods < myScheduleParameters.getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule();
    }
    

    private static boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
        int consecutiveWorkingPeriods = 1;
        int compteurWorkPeriod = workPeriod - 1;
        while ( compteurWorkPeriod >= 0 && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutiveWorkingPeriods += 1;
            compteurWorkPeriod--;
        }
        compteurWorkPeriod = workPeriod + 1;
        while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutiveWorkingPeriods += 1;
            compteurWorkPeriod++;
        }
        return consecutiveWorkingPeriods <= myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork();
    }

    private static boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
        int consecutivePreviousNonWorkingPeriods = 0;
        int compteurWorkPeriod = workPeriod - 1;
        while ( compteurWorkPeriod >= 0 && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutivePreviousNonWorkingPeriods += 1;
            compteurWorkPeriod--;
        }
        boolean validConsecutivePreviousNonWorkingPeriods = false;
        if (compteurWorkPeriod == -1) {
            validConsecutivePreviousNonWorkingPeriods = true;
        } else if (consecutivePreviousNonWorkingPeriods == 0) {
            validConsecutivePreviousNonWorkingPeriods = true;
        } else if (consecutivePreviousNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
            validConsecutivePreviousNonWorkingPeriods = true;
        }
        int consecutiveNextNonWorkingPeriods = 0;
        compteurWorkPeriod = workPeriod + 1;
        while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
            consecutiveNextNonWorkingPeriods += 1;
            compteurWorkPeriod++;
        }
        boolean validConsecutiveNextNonWorkingPeriods = false;
        if (compteurWorkPeriod == myScheduleParameters.getWorkPeriodsPerSchedule()) {
            validConsecutiveNextNonWorkingPeriods = true;
        } else if (consecutiveNextNonWorkingPeriods == 0) {
            validConsecutiveNextNonWorkingPeriods = true;
        } else if (consecutiveNextNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
            validConsecutiveNextNonWorkingPeriods = true;
        }
        return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
    }
}