// BFS.cpp
//
// Created on: 08. 12. 2017
// Author: Jan Uhlik
// Modified by:
//
// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library

#include "BFS.hpp"

#include <registration/AlgoRegistration.hpp>
#include <graph/GraphClasses.hpp>
#include <grid/GridClasses.hpp>

namespace graph::traverse {
class BFSBidirectional {};
} // namespace graph::traverse

namespace {

// ---------------------------------------------------------------------------------------------------------------------
// Normal Graph uni-directional

auto BFS1 = registration::AbstractRegister<graph::traverse::BFS,
                                           ext::vector<DefaultNodeType>,
                                           const graph::UndirectedGraph<> &,
                                           const DefaultNodeType &,
                                           const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFS2 = registration::AbstractRegister<graph::traverse::BFS,
                                           ext::vector<DefaultNodeType>,
                                           const graph::UndirectedMultiGraph<> &,
                                           const DefaultNodeType &,
                                           const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFS3 = registration::AbstractRegister<graph::traverse::BFS,
                                           ext::vector<DefaultNodeType>,
                                           const graph::DirectedGraph<> &,
                                           const DefaultNodeType &,
                                           const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFS4 = registration::AbstractRegister<graph::traverse::BFS,
                                           ext::vector<DefaultNodeType>,
                                           const graph::DirectedMultiGraph<> &,
                                           const DefaultNodeType &,
                                           const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFS5 = registration::AbstractRegister<graph::traverse::BFS,
                                           ext::vector<DefaultNodeType>,
                                           const graph::MixedGraph<> &,
                                           const DefaultNodeType &,
                                           const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFS6 = registration::AbstractRegister<graph::traverse::BFS,
                                           ext::vector<DefaultNodeType>,
                                           const graph::MixedMultiGraph<> &,
                                           const DefaultNodeType &,
                                           const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFSGrid1 = registration::AbstractRegister<graph::traverse::BFS,
                                               ext::vector<DefaultSquareGridNodeType>,
                                               const grid::SquareGrid4<> &,
                                               const DefaultSquareGridNodeType &,
                                               const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathRegistration);

auto BFSGrid2 = registration::AbstractRegister<graph::traverse::BFS,
                                               ext::vector<DefaultSquareGridNodeType>,
                                               const grid::SquareGrid8<> &,
                                               const DefaultSquareGridNodeType &,
                                               const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathRegistration);

// ---------------------------------------------------------------------------------------------------------------------
// Normal Graph bidirectional

auto BFSBidirectional1 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                        ext::vector<DefaultNodeType>,
                                                        const graph::UndirectedGraph<> &,
                                                        const DefaultNodeType &,
                                                        const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSBidirectional2 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                        ext::vector<DefaultNodeType>,
                                                        const graph::UndirectedMultiGraph<> &,
                                                        const DefaultNodeType &,
                                                        const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSBidirectional3 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                        ext::vector<DefaultNodeType>,
                                                        const graph::DirectedGraph<> &,
                                                        const DefaultNodeType &,
                                                        const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSBidirectional4 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                        ext::vector<DefaultNodeType>,
                                                        const graph::DirectedMultiGraph<> &,
                                                        const DefaultNodeType &,
                                                        const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSBidirectional5 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                        ext::vector<DefaultNodeType>,
                                                        const graph::MixedGraph<> &,
                                                        const DefaultNodeType &,
                                                        const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSBidirectional6 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                        ext::vector<DefaultNodeType>,
                                                        const graph::MixedMultiGraph<> &,
                                                        const DefaultNodeType &,
                                                        const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSGridBidirectional1 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                            ext::vector<DefaultSquareGridNodeType>,
                                                            const grid::SquareGrid4<> &,
                                                            const DefaultSquareGridNodeType &,
                                                            const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto BFSGridbidirectional2 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                            ext::vector<DefaultSquareGridNodeType>,
                                                            const grid::SquareGrid8<> &,
                                                            const DefaultSquareGridNodeType &,
                                                            const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

// ---------------------------------------------------------------------------------------------------------------------
// Weighted Graph uni-directional

auto WBFS1 = registration::AbstractRegister<graph::traverse::BFS,
                                            ext::vector<DefaultNodeType>,
                                            const graph::WeightedUndirectedGraph<> &,
                                            const DefaultNodeType &,
                                            const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFS2 = registration::AbstractRegister<graph::traverse::BFS,
                                            ext::vector<DefaultNodeType>,
                                            const graph::WeightedUndirectedMultiGraph<> &,
                                            const DefaultNodeType &,
                                            const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFS3 = registration::AbstractRegister<graph::traverse::BFS,
                                            ext::vector<DefaultNodeType>,
                                            const graph::WeightedDirectedGraph<> &,
                                            const DefaultNodeType &,
                                            const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFS4 = registration::AbstractRegister<graph::traverse::BFS,
                                            ext::vector<DefaultNodeType>,
                                            const graph::WeightedDirectedMultiGraph<> &,
                                            const DefaultNodeType &,
                                            const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFS5 = registration::AbstractRegister<graph::traverse::BFS,
                                            ext::vector<DefaultNodeType>,
                                            const graph::WeightedMixedGraph<> &,
                                            const DefaultNodeType &,
                                            const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFS6 = registration::AbstractRegister<graph::traverse::BFS,
                                            ext::vector<DefaultNodeType>,
                                            const graph::WeightedMixedMultiGraph<> &,
                                            const DefaultNodeType &,
                                            const DefaultNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFSGrid1 = registration::AbstractRegister<graph::traverse::BFS,
                                                ext::vector<DefaultSquareGridNodeType>,
                                                const grid::WeightedSquareGrid4<> &,
                                                const DefaultSquareGridNodeType &,
                                                const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathRegistration);

auto WBFSGrid2 = registration::AbstractRegister<graph::traverse::BFS,
                                                ext::vector<DefaultSquareGridNodeType>,
                                                const grid::WeightedSquareGrid8<> &,
                                                const DefaultSquareGridNodeType &,
                                                const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathRegistration);

// ---------------------------------------------------------------------------------------------------------------------
// Weighted Graph bidirectional

auto WBFSBidirectional1 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                         ext::vector<DefaultNodeType>,
                                                         const graph::WeightedUndirectedGraph<> &,
                                                         const DefaultNodeType &,
                                                         const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSBidirectional2 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                         ext::vector<DefaultNodeType>,
                                                         const graph::WeightedUndirectedMultiGraph<> &,
                                                         const DefaultNodeType &,
                                                         const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSBidirectional3 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                         ext::vector<DefaultNodeType>,
                                                         const graph::WeightedDirectedGraph<> &,
                                                         const DefaultNodeType &,
                                                         const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSBidirectional4 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                         ext::vector<DefaultNodeType>,
                                                         const graph::WeightedDirectedMultiGraph<> &,
                                                         const DefaultNodeType &,
                                                         const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSBidirectional5 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                         ext::vector<DefaultNodeType>,
                                                         const graph::WeightedMixedGraph<> &,
                                                         const DefaultNodeType &,
                                                         const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSBidirectional6 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                         ext::vector<DefaultNodeType>,
                                                         const graph::WeightedMixedMultiGraph<> &,
                                                         const DefaultNodeType &,
                                                         const DefaultNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSGridBidirectional1 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                             ext::vector<DefaultSquareGridNodeType>,
                                                             const grid::WeightedSquareGrid4<> &,
                                                             const DefaultSquareGridNodeType &,
                                                             const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

auto WBFSGridbidirectional2 = registration::AbstractRegister<graph::traverse::BFSBidirectional,
                                                             ext::vector<DefaultSquareGridNodeType>,
                                                             const grid::WeightedSquareGrid8<> &,
                                                             const DefaultSquareGridNodeType &,
                                                             const DefaultSquareGridNodeType &>(graph::traverse::BFS::findPathBidirectionalRegistration);

// ---------------------------------------------------------------------------------------------------------------------

}
