import QtQuick 2.0

Item {
    id: root

    property string gameVariant
    property bool isTrigon: gameVariant.indexOf("trigon") === 0
    property bool isNexos: gameVariant.indexOf("nexos") === 0
    property bool isCallisto: gameVariant.indexOf("callisto") === 0
    property int columns: {
        switch (gameVariant) {
        case "duo":
        case "junior":
            return 14
        case "callisto_2":
            return 16
        case "trigon":
        case "trigon_2":
            return 35
        case "trigon_3":
            return 31
        case "nexos":
        case "nexos_2":
            return 25
        default:
            return 20
        }
    }
    property int rows: {
        switch (gameVariant) {
        case "duo":
        case "junior":
            return 14
        case "callisto_2":
            return 16
        case "trigon":
        case "trigon_2":
            return 18
        case "trigon_3":
            return 16
        case "nexos":
        case "nexos_2":
            return 25
        default:
            return 20
        }
    }
    // Avoid fractional piece element sizes if the piece elements are squares
    property real gridWidth: {
        var sideLength
        if (isTrigon) sideLength = Math.min(width, Math.sqrt(3) * height)
        else sideLength = Math.min(width, height)
        if (isTrigon) return sideLength / (columns + 1)
        else if (isNexos) Math.floor(sideLength / (columns - 0.5))
        else return Math.floor(sideLength / columns)
    }
    property real gridHeight: {
        if (isTrigon) return Math.sqrt(3) * gridWidth
        else return gridWidth
    }
    property real startingPointSize: {
        if (isTrigon) return 0.27 * gridHeight
        if (isNexos) return 0.3 * gridHeight
        return 0.35 * gridHeight
    }

    function mapFromGameX(x) {
        if (isTrigon) return image.x + (x + 0.5) * gridWidth
        else if (isNexos) return image.x + (x - 0.25) * gridWidth
        else return image.x + x * gridWidth
    }
    function mapFromGameY(y) {
        if (isNexos) return image.y + (y - 0.25) * gridHeight
        else return image.y + y * gridHeight
    }
    function mapToGame(pos) {
        if (isTrigon)
            return Qt.point((pos.x - image.x - 0.5 * gridWidth) / gridWidth,
                            (pos.y - image.y) / gridHeight)
        else if (isNexos)
            return Qt.point((pos.x - image.x + 0.25 * gridWidth) / gridWidth,
                            (pos.y - image.y + 0.25 * gridHeight) / gridHeight)
        else
            return Qt.point((pos.x - image.x) / gridWidth,
                            (pos.y - image.y) / gridHeight)
    }
    function getCenterYTrigon(pos) {

        var isDownward = ((pos.x % 2 == 0) != (pos.y % 2 == 0))
        if (gameVariant === "trigon_3")
            isDownward = ! isDownward
        return (isDownward ? 1 : 2) / 3 * gridHeight
    }

    Image {
        id: image

        width: {
            if (isTrigon) return gridWidth * (columns + 1)
            else if (isNexos) return gridWidth * (columns - 0.5)
            else return gridWidth * columns
        }
        height: {
            if (isNexos) return gridHeight * (rows - 0.5)
            else return gridHeight * rows
        }
        anchors.centerIn: root
        source: {
            switch (gameVariant) {
            case "trigon":
            case "trigon_2":
                return theme.getImage("board-trigon")
            case "trigon_3":
                return theme.getImage("board-trigon-3")
            case "nexos":
            case "nexos_2":
                return theme.getImage("board-tile-nexos")
            case "callisto":
                return theme.getImage("board-callisto")
            case "callisto_2":
                return theme.getImage("board-callisto-2")
            case "callisto_3":
                return theme.getImage("board-callisto-3")
            default:
                return theme.getImage("board-tile-classic")
            }
        }
        sourceSize {
            width: {
                if (isTrigon || isCallisto) return width
                if (isNexos) return 2 * gridWidth
                return gridWidth
            }
            height: {
                if (isTrigon || isCallisto) return height
                if (isNexos) return 2 * gridHeight
                return gridHeight
            }
        }
        // It should work to use Image.Tile for all game variants, but the
        // Trigon board is not painted with Image.width/height even if
        // sourceSize is bound to it (the Trigon SVG files have a different
        // aspect ratio but that shouldn't matter). Bug in Qt 5.6?
        fillMode: isTrigon? Image.Stretch : Image.Tile
        horizontalAlignment: Image.AlignLeft
        verticalAlignment: Image.AlignTop
        cache: false
    }
    Repeater {
        model: gameModel.startingPoints0

        Rectangle {
            color: theme.colorBlue
            width: startingPointSize; height: width
            radius: width / 2
            x: mapFromGameX(modelData.x) + (gridWidth - width) / 2
            y: mapFromGameY(modelData.y) + (gridHeight - height) / 2
        }
    }
    Repeater {
        model: gameModel.startingPoints1

        Rectangle {
            color: gameModel.gameVariant == "duo"
                   || gameModel.gameVariant == "junior"
                   || gameModel.gameVariant == "callisto_2" ?
                       theme.colorGreen : theme.colorYellow
            width: startingPointSize; height: width
            radius: width / 2
            x: mapFromGameX(modelData.x) + (gridWidth - width) / 2
            y: mapFromGameY(modelData.y) + (gridHeight - height) / 2
        }
    }
    Repeater {
        model: gameModel.startingPoints2

        Rectangle {
            color: theme.colorRed
            width: startingPointSize; height: width
            radius: width / 2
            x: mapFromGameX(modelData.x) + (gridWidth - width) / 2
            y: mapFromGameY(modelData.y) + (gridHeight - height) / 2
        }
    }
    Repeater {
        model: gameModel.startingPoints3

        Rectangle {
            color: theme.colorGreen
            width: startingPointSize; height: width
            radius: width / 2
            x: mapFromGameX(modelData.x) + (gridWidth - width) / 2
            y: mapFromGameY(modelData.y) + (gridHeight - height) / 2
        }
    }
    Repeater {
        model: gameModel.startingPointsAll

        Rectangle {
            color: theme.colorStartingPoint
            width: startingPointSize; height: width
            radius: width / 2
            x: mapFromGameX(modelData.x) + (gridWidth - width) / 2
            y: mapFromGameY(modelData.y) + getCenterYTrigon(modelData)
               - height / 2
        }
    }
}
