//#####################################################################
// Copyright 2022, Jason Goulding, Craig Schroeder
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Flood_Fill function
//#####################################################################
#ifndef __FLOOD_FILL__
#define __FLOOD_FILL__

#include <Core/Arrays/ARRAY.h>
#include <Core/Arrays/ARRAYS_ND.h>
#include <Core/Arrays/FACE_ARRAYS.h>
#include <Core/Grids/GRID.h>
#include <Core/Vectors/VECTOR.h>
#include <climits>

namespace PhysBAM{
namespace FLOOD_FILL{
enum{uncolorable_flag=1,boundary_flag=2,uncolorable=-2,colorable=-1};
}

template<int d,class IV,bool is_mac>
int Flood_Fill(const RANGE<IV>& domain,GRID_TYPE<is_mac>,ARRAY<int,IV>& colors,
    const ARRAY<bool,FACE_INDEX<d> >& edge_is_blocked,
    ARRAY<int>* color_flags=0,VECTOR<bool,d> periodic_axis={},
    ARRAY<VECTOR<int,2> >* region_boundaries=0)
{
    if(is_mac) return Flood_Fill(domain,at_cells,colors,&edge_is_blocked,color_flags,periodic_axis,region_boundaries);
    else return Flood_Fill(domain,at_nodes,colors,&edge_is_blocked,color_flags,periodic_axis,region_boundaries);
}

template<int d,class IV,bool is_mac>
int Flood_Fill(const RANGE<IV>& domain,GRID_TYPE<is_mac>,ARRAY<int,IV>& colors,
    const ARRAY<bool,FACE_INDEX<d> >* edge_is_blocked,
    ARRAY<int>* color_flags=0,VECTOR<bool,d> periodic_axis={},
    ARRAY<VECTOR<int,2> >* region_boundaries=0)
{
    const VECTOR<ARRAY_VIEW<bool,IV>,IV::m>* edge_is_blocked_data=0;
    if(edge_is_blocked) edge_is_blocked_data=&(edge_is_blocked->data);
    if(is_mac) return Flood_Fill(domain,at_cells,colors,edge_is_blocked_data,color_flags,periodic_axis,region_boundaries);
    else return Flood_Fill(domain,at_nodes,colors,edge_is_blocked_data,color_flags,periodic_axis,region_boundaries);
}

// colors should be initialized by the user with FLOOD_FILL::colorable where colors
// will be filled and FLOOD_FILL::uncolorable for nodes which will not be colored.
template<int d,class IV>
int Flood_Fill(const RANGE<IV>& domain,AT_NODES,ARRAY<int,IV>& colors,
    const VECTOR<ARRAY_VIEW<bool,IV>,IV::m>* edge_is_blocked,
    ARRAY<int>* color_flags=0,VECTOR<bool,d> periodic_axis={},
    ARRAY<VECTOR<int,2> >* region_boundaries=0)
{
    return Flood_Fill(domain,at_cells,colors,edge_is_blocked,color_flags,periodic_axis,region_boundaries);
}

template<int d,class IV>
int Flood_Fill(const RANGE<IV>& domain,AT_CELLS,ARRAY<int,IV>& colors,
    const VECTOR<ARRAY_VIEW<bool,IV>,IV::m>* edge_is_blocked,
    ARRAY<int>* color_flags=0,VECTOR<bool,d> periodic_axis={},
    ARRAY<VECTOR<int,2> >* region_boundaries=0);
}
#endif
