import { ECellType } from "../sim/ECellType";
import { SimLevel } from "../sim/SimLevel";
import { Hex } from "./Hex";

export abstract class PathFinding {
    public static bfs(level: SimLevel, startIndex: number, endIndex: number): number[] | null {
        const listToExplore: number[] = [startIndex];
        let cameFrom: number[] = new Array<number>(level.cells.length);
        cameFrom.fill(-1);

        while (listToExplore.length > 0) {
            const nodeIndex = listToExplore.shift()!;
            const cell = level.cells[nodeIndex];

            for (let i = 0; i < 6; ++i) {
                const neighbourHex = Hex.neighbour(cell.hex, i);
                const neighbourIndex = level.getCellIndex(neighbourHex);

                if (neighbourIndex === -1) {
                    continue;
                }

                const neighbourCell = level.cells[neighbourIndex];
                if (neighbourCell.type === ECellType.Blocked || neighbourCell.type === ECellType.Reserved || neighbourCell.tower !== null) {
                    continue;
                }

                if (cameFrom[neighbourIndex] === -1) {
                    cameFrom[neighbourIndex] = nodeIndex;

                    if (neighbourIndex !== endIndex) {
                        listToExplore.push(neighbourIndex);
                    } else {
                        let idx = neighbourIndex;
                        const path: number[] = [idx];

                        while (idx !== startIndex) {
                            const prev = cameFrom[idx];
                            idx = prev;
                            path.unshift(idx);
                        }

                        return path;
                    }
                }
            }
        }

        return null;
    }
}
