contract CheezyExchangeTournamentTime {

    /// @notice The following struct was copied directly from CheezeWizards
    ///  TournamentTimeAbstract contract in order to replicate much of its
    ///  functionality.
    // The data needed to check if we are in a given Window
    struct WindowParameters {
        // The block number that the first window of this type begins
        uint48 firstWindowStartBlock;

        // A copy of the pause ending block, copied into this storage slot to
        // save gas
        uint48 pauseEndedBlock;

        // The length of an entire "session" (see above for definitions), ALL
        // windows repeat with a period of one session.
        uint32 sessionDuration;

        // The duration of this window
        uint32 windowDuration;
    }

    /// @notice The following function was copied directly from CheezeWizards
    ///  TournamentTimeAbstract contract in order to replicate much of its
    ///  functionality.
    // An internal convenience function that checks to see if we are currently
    // in the Window defined by the WindowParameters struct passed as an
    // argument.
    function _isInWindow(WindowParameters memory localParams) internal view returns (bool) {
        // We are never "in a window" if the contract is paused
        if (block.number < localParams.pauseEndedBlock) {
            return false;
        }

        // If we are before the first window of this type, we are obviously NOT
        // in this window!
        if (block.number < localParams.firstWindowStartBlock) {
            return false;
        }

        // Use modulus to figure out how far we are past the beginning of the
        // most recent window
        // of this type
        uint256 windowOffset = (block.number - localParams.firstWindowStartBlock) % localParams.sessionDuration;

        // If we are in the window, we will be within duration of the start of
        // the most recent window
        return windowOffset < localParams.windowDuration;
    }

    /// @notice A getter function for determining whether we are currently in a
    ///  fightWindow for a given tournament
    /// @param _basicTournamentAddress  The address of the tournament in
    ///  question
    /// @return  Whether or not we are in a fightWindow for this tournament
    function _isInFightWindowForTournament(address _basicTournamentAddress) internal view returns (bool){
        uint256 tournamentStartBlock;
        uint256 pauseEndedBlock;
        uint256 admissionDuration;
        uint256 duelTimeoutDuration;
        uint256 ascensionWindowDuration;
        uint256 fightWindowDuration;
        uint256 cullingWindowDuration;
        (
            tournamentStartBlock,
            pauseEndedBlock,
            admissionDuration,
            ,
            duelTimeoutDuration,
            ,
            ascensionWindowDuration,
            ,
            fightWindowDuration,
            ,
            ,
            ,
            cullingWindowDuration
        ) = IBasicTournamentTimeParams(_basicTournamentAddress).getTimeParameters();
        uint256 firstSessionStartBlock = uint256(tournamentStartBlock) + uint256(admissionDuration);
        uint256 sessionDuration = uint256(ascensionWindowDuration) + uint256(fightWindowDuration) + uint256(duelTimeoutDuration) + uint256(cullingWindowDuration);

        return _isInWindow(WindowParameters({
            firstWindowStartBlock: uint48(uint256(firstSessionStartBlock) + uint256(ascensionWindowDuration)),
            pauseEndedBlock: uint48(pauseEndedBlock),
            sessionDuration: uint32(sessionDuration),
            windowDuration: uint32(fightWindowDuration)
        }));
    }
}
/// @title Convenience contract for CheezyExchange to retrieve Tournament Times
///  from a basic tournament contract.
/// @notice Unfortunately, the CheezeWizard's official contracts do not have a
///  getter function for checking whether we are in a fight window, etc. Since
///  CheezyExchange power transfers can only occur duringFightWindow, we had to
///  re-write all of the CheezeWizards TournamentTime logic simply to get a
///  getter function for checking whether we are duringFightWindow.
function _isInFightWindowForTournament(address _basicTournamentAddress) internal view returns (bool){
    uint256 tournamentStartBlock;
    uint256 pauseEndedBlock;
    uint256 admissionDuration;
    uint256 duelTimeoutDuration;
    uint256 ascensionWindowDuration;
    uint256 fightWindowDuration;
    uint256 cullingWindowDuration;
    (
        tournamentStartBlock,
        pauseEndedBlock,
        admissionDuration,
        ,
        duelTimeoutDuration,
        ,
        ascensionWindowDuration,
        ,
        fightWindowDuration,
        ,
        ,
        ,
        cullingWindowDuration
    ) = IBasicTournamentTimeParams(_basicTournamentAddress).getTimeParameters();
    uint256 firstSessionStartBlock = uint256(tournamentStartBlock) + uint256(admissionDuration);
    uint256 sessionDuration = uint256(ascensionWindowDuration) + uint256(fightWindowDuration) + uint256(duelTimeoutDuration) + uint256(cullingWindowDuration);

    return _isInWindow(WindowParameters({
        firstWindowStartBlock: uint48(uint256(firstSessionStartBlock) + uint256(ascensionWindowDuration)),
        pauseEndedBlock: uint48(pauseEndedBlock),
        sessionDuration: uint32(sessionDuration),
        windowDuration: uint32(fightWindowDuration)
    }));
}

/// @notice A getter function for determining whether we are currently in a
///  fightWindow for a given tournament
/// @param _basicTournamentAddress  The address of the tournament in
///  question
/// @return  Whether or not we are in a fightWindow for this tournament