import Foundation

extension Array {

    func at(_ index: Int) -> Element? {
        guard index < count else {
            return nil
        }
        return self[index]
    }

    func rotatedByOne() -> [Element] {
        guard !isEmpty else {
            return []
        }
        return self[1...] + [self[0]]
    }

    mutating func rotateByOne() {
        guard !isEmpty else {
            return
        }
        append(removeFirst())
    }
    
    func rotated(toStartAt index: Int) -> [Element] {
        guard index != 0 else {
            return self
        }
        return Array(self[index..<count] + self[0..<index])
    }

    func sorted<T>(by converting: (Element) -> T) -> [Element] where T: Comparable {
        sorted { converting($0) < converting($1) }
    }
}

extension Array where Element: Equatable {

    func index(of element: Element) -> Index {
        firstIndex(of: element)!
    }
}

extension Array where Element: Player {

    var names: [PlayerName] {
        map { $0.name }
    }

    func index(of player: PlayerName) -> Int {
        firstIndex { $0.name == player }!
    }

    func player(named name: PlayerName) -> Element? {
        first { $0.name == name }
    }

    func contains(player: PlayerName) -> Bool {
        contains { $0.name == player }
    }

    func next(after player: Element) -> Element {
        let i = index(of: player)
        let newIndex = (i + 1) % maximumPlayersPerTable
        return self[newIndex]
    }
}
