// File: halsafar[P]libtmx-parser/./src/tmxparser.cpp
// Function: tmxparser::_parseLayerDataNode(tinyxml2::XMLElement*, std::vector<tmxparser::TmxTileset, std::allocator<tmxparser::TmxTileset>> const&, std::vector<tmxparser::TmxLayerTile, std::allocator<tmxparser::TmxLayerTile>>*)
TmxReturn _parseLayerDataNode(tinyxml2::XMLElement* element, const TmxTilesetCollection_t& tilesets, TmxLayerTileCollection_t* outTileCollection)
{
	TmxReturn error = TmxReturn::kSuccess;

	const char* encoding = element->Attribute("encoding");
	const char* compression = element->Attribute("compression");

	if (compression != NULL)
	{
		LOGE("Does not support compression yet...");
		return TmxReturn::kErrorParsing;
	}

	if (encoding == NULL)
	{
		for (tinyxml2::XMLElement* child = element->FirstChildElement("tile"); child != NULL; child = child->NextSiblingElement("tile"))
		{
			TmxLayerTile tile;
			error = _parseLayerXmlTileNode(child, tilesets, &tile);
			outTileCollection->push_back(tile);
		}
	}
	else if (strcmp(encoding, "csv") == 0)
	{
		std::stringstream csvss(element->FirstChild()->Value());
		//LOGE("TEXT = %s", csv.c_str());

		unsigned int gid = 0;
		while (csvss >> gid)
		{
			if (csvss.peek() == ',' || csvss.peek() == '\n')
			{
				csvss.ignore();
			}

			TmxLayerTile tile;

			tile.gid = gid;
			error = _calculateTileIndices(tilesets, &tile);
			if (error == TmxReturn::kErrorParsing)
			{
				return error;
			}

			outTileCollection->push_back(tile);
		}
	}
	else if (strcmp(encoding, "base64") == 0)
	{
		std::string csvbase64 = element->FirstChild()->Value();

		csvbase64.erase(std::remove(csvbase64.begin(), csvbase64.end(), '\n'), csvbase64.end());
		csvbase64.erase(std::remove(csvbase64.begin(), csvbase64.end(), '\r'), csvbase64.end());
		csvbase64.erase(std::remove(csvbase64.begin(), csvbase64.end(), ' '), csvbase64.end());

		std::string csv = base64_decode(csvbase64);

		unsigned int length = csv.size() / sizeof(unsigned int);

		// tiled base64 layer data is an unsigned 32bit array little endian
		// TODO - verify this on other platforms, write some tests
		unsigned int* p = (unsigned int*)csv.c_str();
		for (unsigned int i = 0; i < length; i++)
		{
			TmxLayerTile tile;
			tile.gid = p[i];
			error = _calculateTileIndices(tilesets, &tile);
			if (error == TmxReturn::kErrorParsing)
			{
				return error;
			}

			outTileCollection->push_back(tile);
		}
	}
	else
	{
		LOGE("Unsupported layer compression [%s]... coming soon...", encoding);
		return TmxReturn::kErrorParsing;
	}

	return error;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400, %rsp            # imm = 0x400
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x1b95d(%rip), %rsi     # 0x22446
xorl %eax, %eax
movl %eax, %edx
callq 0x1c710
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x1b94e(%rip), %rsi     # 0x2244f
xorl %eax, %eax
movl %eax, %edx
callq 0x1c710
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x6b51
movq 0x2c4bc(%rip), %rax     # 0x32fd8
movq (%rax), %rdi
leaq 0x1b935(%rip), %rsi     # 0x2245b
movb $0x0, %al
callq 0x43a0
movq 0x2c4a4(%rip), %rax     # 0x32fd8
movq (%rax), %rdi
leaq 0x1bdf2(%rip), %rsi     # 0x22930
movb $0x0, %al
callq 0x43a0
movl $0x1, -0x4(%rbp)
jmp 0x7288
cmpq $0x0, -0x30(%rbp)
jne 0x6baf
movq -0x10(%rbp), %rdi
leaq 0x1b7dd(%rip), %rsi     # 0x22340
callq 0x7b60
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x6baa
movq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x72a0
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x85c0
movq -0x40(%rbp), %rdi
leaq 0x1b7a1(%rip), %rsi     # 0x22340
callq 0x7f80
movq %rax, -0x40(%rbp)
jmp 0x6b6c
jmp 0x7282
movq -0x30(%rbp), %rdi
leaq 0x1b8d7(%rip), %rsi     # 0x22491
callq 0x4390
cmpl $0x0, %eax
jne 0x6de8
movq -0x10(%rbp), %rdi
callq 0x8630
movq %rax, %rdi
callq 0x1abc0
movq %rax, -0x368(%rbp)
leaq -0x1f9(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x4480
movq -0x368(%rbp), %rsi
movq -0x360(%rbp), %rdx
leaq -0x1f8(%rbp), %rdi
callq 0x4370
jmp 0x6c0f
movl $0x10, %edi
movl $0x8, %esi
callq 0x8650
movl %eax, -0x36c(%rbp)
jmp 0x6c26
movl -0x36c(%rbp), %edx
leaq -0x1d8(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x4400
jmp 0x6c41
leaq -0x1f8(%rbp), %rdi
callq 0x4508
leaq -0x1f9(%rbp), %rdi
callq 0x42a0
movl $0x0, -0x210(%rbp)
leaq -0x1d8(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x4080
movq %rax, -0x378(%rbp)
jmp 0x6c7f
movq -0x378(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x4300
movb %al, -0x379(%rbp)
jmp 0x6c9d
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0x6cac
jmp 0x6dbc
leaq -0x1d8(%rbp), %rdi
callq 0x40e0
movl %eax, -0x380(%rbp)
jmp 0x6cc0
movl -0x380(%rbp), %eax
cmpl $0x2c, %eax
je 0x6cea
leaq -0x1d8(%rbp), %rdi
callq 0x40e0
movl %eax, -0x384(%rbp)
jmp 0x6cdf
movl -0x384(%rbp), %eax
cmpl $0xa, %eax
jne 0x6d60
leaq -0x1d8(%rbp), %rdi
callq 0x4490
jmp 0x6cf8
jmp 0x6d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x208(%rbp)
movl %eax, -0x20c(%rbp)
jmp 0x6d2c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x208(%rbp)
movl %eax, -0x20c(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x4508
leaq -0x1f9(%rbp), %rdi
callq 0x42a0
jmp 0x7294
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x208(%rbp)
movl %eax, -0x20c(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x41d0
jmp 0x7294
movl -0x210(%rbp), %eax
movl %eax, -0x220(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x7350
movl %eax, -0x388(%rbp)
jmp 0x6d84
movl -0x388(%rbp), %eax
movl %eax, -0x24(%rbp)
cmpl $0x1, -0x24(%rbp)
jne 0x6da5
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x224(%rbp)
jmp 0x6dc6
movq -0x20(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x85c0
jmp 0x6db7
jmp 0x6c63
movl $0x0, -0x224(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x41d0
movl -0x224(%rbp), %eax
testl %eax, %eax
je 0x6de3
jmp 0x6dde
jmp 0x7288
jmp 0x7280
movq -0x30(%rbp), %rdi
leaq 0x1b6a2(%rip), %rsi     # 0x22495
callq 0x4390
cmpl $0x0, %eax
jne 0x7241
movq -0x10(%rbp), %rdi
callq 0x8630
movq %rax, %rdi
callq 0x1abc0
movq %rax, -0x398(%rbp)
leaq -0x249(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0x4480
movq -0x398(%rbp), %rsi
movq -0x390(%rbp), %rdx
leaq -0x248(%rbp), %rdi
callq 0x4370
jmp 0x6e48
leaq -0x249(%rbp), %rdi
callq 0x42a0
leaq -0x248(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x4200
movq -0x3a8(%rbp), %rdi
movq %rax, -0x268(%rbp)
callq 0x4180
movq %rax, -0x270(%rbp)
movb $0xa, -0x271(%rbp)
movq -0x268(%rbp), %rdi
movq -0x270(%rbp), %rsi
leaq -0x271(%rbp), %rdx
callq 0x8670
movq %rax, -0x3a0(%rbp)
jmp 0x6eab
movq -0x3a0(%rbp), %rax
movq %rax, -0x260(%rbp)
leaq -0x258(%rbp), %rdi
leaq -0x260(%rbp), %rsi
callq 0x86c0
leaq -0x248(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x4180
movq %rax, -0x288(%rbp)
leaq -0x280(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x86c0
movq -0x3b8(%rbp), %rdi
movq -0x258(%rbp), %rsi
movq -0x280(%rbp), %rdx
callq 0x40a0
movq %rax, -0x3b0(%rbp)
jmp 0x6f1c
movq -0x3b0(%rbp), %rax
movq %rax, -0x290(%rbp)
leaq -0x248(%rbp), %rdi
movq %rdi, -0x3c8(%rbp)
callq 0x4200
movq -0x3c8(%rbp), %rdi
movq %rax, -0x2a8(%rbp)
callq 0x4180
movq %rax, -0x2b0(%rbp)
movb $0xd, -0x2b1(%rbp)
movq -0x2a8(%rbp), %rdi
movq -0x2b0(%rbp), %rsi
leaq -0x2b1(%rbp), %rdx
callq 0x8670
movq %rax, -0x3c0(%rbp)
jmp 0x6f81
movq -0x3c0(%rbp), %rax
movq %rax, -0x2a0(%rbp)
leaq -0x298(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
callq 0x86c0
leaq -0x248(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x4180
movq %rax, -0x2c8(%rbp)
leaq -0x2c0(%rbp), %rdi
leaq -0x2c8(%rbp), %rsi
callq 0x86c0
movq -0x3d8(%rbp), %rdi
movq -0x298(%rbp), %rsi
movq -0x2c0(%rbp), %rdx
callq 0x40a0
movq %rax, -0x3d0(%rbp)
jmp 0x6ff2
movq -0x3d0(%rbp), %rax
movq %rax, -0x2d0(%rbp)
leaq -0x248(%rbp), %rdi
movq %rdi, -0x3e8(%rbp)
callq 0x4200
movq -0x3e8(%rbp), %rdi
movq %rax, -0x2e8(%rbp)
callq 0x4180
movq %rax, -0x2f0(%rbp)
movb $0x20, -0x2f1(%rbp)
movq -0x2e8(%rbp), %rdi
movq -0x2f0(%rbp), %rsi
leaq -0x2f1(%rbp), %rdx
callq 0x8670
movq %rax, -0x3e0(%rbp)
jmp 0x7057
movq -0x3e0(%rbp), %rax
movq %rax, -0x2e0(%rbp)
leaq -0x2d8(%rbp), %rdi
leaq -0x2e0(%rbp), %rsi
callq 0x86c0
leaq -0x248(%rbp), %rdi
movq %rdi, -0x3f8(%rbp)
callq 0x4180
movq %rax, -0x308(%rbp)
leaq -0x300(%rbp), %rdi
leaq -0x308(%rbp), %rsi
callq 0x86c0
movq -0x3f8(%rbp), %rdi
movq -0x2d8(%rbp), %rsi
movq -0x300(%rbp), %rdx
callq 0x40a0
movq %rax, -0x3f0(%rbp)
jmp 0x70c8
movq -0x3f0(%rbp), %rax
movq %rax, -0x310(%rbp)
leaq -0x330(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x21200
jmp 0x70eb
leaq -0x330(%rbp), %rdi
callq 0x41c0
shrq $0x2, %rax
movl %eax, -0x334(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x4100
movq %rax, -0x340(%rbp)
movl $0x0, -0x344(%rbp)
movl -0x344(%rbp), %eax
cmpl -0x334(%rbp), %eax
jae 0x7201
movq -0x340(%rbp), %rax
movl -0x344(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x354(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x354(%rbp), %rsi
callq 0x7350
movl %eax, -0x3fc(%rbp)
jmp 0x715e
movl -0x3fc(%rbp), %eax
movl %eax, -0x24(%rbp)
cmpl $0x1, -0x24(%rbp)
jne 0x71d9
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x224(%rbp)
jmp 0x720b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x208(%rbp)
movl %eax, -0x20c(%rbp)
leaq -0x249(%rbp), %rdi
callq 0x42a0
jmp 0x7294
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x208(%rbp)
movl %eax, -0x20c(%rbp)
jmp 0x7233
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x208(%rbp)
movl %eax, -0x20c(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x4508
jmp 0x7233
movq -0x20(%rbp), %rdi
leaq -0x354(%rbp), %rsi
callq 0x85c0
jmp 0x71eb
jmp 0x71ed
movl -0x344(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x344(%rbp)
jmp 0x711e
movl $0x0, -0x224(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x4508
leaq -0x248(%rbp), %rdi
callq 0x4508
movl -0x224(%rbp), %eax
testl %eax, %eax
je 0x7231
jmp 0x722f
jmp 0x7288
jmp 0x727e
leaq -0x248(%rbp), %rdi
callq 0x4508
jmp 0x7294
movq 0x2bd90(%rip), %rax     # 0x32fd8
movq (%rax), %rdi
movq -0x30(%rbp), %rdx
leaq 0x1b246(%rip), %rsi     # 0x2249c
movb $0x0, %al
callq 0x43a0
movq 0x2bd74(%rip), %rax     # 0x32fd8
movq (%rax), %rdi
leaq 0x1b6c2(%rip), %rsi     # 0x22930
movb $0x0, %al
callq 0x43a0
movl $0x1, -0x4(%rbp)
jmp 0x7288
jmp 0x7280
jmp 0x7282
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x400, %rsp            # imm = 0x400
popq %rbp
retq
movq -0x208(%rbp), %rdi
callq 0x4470