from mcpi.minecraft import Minecraft, Vec3
from minecraftstuff import MinecraftDrawing
from vecIterator import vecItereator
from random import randint, choice
from splitIntoHouses import splitIntoHouses

rpiIp = "192.168.1.182"

mc = Minecraft.create(address=rpiIp)
mcdraw = MinecraftDrawing(mc)


def makeRoad(posA: Vec3, posB: Vec3, blockTypes=[1, 2, 7]):
    if not (posA.x == posB.x or posA.z == posB.z):
        raise NotImplementedError

    roadCenterOffset = 4

    for i in range(-roadCenterOffset, roadCenterOffset + 1, 1):
        if i == 0:
            blockType = blockTypes[2]
        elif i <= -3 or i >= 3:
            blockType = blockTypes[1]
        else:
            blockType = blockTypes[0]

        if posA.x == posB.x:  # ----
            mcdraw.drawLine(posA.x + i, posA.y, posA.z - roadCenterOffset,
                            posB.x + i, posB.y, posB.z + roadCenterOffset, blockType)
        else:  # ||||
            mcdraw.drawLine(posA.x - roadCenterOffset, posA.y, posA.z + i,
                            posB.x + roadCenterOffset, posB.y, posB.z + i, blockType)


def createPlane(posA: Vec3, posB: Vec3, blockType=1):
    mc.setBlocks(posA.x, posA.y, posA.z, posB.x, posB.y, posB.z, blockType)
    mc.setBlocks(posA.x, posA.y + 1, posA.z, posB.x, posB.y + 100, posB.z, 0)


def makeHouse(posA: Vec3, posB: Vec3, height=4, blockType=1):
    mc.setBlocks(posA.x, posA.y + 1, posA.z, posB.x,
                 posB.y + height, posB.z, blockType)
    mc.setBlocks(posA.x + 1, posA.y + 1, posA.z + 1, posB.x - 1,
                 posB.y + height - 1, posB.z - 1, 0)
    mc.setBlocks(posA.x, posA.y, posA.z, posB.x,
                 posB.y, posB.z, 5)


def makeStreets(basePos: Vec3, sizeX: int, sizeZ: int, blockTypes=[49, 43, 42]):
    roadSize = 4
    # Road centers positions
    posA = offsetPoint(basePos, roadSize, 0, roadSize)
    posB = offsetPoint(basePos, sizeX * 9 - roadSize, 0, sizeZ * 9 - roadSize)

    intersections = list()

    # Make streetes around city
    posAx = Vec3(posB.x, posA.y, posA.z)
    posAz = Vec3(posA.x, posA.y, posB.z)

    makeRoad(posA, posAx, blockTypes=blockTypes)
    makeRoad(posAz, posB, blockTypes=blockTypes)
    makeRoad(posA, posAz, blockTypes=blockTypes)
    makeRoad(posAx, posB, blockTypes=blockTypes)
    intersections.append(posA)
    intersections.append(posAx)
    intersections.append(posAz)
    intersections.append(posB)

    for inter in intersections:
        makeIntersection(inter, blockTypes=blockTypes)


def offsetPoint(point: Vec3, x=0, y=0, z=0):
    newPoint = point.clone()
    newPoint.x += x
    newPoint.y += y
    newPoint.z += z
    return newPoint


def makeIntersection(point: Vec3, blockTypes=[1, 2, 7]):
    roadOffset = 4
    mc.setBlocks(point.x - roadOffset, point.y, point.z - roadOffset,
                 point.x + roadOffset, point.y, point.z + roadOffset, blockTypes[0])

    # create greenAreas
    mc.setBlocks(point.x - roadOffset, point.y, point.z - roadOffset,
                 point.x - roadOffset + 1, point.y, point.z - roadOffset + 1, blockTypes[1])

    mc.setBlocks(point.x + roadOffset, point.y, point.z - roadOffset,
                 point.x + roadOffset - 1, point.y, point.z - roadOffset + 1, blockTypes[1])

    mc.setBlocks(point.x - roadOffset, point.y, point.z + roadOffset,
                 point.x - roadOffset + 1, point.y, point.z + roadOffset - 1, blockTypes[1])

    mc.setBlocks(point.x + roadOffset, point.y, point.z + roadOffset,
                 point.x + roadOffset - 1, point.y, point.z + roadOffset - 1, blockTypes[1])

    # create line endings

    mc.setBlocks(point.x + roadOffset, point.y, point.z,
                 point.x + roadOffset - 1, point.y, point.z, blockTypes[2])
    mc.setBlocks(point.x - roadOffset, point.y, point.z,
                 point.x - roadOffset + 1, point.y, point.z, blockTypes[2])
    mc.setBlocks(point.x, point.y, point.z + roadOffset,
                 point.x, point.y, point.z + roadOffset - 1, blockTypes[2])
    mc.setBlocks(point.x, point.y, point.z - roadOffset,
                 point.x, point.y, point.z - roadOffset + 1,  blockTypes[2])


def fillHouses(posA: Vec3, posB: Vec3, blockTypes=[82, 1, 3]):
    minHeight = 4
    maxHeight = 10
    for pos in vecItereator(posA, posB, 2):
        makeHouse(pos, offsetPoint(pos, 6, 0, 6), randint(
            minHeight, maxHeight), choice(blockTypes))


a = Vec3(0, 0, 0)
b = Vec3(3, 0, 3)

playerPos = Vec3(0, 4, 0)
playerPos.iround()

size = 10
MB = 9
# fillHouses(offsetPoint(playerPos, MB, 0, MB), offsetPoint(
#     playerPos, (size - 1) * MB, 0, (size - 1) * MB))

if __name__ == "__main__":
    createPlane(playerPos, offsetPoint(playerPos, size * MB, 0, size * MB))
    makeStreets(playerPos, size, size)
    housePointA = offsetPoint(playerPos, MB, 0, MB)
    housePointB = offsetPoint(playerPos, (size - 1) * MB, 0, (size - 1) * MB)
    blockTypes = [82, 1, 3]
    for house in splitIntoHouses(housePointA, housePointB):
        makeHouse(house[0], house[1], height=randint(
            4, 10), blockType=choice(blockTypes))

from mcpi.minecraft import Minecraft, Vec3
from minecraftstuff import MinecraftDrawing
from vecIterator import vecItereator
from random import randint, choice
from splitIntoHouses import splitIntoHouses

rpiIp = "192.168.1.182"

mc = Minecraft.create(address=rpiIp)
mcdraw = MinecraftDrawing(mc)


def makeRoad(posA: Vec3, posB: Vec3, blockTypes=[1, 2, 7]):
    if not (posA.x == posB.x or posA.z == posB.z):
        raise NotImplementedError

    roadCenterOffset = 4

    for i in range(-roadCenterOffset, roadCenterOffset + 1, 1):
        if i == 0:
            blockType = blockTypes[2]
        elif i <= -3 or i >= 3:
            blockType = blockTypes[1]
        else:
            blockType = blockTypes[0]

        if posA.x == posB.x:  # ----
            mcdraw.drawLine(posA.x + i, posA.y, posA.z - roadCenterOffset,
                            posB.x + i, posB.y, posB.z + roadCenterOffset, blockType)
        else:  # ||||
            mcdraw.drawLine(posA.x - roadCenterOffset, posA.y, posA.z + i,
                            posB.x + roadCenterOffset, posB.y, posB.z + i, blockType)


def createPlane(posA: Vec3, posB: Vec3, blockType=1):
    mc.setBlocks(posA.x, posA.y, posA.z, posB.x, posB.y, posB.z, blockType)
    mc.setBlocks(posA.x, posA.y + 1, posA.z, posB.x, posB.y + 100, posB.z, 0)


def makeHouse(posA: Vec3, posB: Vec3, height=4, blockType=1):
    mc.setBlocks(posA.x, posA.y + 1, posA.z, posB.x,
                 posB.y + height, posB.z, blockType)
    mc.setBlocks(posA.x + 1, posA.y + 1, posA.z + 1, posB.x - 1,
                 posB.y + height - 1, posB.z - 1, 0)
    mc.setBlocks(posA.x, posA.y, posA.z, posB.x,
                 posB.y, posB.z, 5)


def makeStreets(basePos: Vec3, sizeX: int, sizeZ: int, blockTypes=[49, 43, 42]):
    roadSize = 4
    # Road centers positions
    posA = offsetPoint(basePos, roadSize, 0, roadSize)
    posB = offsetPoint(basePos, sizeX * 9 - roadSize, 0, sizeZ * 9 - roadSize)

    intersections = list()

    # Make streetes around city
    posAx = Vec3(posB.x, posA.y, posA.z)
    posAz = Vec3(posA.x, posA.y, posB.z)

    makeRoad(posA, posAx, blockTypes=blockTypes)
    makeRoad(posAz, posB, blockTypes=blockTypes)
    makeRoad(posA, posAz, blockTypes=blockTypes)
    makeRoad(posAx, posB, blockTypes=blockTypes)
    intersections.append(posA)
    intersections.append(posAx)
    intersections.append(posAz)
    intersections.append(posB)

    for inter in intersections:
        makeIntersection(inter, blockTypes=blockTypes)


def offsetPoint(point: Vec3, x=0, y=0, z=0):
    newPoint = point.clone()
    newPoint.x += x
    newPoint.y += y
    newPoint.z += z
    return newPoint


def makeIntersection(point: Vec3, blockTypes=[1, 2, 7]):
    roadOffset = 4
    mc.setBlocks(point.x - roadOffset, point.y, point.z - roadOffset,
                 point.x + roadOffset, point.y, point.z + roadOffset, blockTypes[0])

    # create greenAreas
    mc.setBlocks(point.x - roadOffset, point.y, point.z - roadOffset,
                 point.x - roadOffset + 1, point.y, point.z - roadOffset + 1, blockTypes[1])

    mc.setBlocks(point.x + roadOffset, point.y, point.z - roadOffset,
                 point.x + roadOffset - 1, point.y, point.z - roadOffset + 1, blockTypes[1])

    mc.setBlocks(point.x - roadOffset, point.y, point.z + roadOffset,
                 point.x - roadOffset + 1, point.y, point.z + roadOffset - 1, blockTypes[1])

    mc.setBlocks(point.x + roadOffset, point.y, point.z + roadOffset,
                 point.x + roadOffset - 1, point.y, point.z + roadOffset - 1, blockTypes[1])

    # create line endings

    mc.setBlocks(point.x + roadOffset, point.y, point.z,
                 point.x + roadOffset - 1, point.y, point.z, blockTypes[2])
    mc.setBlocks(point.x - roadOffset, point.y, point.z,
                 point.x - roadOffset + 1, point.y, point.z, blockTypes[2])
    mc.setBlocks(point.x, point.y, point.z + roadOffset,
                 point.x, point.y, point.z + roadOffset - 1, blockTypes[2])
    mc.setBlocks(point.x, point.y, point.z - roadOffset,
                 point.x, point.y, point.z - roadOffset + 1,  blockTypes[2])


def fillHouses(posA: Vec3, posB: Vec3, blockTypes=[82, 1, 3]):
    minHeight = 4
    maxHeight = 10
    for pos in vecItereator(posA, posB, 2):
        makeHouse(pos, offsetPoint(pos, 6, 0, 6), randint(
            minHeight, maxHeight), choice(blockTypes))


a = Vec3(0, 0, 0)
b = Vec3(3, 0, 3)

playerPos = Vec3(0, 4, 0)
playerPos.iround()

size = 10
MB = 9
# fillHouses(offsetPoint(playerPos, MB, 0, MB), offsetPoint(
#     playerPos, (size - 1) * MB, 0, (size - 1) * MB))

if __name__ == "__main__":
    createPlane(playerPos, offsetPoint(playerPos, size * MB, 0, size * MB))
    makeStreets(playerPos, size, size)
    housePointA = offsetPoint(playerPos, MB, 0, MB)
    housePointB = offsetPoint(playerPos, (size - 1) * MB, 0, (size - 1) * MB)
    blockTypes = [82, 1, 3]
    for house in splitIntoHouses(housePointA, housePointB):
        makeHouse(house[0], house[1], height=randint(
            4, 10), blockType=choice(blockTypes))

# ---- # |||| # Road centers positions # Make streetes around city # create greenAreas # create line endings # fillHouses(offsetPoint(playerPos, MB, 0, MB), offsetPoint( #     playerPos, (size - 1) * MB, 0, (size - 1) * MB))