var Plazes = 
{
	// Configs
	imageBase				: 'common/img/',
	requestBase				: 'app/',
	DEFAULT_MAP_HEIGHT 		: 255,
	animateResize			: true,
	refreshFriendsEvery		: 5, // seconds
	
	// Properties
	resizeInterval	: null,
	resizeLoop		: false,
	debugMsg		: '',
	icons			: {},
	ranges			: {},
	flags			: [],
	people			: 
	{
		friends		: [], 
		fofriends	: [], 
		everyone	: []
	},
	places			: 
	{
		favorites	: [], 
		busiest		: [], 
		newest		: []
	},
	range			: null,
	map				: null,
	point			: null,
	me				: null,
	current			: null,
	
	// methods
	initMap	: function(map, point)
	{
		// The center of our GMap
		this.point 	= point;
		
		// Create flag GIcons
		this.icons =
		{
			plaze 		: new PIcon('plaze'),
			plazeFav	: new PIcon('plaze_fav'),
			friend		: new PIcon('friend'),
			friendFav	: new PIcon('friend_fav'),
			me			: new PIcon('me')
		};
		
		// Create ranges
		/*
		Range	Zoom Level	px		km		km in 710px		km in 255px
		---------------------------------------------------------------
		You		0			106		0.1		0.67			0.25
		-x-		1			106		0.2		1.34			0.5
		1km		2			52		0.2		2.73			1.0
		2km		3			66		0.5		5.39			1.93
		5km		4			66		1.0		10.78			3.86
		10km	5			66		2.0		21.56			7.72
		-x-		6			83		5.0		42.77			15.36
		*/
		this.ranges	=
		{
			'you'		: new PRange(this.point, 'you', 1, 0, this.DEFAULT_MAP_HEIGHT),
			'1km'		: new PRange(this.point, '1km', 710, 2, 550),
			'2km'		: new PRange(this.point, '2km', 710, 3, 550),
			'5km'		: new PRange(this.point, '10km', 710, 4, 680),
			'10km'		: new PRange(this.point, '10km', 710, 5, 680)
		};
		this.range = this.ranges['you'];
		
		// Load our map
		this.map = new GMap($(map));
		this.map.centerAndZoom(point, 0);
		this.map.disableDragging();
	},
	
	initFriends	: function(list)
	{	
		if (SI.Request)
		{
			var seconds = this.refreshFriendsEvery * 1000;
			this.refreshCount = 1;
			window.setInterval
			(
				function()
				{
					if (Plazes.refreshCount >= 5)
					{
						Plazes.refreshCount = 0;
					}
					SI.Request.get(Plazes.requestBase + 'friends.php?refreshed=' + (Plazes.refreshCount++), $(list));
				},
				seconds + 1
			);
		};
	},
	
	debug		: function()
	{
		GEvent.addListener(this.map, "click", function(overlay, point)
		{
			if (point)
			{
				Plazes.map.clearOverlays();
				var marker = new GMarker(point);
				Plazes.map.addOverlay(marker);
				Plazes.debugMsg += '$flags[] = "new PFlag(new GPoint(' + point.x + ', ' + point.y + '), ' + "'type', 'Who')" + '";\r';
			}
		});
		document.write('<a href="#" onclick="alert(Plazes.debugMsg); Plazes.debugMsg = \'\'; return false">Debug Message</a>');
	},
	
	addFlag	: function(flag)
	{
		this.map.removeOverlay(flag);
		this.map.addOverlay(flag);
		flag.setZIndex(1);
		this.flags.push(flag);
	},
	
	removeFlag	: function(flag)
	{
		this.map.removeOverlay(flag);
		this.flags = this.flags.without(flag);
	},
	
	// addFlags and removeFlags accept one or more 
	// PFlags and/or one or more arrays of PFlags
	addFlags : function()
	{
		this.addRemoveFlags('add', arguments);
	},
	
	removeFlags : function()
	{
		this.addRemoveFlags('remove', arguments);
	},
	
	addRemoveFlags	: function(action, flags)
	{
		for (var i = 0; i < flags.length; i++)
		{	
			flag = flags[i];
			if (flag.constructor == Array)
			{
				for (var j = 0; j < flag.length; j++)
				this[action + 'Flag'](flag[j]);
			}
			else
			{
				this[action + 'Flag'](flag);
			};
		};
	},
	
	clearMap	: function()
	{
		this.map.clearOverlays();
		this.flags = [];
	},
	
	changeRange	: function(range)
	{
		if (this.range == this.ranges[range]) return;
		
		this.range = this.ranges[range];
		this.map.zoomTo(this.range.zoom);
		this.resizeMap(this.range.size);
		
		this.clearMap();
		this.map.addOverlay(this.range.marker);
		this.range.marker.setZIndex(0);
		
		var theRanges = 
		{
			'you' 	: $('rangeYou'),
			'1km' 	: $('range1km'),
			'2km' 	: $('range2km'),
			'5km' 	: $('range5km'),
			'10km' 	: $('range10km')
		};
		
		var selected = false;
		for (aRange in theRanges)
		{
			if (aRange == range)
			{
				theRanges[range].className = 'selected';
				selected = true;
			}
			else
			{
				theRanges[aRange].className = (!selected) ? 'withinSelected' : '';
			};
		};
		
		var showMeForm = $('showMeForm');
		var inputs = showMeForm.getElementsByTagName('input');
		for (var i = 0; i < inputs.length; i++)
		{
			var input = inputs[i];
			if (input.type == 'checkbox')
			{
				this.showMe(input);
			};
		}
		this.addFlag(this.me);
	},
	
	resizeMap	: function(targetHeight)
	{
		if (!this.animateResize)
		{
			// Resize without animation
			this.map.container.style.height = targetHeight + 'px';
			this.map.onResize();
			this.map.centerAtLatLng(this.point);
		}
		else
		{
			// Resize with animation
			if (this.resizeLoop)
			{
				var currentHeight = this.map.container.offsetHeight - 2;
				var updatedHeight = currentHeight + (targetHeight - currentHeight)/2;
				
				if (Math.abs(currentHeight - targetHeight) <= 1)
				{
					this.map.container.style.height = targetHeight + 'px';
					clearInterval(this.resizeInterval);
					this.resizeLoop 	= false;
					this.resizeInterval	= null;
				}
				else
				{
					this.map.container.style.height = updatedHeight + 'px';
				};
				this.map.onResize();
				this.map.centerAtLatLng(this.point);
			}
			else
			{
				this.resizeInterval = setInterval('Plazes.resizeMap(' + targetHeight + ')', 100);
				this.resizeLoop = true;
			};
		};
	},
	
	showMe	: function(input)
	{
		var type	= input.name;
		var which	= input.value;
		var show	= input.checked;
		
		if (show)
		{
			var request = GXmlHttp.create();
			request.open("GET", this.requestBase + 'flags.php?ll=' + this.point.x + ',' + this.point.y + '&type=' + type + '&which=' + which + '&range=' + this.range.zoom, true);
			request.onreadystatechange = function() 
			{
				if (request.readyState == 4)
				{
					Plazes[type][which] = eval(request.responseText);
					Plazes.addFlags(Plazes[type][which]);
				}
			}
			request.send(null);
		}
		else
		{
			this.removeFlags(this[type][which]);
		};
	}
};

function PIcon(name)
{
	var imagePre = Plazes.imageBase + 'icon_flag_';
	var imageExt = '.png';
	
	// Preload each image
	var image = new Image();	image.src = imagePre + name + imageExt;
	var shadow = new Image();	shadow.src = imagePre + 'shadow' + imageExt;
	
	var icon	= new GIcon();
	icon.image	= image.src;
	icon.shadow	= shadow.src;
	
	icon.iconSize	= new GSize(31, 29);
	icon.shadowSize	= new GSize(44, 29);
	icon.iconAnchor	= new GPoint(0, 29);

	icon.infoWindowAnchor = new GPoint(31, 0);
	
	return icon;
};

function PFlag(point, icon, html)
{
	var point	= point;
	var flag	= Plazes.icons[icon];
	
	var marker = new GMarker(point, flag);
	
	if (html != '')
	{
		GEvent.addListener(marker, 'click', function() 
		{
			marker.openInfoWindowHtml(html);
		});
	};
	
	return marker;
};

function PRange(point, name, size, zoom, mapHeight)
{
	var imagePre = Plazes.imageBase + 'range_';
	var imageExt = '.png';
	
	// Preload each image
	var image = new Image();	image.src = imagePre + name + imageExt;
	
	var range		= new GIcon();
	range.image		= image.src;
	range.iconSize	= new GSize(size, size);
	range.iconAnchor	= new GPoint(size/2, size/2);
	
	this.name	= name;
	this.marker	= new GMarker(point, range);
	this.zoom	= zoom;
	this.size	= mapHeight;
};

Array.prototype.without = function(element)
{
	var newArray = [];
	for (var i = 0; i < this.length; i++)
	{
		if (this[i] != element)
		{
			newArray.push(this[i]);
		};
	};
	return newArray;
};

var $ = function(e)
{
	return document.getElementById(e);
};