import { Piece } from "../types/Piece";
import { Direction } from "./Direction";
import { InternalNodeType } from "./InternalNodeType";
import { TrackType } from "./TrackType";

const STRAIGHT_RAIL: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      endPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
  ],
});
const TURN_RAIL: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.SOUTH,
      endPoint: Direction.EAST,
      type: TrackType.RAIL,
    },
  ],
});
const FOUR_WAY_CROSS_RAIL: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.NONE,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
  ],
});
const T_JUNCTION_RAIL: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.NONE,
  trackDefinitions: [
    {
      startPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.RAIL,
    },
  ],
});
const DEAD_END_STATION_RAIL: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
  ],
});
const TURN_RAIL_TO_ROAD: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
  ],
});
const T_JUNCTION_WITH_ROAD_ON_SIDE: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
  ],
});
const FOUR_WAY_WITH_ONE_ROAD: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
  ],
});
const T_JUNCTION_WITH_ROAD_AT_CENTER: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
  ],
});
const STRAIGHT_TRACK_CHANGE: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
  ],
});
const DEAD_END_STATION_ROAD: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
  ],
});
const T_JUNCTION_WITH_RAIL_AT_CENTER: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const FOUR_WAY_PERPENDICULAR_CROSSING: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
  ],
});
const FOUR_WAY_WITH_ONE_RAIL: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const FOUR_WAY_TURNING_CROSSING: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.STATION,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
  ],
});
const LEVEL_CROSSING: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      endPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      endPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const STRAIGHT_ROAD: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.EAST,
      endPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const T_JUNCTION_ROAD: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.NONE,
  trackDefinitions: [
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const FOUR_WAY_CROSS_ROAD: Piece = new Piece({
  useInternalTracks: true,
  internalNodeType: InternalNodeType.NONE,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.EAST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.SOUTH,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const DOUBLE_TURN_ROAD: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      endPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
    {
      startPoint: Direction.EAST,
      endPoint: Direction.SOUTH,
      type: TrackType.ROAD,
    },
  ],
});
const TURN_ROAD: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      endPoint: Direction.WEST,
      type: TrackType.ROAD,
    },
  ],
});
const DOUBLE_TURN_RAIL: Piece = new Piece({
  useInternalTracks: false,
  trackDefinitions: [
    {
      startPoint: Direction.NORTH,
      endPoint: Direction.WEST,
      type: TrackType.RAIL,
    },
    {
      startPoint: Direction.EAST,
      endPoint: Direction.SOUTH,
      type: TrackType.RAIL,
    },
  ],
});

export enum PieceId {
  P01 = "P01",
  P02 = "P02",
  P03 = "P03",
  P04 = "P04",
  P05 = "P05",
  P06 = "P06",
  P07 = "P07",
  P08 = "P08",
  P09 = "P09",
  P10 = "P10",
  P11 = "P11",
  P12 = "P12",
  P13 = "P13",
  P14 = "P14",
  P15 = "P15",
  P16 = "P16",
  P17 = "P17",
  P18 = "P18",
  P19 = "P19",
  P20 = "P20",
  P21 = "P21",
  P22 = "P22",
}

export const pieceMap: Record<PieceId, Piece> = {
  [PieceId.P01]: STRAIGHT_RAIL,
  [PieceId.P02]: TURN_RAIL,
  [PieceId.P03]: FOUR_WAY_CROSS_RAIL,
  [PieceId.P04]: T_JUNCTION_RAIL,
  [PieceId.P05]: DEAD_END_STATION_RAIL,
  [PieceId.P06]: TURN_RAIL_TO_ROAD,
  [PieceId.P07]: T_JUNCTION_WITH_ROAD_ON_SIDE,
  [PieceId.P08]: FOUR_WAY_WITH_ONE_ROAD,
  [PieceId.P09]: T_JUNCTION_WITH_ROAD_AT_CENTER,
  [PieceId.P10]: STRAIGHT_TRACK_CHANGE,
  [PieceId.P11]: DEAD_END_STATION_ROAD,
  [PieceId.P12]: T_JUNCTION_WITH_RAIL_AT_CENTER,
  [PieceId.P13]: FOUR_WAY_PERPENDICULAR_CROSSING,
  [PieceId.P14]: FOUR_WAY_WITH_ONE_RAIL,
  [PieceId.P15]: FOUR_WAY_TURNING_CROSSING,
  [PieceId.P16]: LEVEL_CROSSING,
  [PieceId.P17]: STRAIGHT_ROAD,
  [PieceId.P18]: T_JUNCTION_ROAD,
  [PieceId.P19]: FOUR_WAY_CROSS_ROAD,
  [PieceId.P20]: DOUBLE_TURN_ROAD,
  [PieceId.P21]: TURN_ROAD,
  [PieceId.P22]: DOUBLE_TURN_RAIL,
};
