/**
 * @file bin_packing_solver.h
 * @author Jan Holáň, xholan11 (xholan11@vutbr.cz)
 * @brief translated with gcc version 12.2.1
 * @version 0.1
 * @date 2023-05-01
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#ifndef _BIN_PACKING_SOLVER_H_
#define _BIN_PACKING_SOLVER_H_

#include <iostream>
#include <algorithm>
#include <list>
#include <math.h>
#include "WarehousePickingOpt.h"

/// @brief namespace covering all the algorithms for BPP
namespace bp_solver
{
    /// @brief used in base line solution
    /// @param item_vect vector of order items to be fit into boxes
    /// @param box_vect there is returned the vector of filled boxes
    /// @param box_type type of a box to be used
    void baseLineFFD(vector<OItem> item_vect, vector<Box> *box_vect, Box box_type);

    /// @brief
    /// @param item_vect vector of order items to be fit into boxes
    /// @param box_vect there is returned the vector of filled boxes
    /// @param box_type type of a box to be used
    void mainSolution1DFFD_oneBoxType(vector<OItem> item_vect, vector<Box> *box_vect, Box box_type);

    /// @brief
    /// @param item_vect
    /// @param box_vect
    /// @param box_types
    void mainSolution1DFFDS_multipleBoxTypes(vector<OItem> item_vect, vector<Box> *box_vect, vector<Box> box_types);

    /// @brief
    /// @param item_vect vector of order items to be fit into boxes
    /// @param box_vect there is returned the vector of filled boxes
    /// @param box_type type of a box to be used
    void mainSolution3DBP_oneBox_pythonScript(vector<OItem> item_vect, vector<Box> *box_vect, Box box_type);

    /// @brief
    /// @param item_vect vector of order items to be fit into boxes
    /// @param box_vect there is returned the vector of filled boxes
    /// @param box_types types of a boxes to be used
    void mainSolution3DBP_FFDS_multiBoxTypes_pythonScript(vector<OItem> item_vect, vector<Box> *box_vect, vector<Box> box_types);

    /// @brief
    /// @param item_vect vector of order items to be fit into boxes
    /// @param box_vect there is returned the vector of filled boxes
    /// @param box_types types of a boxes to be used
    void mainSolution3DBP_multipleBoxTypes_countDefined_pythonScript(vector<OItem> item_vect, vector<Box> *box_vect, vector<pair<Box, int>> box_types_count);

    /// @brief function for filling shelves in cart with boxes of items
    /// @param box_vect boxes that are going to be loaded
    /// @param out_shelf_vect shelves in cart (should not be more then 3)
    /// @return true when the boxes can be loaded or false when they couldn't
    bool bpSolver_1D_fitBoxesToShelvesInCart(vector<Box> box_vect, vector<CartShelf> *out_shelf_vect, bool is_one_piced);
    /// @brief
    /// @param box_vect
    /// @param out_shelf_vect
    /// @param non_loaded_box_vect
    /// @return true or false depending on whether at least one box has been loaded to the cart
    bool bpSolver_1D_partlyLoadBoxesToShelvesInCart(vector<Box> box_vect, vector<CartShelf> *out_shelf_vect, vector<Box> *non_loaded_box_vect, vector<Box> *loaded_box_ptr_vect);

    bool addBoxItemToExisting_oneItemized_Box_1D(Box box, BoxItem box_item);

    bool addBoxItemToExisting_oneItemized_Box_3D(Box box, BoxItem box_item);
};

#endif