/*
    c99tree - input layer, uid->node_t cache
    Copyright (C) 2015  Tibor Palinkas

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <stdlib.h>
#include <string.h>
#include "tree.h"
#include "tree_load_uid.h"

/* temp hack until error handling is fixed */
#include <stdio.h>

struct uid2node_s {
	node_t **uid2node;
	int alloced;
};

void uid2node_save(uid2node_t *cache,node_t *n)
{
	if (n->uid >= cache->alloced) {
		int last_alloced;
		last_alloced = cache->alloced;
		cache->alloced = n->uid + 256;
		cache->uid2node = realloc(cache->uid2node, sizeof(node_t *) * cache->alloced);
		memset(&cache->uid2node[last_alloced], 0, sizeof(node_t *) * (cache->alloced - last_alloced));
	}
	cache->uid2node[n->uid] = n;
}

static void uid2node_resolve_(uid2node_t *cache, node_t *node)
{
	if ((node->loc.twin_parent_uid > 0) && (node->loc.twin_parent_uid < cache->alloced)) {
		if (cache->uid2node[node->loc.twin_parent_uid] == 0)
			fprintf(stderr, "xml load error: referencing non-existing twin-parent: %d\n", node->loc.twin_parent_uid);
		node->loc.twin_parent = cache->uid2node[node->loc.twin_parent_uid];
	}
	node->loc.twin_parent_uid = -1;
}

void uid2node_resolve(uid2node_t *cache, node_t *root)
{
	for(; root != NULL; root = root->next) {
		uid2node_resolve_(cache, root);
		if (root->children != NULL)
			uid2node_resolve(cache, root->children);
	}
}

uid2node_t *uid2node_alloc(void)
{
	uid2node_t *cache;
	cache = calloc(sizeof(uid2node_t), 1);
	return cache;
}

void uid2node_free(uid2node_t *cache)
{
	if (cache->uid2node != NULL)
		free(cache->uid2node);
	free(cache);
}
