package net.anti344.tm.client.render.connected
import net.anti344.tm.client.render.connected.texture.{RotatedIcon, ConnectedIcon}
import net.anti344.tm.util.mixin.block.ConnectedTextures
import net.anti344.tm.util.mixin.TessellationHelper
import net.anti344.tm.util.Position
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.common.util.ForgeDirection._
import net.minecraft.client.renderer.RenderBlocks
import net.minecraft.world.IBlockAccess
import net.minecraft.block.Block
object ConnectedBlockRender extends ISimpleBlockRenderingHandler with TessellationHelper{
override def shouldRender3DInInventory(modelId: Int): Boolean = true
override def getRenderId: Int = -1
val xyzToForgeMap: Array[Int] = Array(5, 4, 1, 0, 3, 2)
var x: Double = 0.0
var y: Double = 0.0
var z: Double = 0.0
override def renderInventoryBlock(block: Block, meta: Int, modelId: Int, ctx: RenderBlocks) = {
val item: RotatedIcon = block.asInstanceOf[ConnectedTextures].getConnectedIcon(meta).item
tess.setBrightness(983055)
tess.setColorOpaque_F(1.0F, 1.0F, 1.0F)
x = -0.5
y = -0.5
z = -0.5
withoutItemLighting(quad((0 until 6).foreach(drawQuad(_, item))))
}
val sides: Array[Array[ForgeDirection]] =
Array(Array(UP, SOUTH, DOWN, NORTH),
Array(NORTH, EAST, SOUTH, WEST),
Array(UP, EAST, DOWN, WEST))
override def renderWorldBlock(iba: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, ctx: RenderBlocks): Boolean = {
this.x = x
this.y = y
this.z = z
if(ctx.hasOverrideBlockTexture){
val face: RotatedIcon = new RotatedIcon(ctx.overrideBlockTexture)
for(i <- 0 until 6)
drawQuad(i, face)
}else{
val b: ConnectedTextures = block.asInstanceOf[ConnectedTextures]
val pos: Position = new Position(x, y, z)
val texture: ConnectedIcon = b.getConnectedIcon(iba, x, y, z)
val corners: Boolean = !b.removeCorners
tess.setBrightness(b.getMixedBrightnessForBlock(iba, x, y, z))
tess.setColorOpaque_F(1.0F, 1.0F, 1.0F)
for(i <- 0 until 6)
if(!b.canConnectTo(iba, pos.copy.shift(xyzToForgeMap(i))))
drawQuad(i, texture.background)
for(i <- 0 until 6) for(j <- 0 until 4)
if(!b.canConnectTo(iba, pos.copy.shift(xyzToForgeMap(i))) && !b.canConnectTo(iba, pos.copy.shift(sides(i / 2)(j))))
drawQuad(i, texture.side.rotate(j))
for(i <- 0 until 6) for(j <- 0 until 4){
val next: Boolean = !b.canConnectTo(iba, pos.copy.shift(sides(i / 2)(j)))
if(!b.canConnectTo(iba, pos.copy.shift(xyzToForgeMap(i))))
if(!b.canConnectTo(iba, pos.copy.shift(sides(i / 2)(if(j == 0) 3 else j - 1))))
if(next)
drawQuad(i, texture.corner_in.rotate(j))
else
drawQuad(i, texture.corner_vert.rotate(j))
else if(next)
drawQuad(i, texture.corner_hor.rotate(j))
else if(corners || !b.canConnectTo(iba, pos.copy.shift(sides(i / 2)(j)).shift(sides(i / 2)(if(j == 0) 3 else j - 1))))
drawQuad(i, texture.corner_out.rotate(j))
}
}
true
}
private val quads: Array[((Int, Int, Int), (Int, Int, Int), (Int, Int, Int), (Int, Int, Int), RotatedIcon => RotatedIcon)] =
Array(((1, 0, 1), (1, 0, 0), (1, 1, 0), (1, 1, 1), i => i),
((0, 0, 1), (0, 1, 1), (0, 1, 0), (0, 0, 0), i => i.invert().rotate(3)),
((0, 1, 1), (1, 1, 1), (1, 1, 0), (0, 1, 0), i => i.invert()),
((1, 0, 1), (0, 0, 1), (0, 0, 0), (1, 0, 0), i => i),
((1, 0, 1), (1, 1, 1), (0, 1, 1), (0, 0, 1), i => i.invert().rotate(3)),
((1, 0, 0), (0, 0, 0), (0, 1, 0), (1, 1, 0), i => i))
def drawQuad(side: Int, icon: RotatedIcon) = {
val quad = quads(side)
val _icon: RotatedIcon = quad._5(icon)
vertexUV(x + quad._1._1, y + quad._1._2, z + quad._1._3, _icon.getUV_1.getU, _icon.getUV_1.getV)
vertexUV(x + quad._2._1, y + quad._2._2, z + quad._2._3, _icon.getUV_2.getU, _icon.getUV_2.getV)
vertexUV(x + quad._3._1, y + quad._3._2, z + quad._3._3, _icon.getUV_3.getU, _icon.getUV_3.getV)
vertexUV(x + quad._4._1, y + quad._4._2, z + quad._4._3, _icon.getUV_4.getU, _icon.getUV_4.getV)
}
}