summaryrefslogblamecommitdiffstats
path: root/friendfinder/map/object.c
blob: f4f4c0b18bc81f5dcac66f787999feb83896e74a (plain) (tree)















































































































































































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

#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Evas.h>
#include <Edje.h>

#include "e_smart_tile.h"

#include "smart_map_priv.h"

static void tile_array_add(struct smart_map *smart, int index)
{
	smart->ta.tiles[index] = e_smart_tile_add(smart->evas);
	evas_object_smart_member_add(smart->ta.tiles[index], smart->obj);
	evas_object_clip_set(smart->ta.tiles[index], smart->clip);
	evas_object_pass_events_set(smart->ta.tiles[index], 1);
	evas_object_stack_below(smart->ta.tiles[index], smart->clip);
}

static int tile_array_resize(struct tile_array *ta, struct smart_map *smart, int tw, int th)
{
	int i;
	if(ta->tiles == NULL)
	{	
		ta->tiles = calloc(1, tw * th * sizeof(Evas_Object *));
		if(ta->tiles == NULL)
			return -1;
		ta->tw = tw;
		ta->th = th;
		for(i = 0; i < tw*th; i++)
			tile_array_add(smart, i);
		return 0;
	}
	
	int oldsize = smart->ta.tw * smart->ta.th;
	if(oldsize < tw*th)
	{
		ta->tiles = realloc(ta->tiles, tw * th * sizeof(Evas_Object *));
		if(smart->ta.tiles == NULL)
			return -1;

		for(i = oldsize; i < tw*th; i++)
			tile_array_add(smart, i);
	}
	else
	{
		for(i = tw*th; i < oldsize; i++)
		{
			evas_object_del(ta->tiles[i]);
			evas_object_smart_member_del(ta->tiles[i]);
		}
		
		ta->tiles = realloc(ta->tiles, 
			tw * th * sizeof(Evas_Object *));
		if(ta->tiles == NULL)
			return -1;
	}
	ta->tw = tw;
	ta->th = th;
	return 0;
}

static inline int tile_array_update(struct tile_array *ta, struct map_level_info *li)
{
	if(ta->mode == POSITION_WORLD)
	{
		if(latlon_to_map(li, ta->lat, ta->lon, &ta->ox, &ta->oy) < 0)
			return -1;
		ta->ox -= ta->w/2;
		ta->oy -= ta->h/2;
		ta->mode = POSITION_PX;
	}
	else
	{
		if(map_to_latlon(li, ta->ox + ta->w/2, ta->oy + ta->h/2, &ta->lat, &ta->lon) < 0)
			return -1;
	}
	return 0;
}

static int fill_tiles(struct smart_map *smart)
{
	int tx, ty;
	int xmin, ymin, xoffset, yoffset;
	int tile_size = smart->mi->tile_size;
	struct tile_array *ta = &smart->ta;
	Eina_Array_Iterator iterator;
	int i;
	Evas_Object *path;

	if(smart->li == NULL)
		return -1;
	
	tile_array_update(ta, smart->li);

	EINA_ARRAY_ITER_NEXT(smart->paths, i, path, iterator)
	{
		evas_object_move(path, ta->ox, ta->oy);
		evas_object_show(path);
	}
	
	xmin = ta->ox / tile_size + smart->li->min_x - 1; 
	ymin = ta->oy / tile_size + smart->li->min_y - 1;	
	xoffset = -ta->ox % tile_size;
	yoffset = -ta->oy % tile_size;
	for(ty = 0; ty < ta->th; ty++)
	{
		Evas_Coord y0;
		y0 = (ty - 1) * tile_size;
		for(tx = 0; tx < ta->tw; tx++)
		{
			Evas_Coord x0;
			struct osm_data *osm;
			Evas_Object *o;

			x0 = (tx - 1) * tile_size;
			o = ta->tiles[ty * ta->tw + tx];
			if(o == NULL)
				return -1;
	
			if(xmin + tx < smart->li->min_x || xmin + tx > smart->li->max_x || 
				ymin + ty < smart->li->min_y || ymin + ty > smart->li->max_y)
			{
				osm = e_smart_tile_unload(o);
				overlay_unload(smart, osm);
			}
			else
			{
				osm = e_smart_tile_needs_update(o, 
					smart->current_level, xmin + tx, ymin + ty);
				if(osm != NULL)
					overlay_unload(smart, osm);
				
				osm = e_smart_tile_load(o, smart->mi->path, 
					smart->current_level, xmin + tx, ymin + ty); 
				if(osm == NULL)
					continue;
			}
			evas_object_move(o, smart->x + xoffset + x0, smart->y + yoffset + y0);
			evas_object_resize(o, tile_size, tile_size);
			evas_object_show(o);
			overlay_update(smart, osm, smart->x + xoffset + x0, smart->y + yoffset + y0);
		}
	}
	return 0;
}

int map_object_update(struct smart_map *smart)
{
	int tw, th;
	int ret, ts = smart->mi->tile_size;
	char buffer[512];
	
	tw = 2 + (((double)smart->w + ts) / ts);
	th = 2 + (((double)smart->h + ts) / ts);
	if(tw != smart->ta.tw || th != smart->ta.th)
	{
		if(tile_array_resize(&smart->ta, smart, tw, th) < 0)
			return -1;
	}
	ret = fill_tiles(smart);
	if(ret < 0)
		return -1;

	if(smart->theme == NULL)
		return 0;

	snprintf(buffer, 512, "%lf * %lf", smart->ta.lat, smart->ta.lon);
	smart->lat = smart->ta.lat;
	smart->lon = smart->ta.lon;
	edje_object_part_text_set(smart->theme, "position", buffer);
	return 0; 
}