summaryrefslogblamecommitdiffstats
path: root/friendfinder/map/overlay.c
blob: 1566040d73bf397457c6abff5d159f323b22e08b (plain) (tree)
































































































































































































































































                                                                                                            
#include <stdio.h>
#include <string.h>

#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Edje.h>
#include <Elementary.h>
#include <Eina.h>

#include "e_smart_tile.h"

#include "smart_map_priv.h"

struct map_overlay *overlay_find_by_name(struct smart_map *smart, char *name)
{
	int i;
	struct map_overlay *ov = NULL;
	Eina_Array_Iterator iterator;
	
	EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
	{
		if(strcmp(ov->name, name) == 0)
			return ov;
	}
	return NULL;	
}

struct map_overlay *overlay_create(struct smart_map *smart, char *name)
{
	int i;
	struct map_overlay *ov = malloc(sizeof(struct map_overlay));
	if(ov == NULL)
		return NULL;

	eina_array_init();
	ov->name = strdup(name);
	ov->parent = smart;
	ov->state = OVERLAY_VISIBLE;

	ov->hash = eina_hash_string_superfast_new(NULL);
	for(i = 0; i < OSM_LEVEL_COUNT; i++)
		ov->pois[i] = NULL;

	ov->current_level = -1;
	return ov;
}

void overlay_add(struct smart_map *smart, struct map_overlay *ov, struct overlay_item *poi)
{
	int i;
	if(ov == NULL)
		return;

	for(i = 1; i < OSM_LEVEL_COUNT; i++)
	{
		unsigned int mask = 1<<i;
		if(!(poi->level_mask & mask))
			continue;

		if(ov->pois[i] == NULL)
			ov->pois[i] = eina_array_new(4);

		eina_array_push(ov->pois[i], poi);
	}
}

static void _hash_item(struct smart_map *smart, struct map_overlay *ov, struct overlay_item *poi, int level)
{
	int x, y, tx, ty;
	char buf[64];
	Eina_Array *items;
	struct map_level_info *li;
	li = map_info_get_level(smart->mi, &level);
	
	if(latlon_to_map(li, poi->lat, poi->lon, &x, &y) < 0)
		return;

	tx = x / smart->mi->tile_size + li->min_x; 
	ty = y / smart->mi->tile_size + li->min_y;
	poi->level_data.ox = x % smart->mi->tile_size; 
	poi->level_data.oy = y % smart->mi->tile_size;
	poi->level_data.visible = 1;

	snprintf(buf, 64, "%i/%i/%i", level, tx, ty);
	items = eina_hash_find(ov->hash, (const void *)buf);
	if(items == NULL)
	{
		items = eina_array_new(4);
		eina_array_push(items, poi);
		eina_hash_add(ov->hash, buf, items);
	}
	else
	{
		eina_array_push(items, poi);
	}
}

static void _overlay_hide(struct smart_map *smart, struct map_overlay *ov, int newstate)
{
	Eina_Array_Iterator iterator;
	int i;
	struct overlay_item *poi;

	if(ov->state == OVERLAY_HIDDEN)
		return;

	if(ov->current_level <= 0)
		return;

	if(ov->pois[ov->current_level] == NULL)
		return;
	ov->state = newstate;
	
	EINA_ARRAY_ITER_NEXT(ov->pois[ov->current_level], i, poi, iterator)
	{
		evas_object_hide(poi->obj->obj); 
	}
}

void overlay_hide(struct smart_map *smart, char *name)
{
	struct map_overlay *ov = overlay_find_by_name(smart, name);
	if(ov == NULL)
		return;

	_overlay_hide(smart, ov, OVERLAY_HIDDEN);
}

void overlay_hide_all(struct smart_map *smart)
{
	Eina_Array_Iterator iterator;
	int i;
	struct map_overlay *ov;


	EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
	{
		_overlay_hide(smart, ov, OVERLAY_HIDDEN);
	}
} 

static void _overlay_change_level(struct smart_map *smart, struct map_overlay *ov, int level)
{
	Eina_Array_Iterator iterator;
	int i;
	struct overlay_item *poi;

	if(level >= OSM_LEVEL_COUNT)
	{
		printf("overlay_change_level: level %i not supported\n", level);
		return;
	}

	if(ov->current_level > 0 && ov->current_level < OSM_LEVEL_COUNT)
		_overlay_hide(smart, ov, ov->state);
	
	eina_hash_free(ov->hash); //XXX
	ov->hash = eina_hash_string_superfast_new(NULL);
	ov->current_level = level;

	if(ov->pois[level] == NULL)
		return;

	EINA_ARRAY_ITER_NEXT(ov->pois[level], i, poi, iterator)
	{
		_hash_item(smart, ov, poi, level);
	}
}	

void overlay_change_level(struct smart_map *smart, int level)
{
	Eina_Array_Iterator iterator;
	int i;
	struct map_overlay *ov;

	EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
	{
		_overlay_change_level(smart, ov, level);
	}
}
	
static inline void 
_overlay_unload(struct smart_map *smart, struct map_overlay *ov, struct osm_data *osm)
{
	char buf[64];
	struct map_level_info *li;
	Eina_Array *items;
	Eina_Array_Iterator iterator;
	unsigned int i;
	struct overlay_item *oi;
	
	snprintf(buf, 64, "%i/%i/%i", osm->z, osm->x, osm->y);
	items = eina_hash_find(ov->hash, (const void *)buf);
	if(items == NULL)
	{
		return;
	}
	
	EINA_ARRAY_ITER_NEXT(items, i, oi, iterator)
	{
		evas_object_hide(oi->obj->obj);
	}
}

void overlay_unload(struct smart_map *smart, struct osm_data *osm)
{
	Eina_Array_Iterator iterator;
	int i;
	struct map_overlay *ov;

	EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
	{
		_overlay_unload(smart, ov, osm);
	}
}

static void inline
_overlay_update(struct smart_map *smart, struct map_overlay *ov, struct osm_data *osm, int xoff, int yoff)
{
	char buf[64];
	Eina_Array *items;
	Eina_Array_Iterator iterator;
	unsigned int i;
	struct overlay_item *oi;

	snprintf(buf, 64, "%i/%i/%i", osm->z, osm->x, osm->y);
	items = eina_hash_find(ov->hash, (const void *)buf);
	if(items == NULL)
	{
		return;
	}
	
	EINA_ARRAY_ITER_NEXT(items, i, oi, iterator)
	{
		struct overlay_object *obj = oi->obj;
		evas_object_move(obj->obj,
			xoff + oi->level_data.ox + obj->ox, 
			yoff + oi->level_data.oy + obj->oy);
		evas_object_resize(oi->obj->obj, obj->sw, obj->sh);
	//	if(oi->level_data.visible)
		evas_object_show(oi->obj->obj);
	}
}

void overlay_update(struct smart_map *smart, struct osm_data *osm, int xoff, int yoff)
{
	Eina_Array_Iterator iterator;
	int i;
	struct map_overlay *ov;

	EINA_ARRAY_ITER_NEXT(smart->overlays, i, ov, iterator)
	{
		if(ov->state != OVERLAY_VISIBLE)
			continue;
		_overlay_update(smart, ov, osm, xoff, yoff);
	}
}