package org.artisanlogiciel.games.minetest;

import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;

import java.nio.ByteBuffer;
import java.util.List;

public class MapNode {
	/*
		Main content
	*/
	short param0;

	/*
		Misc parameter. Initialized to 0.
		- For light_propagates() blocks, this is light intensity,
		  stored logarithmically from 0 to LIGHT_MAX.
		  Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
		  - Contains 2 values, day- and night lighting. Each takes 4 bits.
		- Uhh... well, most blocks have light or nothing in here.
	*/
	byte param1;

	/*
		The second parameter. Initialized to 0.
		E.g. direction for torches and flowing water.
	*/
	byte param2;

    public void deSerialize(ByteBuffer buffer)
            throws PacketException
    {
        // version >= 24
		param0 = (short) Serialize.readU16(buffer);
        buffer.position(buffer.position() + 2);
        param1 = (byte) Serialize.readU8(buffer);
        buffer.position(buffer.position() + 1);
		param2 = (byte) Serialize.readU8(buffer);
        // network specific ...
        // readU8(is);

    }

	// Deserialize bulk node data
	public static void deSerializeBulk(ByteBuffer buffer, int version,
									   List<MapNode> nodes, int nodecount,
									   int content_width, int params_width)
		throws PacketException
	{
		byte[] intern = buffer.array();
		int initialOffset = buffer.position();

		// Deserialize content
		if(content_width == 1)
		{
			for(int i=0; i<nodecount; i++) {
				nodes.add(i, new MapNode());
				nodes.get(i).param0 = (short) Serialize.readU8( intern, initialOffset + i, intern.length);
			}
		}
		else if(content_width == 2)
		{
			for(int i=0; i<nodecount; i++) {
				nodes.add(i, new MapNode());
				nodes.get(i).param0 = (short) Serialize.readU8( intern, initialOffset + (i*2), intern.length);
			}
		}

		// Deserialize param1
		int start1 = initialOffset + (content_width * nodecount);
		for(int i=0; i<nodecount; i++) {
			nodes.get(i).param1 = (byte) Serialize.readU8( intern, start1 + i, intern.length);
		}

		// Deserialize param2
		int start2 = initialOffset + ((content_width + 1) * nodecount);
		if(content_width == 1)
		{
			for(int i=0; i<nodecount; i++) {
				MapNode node = nodes.get(i);
				node.param2 = (byte) Serialize.readU8( intern, start2 + i, intern.length);
				if(node.param0 > 0x7F){
					node.param0 <<= 4;
					node.param0 |= (node.param2&0xF0)>>4;
					node.param2 &= 0x0F;
				}
			}
		}
		else if(content_width == 2)
		{
			for(int i=0; i<nodecount; i++) {
				nodes.get(i).param2 = (byte) Serialize.readU8(intern, start2 + i, intern.length);
			}
		}

	}

}
