/*****************************************************************************
 * Copyright (c) 2014-2026 OpenRCT2 developers
 *
 * For a complete list of all authors, please refer to contributors.md
 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
 *
 * OpenRCT2 is licensed under the GNU General Public License version 3.
 *****************************************************************************/

#pragma once

#include <cstdint>

namespace OpenRCT2
{
    enum class TrackElemType : uint16_t
    {
        flat = 0,
        endStation = 1,
        beginStation = 2,
        middleStation = 3,
        up25 = 4,
        up60 = 5,
        flatToUp25 = 6,
        up25ToUp60 = 7,
        up60ToUp25 = 8,
        up25ToFlat = 9,
        down25 = 10,
        down60 = 11,
        flatToDown25 = 12,
        down25ToDown60 = 13,
        down60ToDown25 = 14,
        down25ToFlat = 15,
        leftQuarterTurn5Tiles = 16,
        rightQuarterTurn5Tiles = 17,
        flatToLeftBank = 18,
        flatToRightBank = 19,
        leftBankToFlat = 20,
        rightBankToFlat = 21,
        bankedLeftQuarterTurn5Tiles = 22,
        bankedRightQuarterTurn5Tiles = 23,
        leftBankToUp25 = 24,
        rightBankToUp25 = 25,
        up25ToLeftBank = 26,
        up25ToRightBank = 27,
        leftBankToDown25 = 28,
        rightBankToDown25 = 29,
        down25ToLeftBank = 30,
        down25ToRightBank = 31,
        leftBank = 32,
        rightBank = 33,
        leftQuarterTurn5TilesUp25 = 34,
        rightQuarterTurn5TilesUp25 = 35,
        leftQuarterTurn5TilesDown25 = 36,
        rightQuarterTurn5TilesDown25 = 37,
        sBendLeft = 38,
        sBendRight = 39,
        leftVerticalLoop = 40,
        rightVerticalLoop = 41,
        leftQuarterTurn3Tiles = 42,
        rightQuarterTurn3Tiles = 43,
        leftBankedQuarterTurn3Tiles = 44,
        rightBankedQuarterTurn3Tiles = 45,
        leftQuarterTurn3TilesUp25 = 46,
        rightQuarterTurn3TilesUp25 = 47,
        leftQuarterTurn3TilesDown25 = 48,
        rightQuarterTurn3TilesDown25 = 49,
        leftQuarterTurn1Tile = 50,
        rightQuarterTurn1Tile = 51,
        leftTwistDownToUp = 52,
        rightTwistDownToUp = 53,
        leftTwistUpToDown = 54,
        rightTwistUpToDown = 55,
        halfLoopUp = 56,
        halfLoopDown = 57,
        leftCorkscrewUp = 58,
        rightCorkscrewUp = 59,
        leftCorkscrewDown = 60,
        rightCorkscrewDown = 61,
        flatToUp60 = 62,
        up60ToFlat = 63,
        flatToDown60 = 64,
        down60ToFlat = 65,
        towerBase = 66,
        towerSection = 67,
        flatCovered = 68,
        up25Covered = 69,
        up60Covered = 70,
        flatToUp25Covered = 71,
        up25ToUp60Covered = 72,
        up60ToUp25Covered = 73,
        up25ToFlatCovered = 74,
        down25Covered = 75,
        down60Covered = 76,
        flatToDown25Covered = 77,
        down25ToDown60Covered = 78,
        down60ToDown25Covered = 79,
        down25ToFlatCovered = 80,
        leftQuarterTurn5TilesCovered = 81,
        rightQuarterTurn5TilesCovered = 82,
        sBendLeftCovered = 83,
        sBendRightCovered = 84,
        leftQuarterTurn3TilesCovered = 85,
        rightQuarterTurn3TilesCovered = 86,
        leftHalfBankedHelixUpSmall = 87,
        rightHalfBankedHelixUpSmall = 88,
        leftHalfBankedHelixDownSmall = 89,
        rightHalfBankedHelixDownSmall = 90,
        leftHalfBankedHelixUpLarge = 91,
        rightHalfBankedHelixUpLarge = 92,
        leftHalfBankedHelixDownLarge = 93,
        rightHalfBankedHelixDownLarge = 94,
        leftQuarterTurn1TileUp60 = 95,
        rightQuarterTurn1TileUp60 = 96,
        leftQuarterTurn1TileDown60 = 97,
        rightQuarterTurn1TileDown60 = 98,
        brakes = 99,
        booster = 100,
        maze = 101,
        leftQuarterBankedHelixLargeUp = 102,
        rightQuarterBankedHelixLargeUp = 103,
        leftQuarterBankedHelixLargeDown = 104,
        rightQuarterBankedHelixLargeDown = 105,
        leftQuarterHelixLargeUp = 106,
        rightQuarterHelixLargeUp = 107,
        leftQuarterHelixLargeDown = 108,
        rightQuarterHelixLargeDown = 109,
        up25LeftBanked = 110,
        up25RightBanked = 111,
        waterfall = 112,
        rapids = 113,
        onRidePhoto = 114,
        down25LeftBanked = 115,
        down25RightBanked = 116,
        waterSplash = 117,
        flatToUp60LongBase = 118,
        up60ToFlatLongBase = 119,
        whirlpool = 120,
        down60ToFlatLongBase = 121,
        flatToDown60LongBase = 122,
        cableLiftHill = 123,
        reverseFreefallSlope = 124,
        reverseFreefallVertical = 125,
        up90 = 126,
        down90 = 127,
        up60ToUp90 = 128,
        down90ToDown60 = 129,
        up90ToUp60 = 130,
        down60ToDown90 = 131,
        brakeForDrop = 132,
        leftEighthToDiag = 133,
        rightEighthToDiag = 134,
        leftEighthToOrthogonal = 135,
        rightEighthToOrthogonal = 136,
        leftEighthBankToDiag = 137,
        rightEighthBankToDiag = 138,
        leftEighthBankToOrthogonal = 139,
        rightEighthBankToOrthogonal = 140,
        diagFlat = 141,
        diagUp25 = 142,
        diagUp60 = 143,
        diagFlatToUp25 = 144,
        diagUp25ToUp60 = 145,
        diagUp60ToUp25 = 146,
        diagUp25ToFlat = 147,
        diagDown25 = 148,
        diagDown60 = 149,
        diagFlatToDown25 = 150,
        diagDown25ToDown60 = 151,
        diagDown60ToDown25 = 152,
        diagDown25ToFlat = 153,
        diagFlatToUp60 = 154,
        diagUp60ToFlat = 155,
        diagFlatToDown60 = 156,
        diagDown60ToFlat = 157,
        diagFlatToLeftBank = 158,
        diagFlatToRightBank = 159,
        diagLeftBankToFlat = 160,
        diagRightBankToFlat = 161,
        diagLeftBankToUp25 = 162,
        diagRightBankToUp25 = 163,
        diagUp25ToLeftBank = 164,
        diagUp25ToRightBank = 165,
        diagLeftBankToDown25 = 166,
        diagRightBankToDown25 = 167,
        diagDown25ToLeftBank = 168,
        diagDown25ToRightBank = 169,
        diagLeftBank = 170,
        diagRightBank = 171,
        logFlumeReverser = 172,
        spinningTunnel = 173,
        leftBarrelRollUpToDown = 174,
        rightBarrelRollUpToDown = 175,
        leftBarrelRollDownToUp = 176,
        rightBarrelRollDownToUp = 177,
        leftBankToLeftQuarterTurn3TilesUp25 = 178,
        rightBankToRightQuarterTurn3TilesUp25 = 179,
        leftQuarterTurn3TilesDown25ToLeftBank = 180,
        rightQuarterTurn3TilesDown25ToRightBank = 181,
        poweredLift = 182,
        leftLargeHalfLoopUp = 183,
        rightLargeHalfLoopUp = 184,
        leftLargeHalfLoopDown = 185,
        rightLargeHalfLoopDown = 186,
        leftFlyerTwistUp = 187,
        rightFlyerTwistUp = 188,
        leftFlyerTwistDown = 189,
        rightFlyerTwistDown = 190,
        flyerHalfLoopUninvertedUp = 191,
        flyerHalfLoopInvertedDown = 192,
        leftFlyerCorkscrewUp = 193,
        rightFlyerCorkscrewUp = 194,
        leftFlyerCorkscrewDown = 195,
        rightFlyerCorkscrewDown = 196,
        heartLineTransferUp = 197,
        heartLineTransferDown = 198,
        leftHeartLineRoll = 199,
        rightHeartLineRoll = 200,
        minigolfHoleA = 201,
        minigolfHoleB = 202,
        minigolfHoleC = 203,
        minigolfHoleD = 204,
        minigolfHoleE = 205,
        multiDimInvertedFlatToDown90QuarterLoop = 206,
        up90ToInvertedFlatQuarterLoop = 207,
        invertedFlatToDown90QuarterLoop = 208,
        leftCurvedLiftHill = 209,
        rightCurvedLiftHill = 210,
        leftReverser = 211,
        rightReverser = 212,
        airThrustTopCap = 213,
        airThrustVerticalDown = 214,
        airThrustVerticalDownToLevel = 215,
        blockBrakes = 216,
        leftBankedQuarterTurn3TileUp25 = 217,
        rightBankedQuarterTurn3TileUp25 = 218,
        leftBankedQuarterTurn3TileDown25 = 219,
        rightBankedQuarterTurn3TileDown25 = 220,
        leftBankedQuarterTurn5TileUp25 = 221,
        rightBankedQuarterTurn5TileUp25 = 222,
        leftBankedQuarterTurn5TileDown25 = 223,
        rightBankedQuarterTurn5TileDown25 = 224,
        up25ToLeftBankedUp25 = 225,
        up25ToRightBankedUp25 = 226,
        leftBankedUp25ToUp25 = 227,
        rightBankedUp25ToUp25 = 228,
        down25ToLeftBankedDown25 = 229,
        down25ToRightBankedDown25 = 230,
        leftBankedDown25ToDown25 = 231,
        rightBankedDown25ToDown25 = 232,
        leftBankedFlatToLeftBankedUp25 = 233,
        rightBankedFlatToRightBankedUp25 = 234,
        leftBankedUp25ToLeftBankedFlat = 235,
        rightBankedUp25ToRightBankedFlat = 236,
        leftBankedFlatToLeftBankedDown25 = 237,
        rightBankedFlatToRightBankedDown25 = 238,
        leftBankedDown25ToLeftBankedFlat = 239,
        rightBankedDown25ToRightBankedFlat = 240,
        flatToLeftBankedUp25 = 241,
        flatToRightBankedUp25 = 242,
        leftBankedUp25ToFlat = 243,
        rightBankedUp25ToFlat = 244,
        flatToLeftBankedDown25 = 245,
        flatToRightBankedDown25 = 246,
        leftBankedDown25ToFlat = 247,
        rightBankedDown25ToFlat = 248,
        leftQuarterTurn1TileUp90 = 249,
        rightQuarterTurn1TileUp90 = 250,
        leftQuarterTurn1TileDown90 = 251,
        rightQuarterTurn1TileDown90 = 252,
        multiDimUp90ToInvertedFlatQuarterLoop = 253,
        multiDimFlatToDown90QuarterLoop = 254,
        multiDimInvertedUp90ToFlatQuarterLoop = 255,

        // Elements that shared an ID with another piece in RCT1/2.
        rotationControlToggle = 256,
        flatTrack1x4A = 257,
        flatTrack2x2 = 258,
        flatTrack4x4 = 259,
        flatTrack2x4 = 260,
        flatTrack1x5 = 261,
        flatTrack1x1A = 262,
        flatTrack1x4B = 263,
        flatTrack1x1B = 264,
        flatTrack1x4C = 265,
        flatTrack3x3 = 266,

        // Highest track element ID that has a TD6 alias
        highestAlias = 266,

        // Track Elements specific to OpenRCT2
        leftLargeCorkscrewUp = 267,
        rightLargeCorkscrewUp = 268,
        leftLargeCorkscrewDown = 269,
        rightLargeCorkscrewDown = 270,
        leftMediumHalfLoopUp = 271,
        rightMediumHalfLoopUp = 272,
        leftMediumHalfLoopDown = 273,
        rightMediumHalfLoopDown = 274,
        leftZeroGRollUp = 275,
        rightZeroGRollUp = 276,
        leftZeroGRollDown = 277,
        rightZeroGRollDown = 278,
        leftLargeZeroGRollUp = 279,
        rightLargeZeroGRollUp = 280,
        leftLargeZeroGRollDown = 281,
        rightLargeZeroGRollDown = 282,

        leftFlyerLargeHalfLoopUninvertedUp = 283,
        rightFlyerLargeHalfLoopUninvertedUp = 284,
        leftFlyerLargeHalfLoopInvertedDown = 285,
        rightFlyerLargeHalfLoopInvertedDown = 286,
        leftFlyerLargeHalfLoopInvertedUp = 287,
        rightFlyerLargeHalfLoopInvertedUp = 288,
        leftFlyerLargeHalfLoopUninvertedDown = 289,
        rightFlyerLargeHalfLoopUninvertedDown = 290,

        flyerHalfLoopInvertedUp = 291,
        flyerHalfLoopUninvertedDown = 292,

        leftEighthToDiagUp25 = 293,
        rightEighthToDiagUp25 = 294,
        leftEighthToDiagDown25 = 295,
        rightEighthToDiagDown25 = 296,
        leftEighthToOrthogonalUp25 = 297,
        rightEighthToOrthogonalUp25 = 298,
        leftEighthToOrthogonalDown25 = 299,
        rightEighthToOrthogonalDown25 = 300,

        diagUp25ToLeftBankedUp25 = 301,
        diagUp25ToRightBankedUp25 = 302,
        diagLeftBankedUp25ToUp25 = 303,
        diagRightBankedUp25ToUp25 = 304,
        diagDown25ToLeftBankedDown25 = 305,
        diagDown25ToRightBankedDown25 = 306,
        diagLeftBankedDown25ToDown25 = 307,
        diagRightBankedDown25ToDown25 = 308,
        diagLeftBankedFlatToLeftBankedUp25 = 309,
        diagRightBankedFlatToRightBankedUp25 = 310,
        diagLeftBankedUp25ToLeftBankedFlat = 311,
        diagRightBankedUp25ToRightBankedFlat = 312,
        diagLeftBankedFlatToLeftBankedDown25 = 313,
        diagRightBankedFlatToRightBankedDown25 = 314,
        diagLeftBankedDown25ToLeftBankedFlat = 315,
        diagRightBankedDown25ToRightBankedFlat = 316,
        diagFlatToLeftBankedUp25 = 317,
        diagFlatToRightBankedUp25 = 318,
        diagLeftBankedUp25ToFlat = 319,
        diagRightBankedUp25ToFlat = 320,
        diagFlatToLeftBankedDown25 = 321,
        diagFlatToRightBankedDown25 = 322,
        diagLeftBankedDown25ToFlat = 323,
        diagRightBankedDown25ToFlat = 324,
        diagUp25LeftBanked = 325,
        diagUp25RightBanked = 326,
        diagDown25LeftBanked = 327,
        diagDown25RightBanked = 328,

        leftEighthBankToDiagUp25 = 329,
        rightEighthBankToDiagUp25 = 330,
        leftEighthBankToDiagDown25 = 331,
        rightEighthBankToDiagDown25 = 332,
        leftEighthBankToOrthogonalUp25 = 333,
        rightEighthBankToOrthogonalUp25 = 334,
        leftEighthBankToOrthogonalDown25 = 335,
        rightEighthBankToOrthogonalDown25 = 336,

        diagBrakes = 337,
        diagBlockBrakes = 338,
        down25Brakes = 339,
        diagBooster = 340,

        diagFlatToUp60LongBase = 341,
        diagUp60ToFlatLongBase = 342,
        diagFlatToDown60LongBase = 343,
        diagDown60ToFlatLongBase = 344,
        leftEighthDiveLoopUpToOrthogonal = 345,
        rightEighthDiveLoopUpToOrthogonal = 346,
        leftEighthDiveLoopDownToDiag = 347,
        rightEighthDiveLoopDownToDiag = 348,

        diagDown25Brakes = 349,

        count = 350,

        none = 65535,
    };

    bool trackTypeIsCovered(TrackElemType trackElementType);
    TrackElemType uncoverTrackType(TrackElemType trackElementType);
    bool trackTypeIsStation(TrackElemType trackType);
    bool trackTypeIsBrakes(TrackElemType trackType);
    bool trackTypeIsBlockBrakes(TrackElemType trackType);
    bool trackTypeIsBooster(TrackElemType trackType);
    bool trackTypeIsReverser(TrackElemType trackType);
    bool trackTypeHasSpeedSetting(TrackElemType trackType);
    bool trackTypeIsHelix(TrackElemType trackType);
} // namespace OpenRCT2
