﻿/// <reference path="jquery/jquery-1.3.2-vsdoc2.js"/>

Cufon.replace('#main h1, #main .prefix', { fontFamily: 'Trade Gothic LT Std Light', hover: true });
Cufon.replace('.cufon p:not(.author), .cufon ul, .contact, p.cufon', { fontFamily: 'Trade Gothic LT Std', hover: true });

document.createElement("abbr");

$(document).ready(function ()
{
	//$('#page').removeClass('no-js');
	$('#page').removeAttr('class');

	$(document).externalLinks();

	$('.labeltovalue').labelToValue();

	// googlemaps
	$('img[src^="http://maps.google.com/maps/api/staticmap"]').each(function ()
	{
		var markers = [];
		var marker;

		$.each($(this).attr('src').match(/markers=(icon:([^|]*))?.*?(\|[0-9.,-]{3,})/g)/*.split(/^.*?&markers=|&markers=|&.*$/)*/, function (i, item)
		{
			marker = item.match(/icon:([^|]*).*?label:([^|]*).*?\|([0-9.-]{3,}),([0-9.-]{3,})/);

			markers.push({
				"icon": ((new Date()).getMonth() == 6 && (new Date()).getDate() == 25) || location.hash == '#doughboy' ? 'http://ayomedia.co.uk/_assets/images/icon_doughboy.png' : unescape(marker[1]),
				"title": unescape(marker[2]),
				"lat": marker[3],
				"lng": marker[4]
			});
		});

		$('#feature .content').googlemap({ "markers": markers });

		marker = undefined;
	});

	// postback page location
	var ypos = get_cookie(document.location.pathname + 'ypos');

	if (ypos > 0)
	{
		$(document).scrollTop(ypos);

		del_cookie(document.location.pathname + 'ypos');
	}

	$('input.enquiry').click(function (e)
	{
		set_cookie(document.location.pathname + 'ypos', $(document).scrollTop(), 0.0166666666666667); // 1 min
	});

	// Slideshow
	$('.slideshow').each(function (i)
	{
		var slideshow = $(this).fadeTo(0, 1);
		var slides = slideshow.find('dt');

		slides.find('img').wrap('<span class="tile" />');

		slides.each(function (i)
		{
			$(this).css({ position: 'absolute', top: 0, left: 0, zIndex: 50 - i }).data('zIndex', 50 - i);
			var title = $(this).next('dd').css({ position: 'absolute', bottom: '15px', left: 0, zIndex: 101 }).fadeTo(0, 1);

			if (i > 0)
			{
				title.animate({ width: 'toggle' }, 0);
			}

			var tile = $(this).find('.tile');
			var img = tile.find('img');

			tile.css({ backgroundImage: 'url(' + img.attr('src') + ')' });

			img.remove();

			for (var i = 1; i < 15; i++)
			{
				tile = tile.fadeTo(0, 1).clone().css({ backgroundPosition: -(/*tile.width()*/142 * (i % 5)) + 'px ' + -(/*tile.height()*/124 * Math.floor(i / 5)) + 'px' }).insertAfter(tile);
			}

			$(this).bigLink($(this).next('dd').find('a'));
			$(this).find('a').attr('href', $(this).next('dd').find('a').attr('href'));
		})
		.eq(0).addClass('current');

		slides.find('a').click(function (e)
		{
			e.preventDefault();
		});


		function next(curr)
		{
			if (window.slideshowTimeout) return;

			curr.next('dd:visible').animate({ width: 'toggle' }, 200);

			var next = curr.nextAll('dt:eq(0)');

			if (!next.length)
			{
				next = curr.siblings('dt:eq(0)');
			}

			var tiles = next.find('.tile').fadeTo(0, 0);

			next.css({ zIndex: 100 }).addClass('current').siblings('.current').removeClass('current');

			tiles.randomise();

			doTransition();

			function doTransition()
			{
				tiles = tiles.not(tiles.slice(0, 1).fadeTo(300, 1));

				if (tiles.length)
				{
					window.slideshowTimeout = setTimeout(doTransition, 20);
				}
				else
				{
					window.slideshowTimeout = setTimeout(function ()
					{
						next.next('dd').animate({ width: 'toggle' }, 200);

						next.siblings('dt').each(function (i)
						{
							$(this).css({ zIndex: $(this).data('zIndex') });
						}).end().css({ zIndex: 99 });

						window.slideshowTimeout = null;
					}, 280);
				}
			};
		};

		window.slideshowInterval = setInterval(function ()
		{
			if (!window.slideshowPaused)
			{
				next(slideshow.find('dt.current'));
			}

		}, 4000)
	});

	if ($.browser.msie && $.browser.version < 7)
	{
		$('#page').addClass('no-js');

		return;
	}

	// Tabs
	$('.tab-set').each(function (i)
	{
		var tabset = $(this).css({ position: 'relative' });
		var tablist = $('<ul class="tab-list"/>');
		var height = 0;

		var panels = $(this).find('.tab-panel').each(function (i)
		{
			var panel = $(this);
			var tab = panel.find('h2');

			if (tab.hasClass('current'))
			{
				panel.addClass('current');
				tab.removeClass('current');
				var current = true;
			}

			tab.find('a').click(function (e)
			{
				var value = $(this).attr('href').replace(/^.*?#/, '');

				$.address.value(value);

				e.preventDefault();

				if (panel.hasClass('current'))
				{
					panel.removeClass('current').fadeOut(300);

					$(this).parents('li').removeClass('current');
				}
				else
				{
					panel.siblings('.current').fadeOut(300).removeClass('current');
					panel.addClass('current').fadeIn(300);

					$(this).parents('li').addClass('current').siblings('.current').removeClass('current');
				}
			});

			tablist.append($('<li' + (current ? ' class="current" ' : ' ') + '/>').append(tab));

			height = Math.max(height, panel.height());

			panel.width(panel.width()).not('.current').hide();

		});

		tablist.insertBefore(tabset.parents('.columns-2'));
		tabset.height(height);
		panels.css({ position: 'absolute', top: '0px' });
	});

	// Services Navigation filtering
	$('#feature .content.hidden').fadeTo(0, 0).css({ display: 'block' });

	if ($.browser.msie)
	{
		$('#feature .content.hidden .slideshow dt').fadeTo(0, 0);
	}
	/*$('#feature .content.hidden').removeClass('hidden');*/

	$('#service-navigation li a').click(function (e)
	{
		e.preventDefault();

		/* Disabled due to bug with clients page grid
		var value = $(this).attr('href').replace(/^.*?\/?services\//, '');
		if (value == '' || value == './') value = $('#service-navigation li a').eq(0).text().urlFriendly();

		$.address.value('services/' + value);
		*/

		clearTimeout(window.gridTimeout);

		if ($(this).parents('li').hasClass('current'))
		{
			$(this).parents('li').removeClass('current');

			if ($.browser.msie && ($('#feature .slideshow').length || $('#feature .googlemap').length))
			{
				$('#feature .slideshow dt.current, #feature .slideshow dt.current + dd, #feature .googlemap').stop().fadeTo(800, 1, function ()
				{
					this.style.removeAttribute('filter');
					$('.googlemap #lmc3d').show();

					$('#feature .slideshow dt:not(.current), #feature .slideshow dt:not(.current) + dd').stop().fadeTo(0, 1);
				});
			}
			else
			{
				$('#feature .content').stop().fadeTo(800, 1);
			}

			//window.slideshowPaused = false;

			var fadeto = 0;

			var service = 'null';
		}
		else
		{
			$(this).parents('li').addClass('current').siblings().removeClass('current');

			if ($.browser.msie && ($('#feature .slideshow').length || $('#feature .googlemap').length))
			{
				$('.googlemap #lmc3d').hide();

				$('#feature .slideshow dt:not(.current), #feature .slideshow dt:not(.current) + dd').stop().fadeTo(0, 0);
				$('#feature .slideshow dt.current, #feature .slideshow dt.current + dd, #feature .googlemap').stop().fadeTo(800, 0);
			}
			else
			{
				$('#feature .content').stop().fadeTo(800, 0);
			}

			//window.slideshowPaused = true;

			var fadeto = .1;

			var service = $(this).text().urlFriendly();
		}

		var tiles = $('#main .grid-list li').stop().show();

		var toFade = tiles.filter('li:not(.' + service + ')');
		var toShow = tiles.filter('li.' + service);
		var toHide = [];

		toFade.randomise();
		toShow.randomise();

		doTransition();

		function pushToHide()
		{
			if (fadeto == 0)
			{
				toHide.push($(this));

				if (toHide.length == tiles.length)
				{
					$.each(toHide, function (i)
					{
						$(this).hide();
					});
				}
			}
		};

		function doTransition()
		{
			toFade = toFade.not(toFade.slice(0, 1).fadeTo(300, fadeto, pushToHide));
			toShow = toShow.not(toShow.slice(0, 1).fadeTo(300, 1));

			if (toFade.length || toShow.length)
			{
				window.gridTimeout = setTimeout(doTransition, 20);
			}
		};
	});

	var clientgrid = $('.grid-list');

	if (!clientgrid.length)
	{
		$('#feature').append($('<ul class="grid-list" />').load("/clients/ajax.aspx ul.grid-list > *"/*, (new Date()).getTime().toString()*/, function (responseText, textStatus, XMLHttpRequest)
		{
			if (XMLHttpRequest.status == 200)
			{
				init($(this));
			}
		}));
	}
	else
	{
		init(clientgrid);
	}

	function init(clientgrid)
	{
		if ($.browser.msie)
		{
			clientgrid.find('img').css('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader()');
		}

		clientgrid.find('li').removeClass('selected').removeClass('visible').addClass($('#service-navigation li.alpha').text().urlFriendly())
		.not('.visible').fadeTo(0, 0); // fix for jQuery not being able to read filters set in CSS (in IE)

		clientgrid.parent('#feature').height(clientgrid.find('li').height() * Math.ceil(clientgrid.find('li').length / 5));

		$('#service-navigation li.current').removeClass('current').find('a').click();
	};

	// Primary Navigation sliding markers
	$('#primary-navigation li:not(.current) a')
	.find('span')
	.append($('<span class="marker" />'))
	.end()
	.click(function (e)
	{
		$(this).parents('li').addClass('current').siblings().removeClass('current');
	})
	.mouseover(function (e)
	{
		$(this).find('span.marker')
		.stop()
		.animate({
			height: '30px'
		}, 100);

		$(this).stop().animate({ color: '#00AEEF' }, 100);
	})
	.mouseout(function (e)
	{
		$(this).find('span.marker')
		.stop()
		.animate({
			height: '0px'
		}, 100);

		$(this).stop().animate({ color: '#FFFFFF' }, 100);
	})
	.focus(function (e) { $(this).mouseover() })
	.blur(function (e) { $(this).mouseout() });


	// Deeplinking
	$.address.externalChange(function (event)
	{
		var value = event.value.replace(/^\/|\/$/g, '');

		if (value != '')
		{
			var items = /^services\//.test(value) ? $('#service-navigation li a') : $('.tab-list li a');
			var value = value.replace(/^services\//, '');

			items.each(function (i)
			{
				//console.log($(this).text().urlFriendly() + ' == ' + value)

				if ($(this).text().urlFriendly() == value)
				{
					$(this).click();
				}
			});
		}
	});
});

$.fn.delay = function(time, callback)
{
    jQuery.fx.step.delay = function() { };
    // Return meaningless animation, (will be added to queue)
    return this.animate({ delay: 1 }, time, callback);
};

$.assetsRoot = function()
{
    var scr = $('script[src*="/global.js"]');
    return (scr.length) ? scr.attr('src').replace(/\/js\/global\.js.*?$/gi, '') : '';
}

$.fn.externalLinks = function()
{
    return this.find('a[href^=http]:not([href*=' + location.hostname + ']), a:[rel=external]').attr('target', '_blank')/*.append('<em class="ext"> [this link opens in a new window] </em>')*/.end();
};

$.fn.bigLink = function(/**String*/selector)
{
    var self = this;
    var selector = selector || 'a[@href]:eq(0)';

    this.click(function(e)
    {
        var link = typeof selector == 'object' ? selector : $(this).find(selector);

        // the first link within the supplied element
        var prevent_default = false;

        // var target_is_link = (e.target.nodeName == 'A');

        // check through all click events for preventDefault command (so we know whether to redirect or not)
        var all_events = link.data('events');
        var click_events;

        if (all_events && all_events.click)
        {
            click_events = all_events.click;

            for (var k in click_events)
            {
                if (/\.preventDefault\(\)/.test(click_events[k].toString()))
                {
                    prevent_default = true;
                }
            }
        }

        // trigger all jquery assigned events
        link.triggerHandler('click');

        // if preventDefault has never been assigned to this link then it is safe to do a standard redirect
        if (!prevent_default)
        {
            //document.location = link.attr('href');
            return !window.open(link.attr('href'), link.attr('target') || '_self');
        }
    })
	.hover(function()
	{
	    $(this).addClass('hover');
	},
	function()
	{
	    $(this).removeClass('hover');
	})
	.css('cursor', 'pointer');

    return self;
}

$.fn.labelToValue = function()
{
    var self = this;

    self.focus(function()
    {
        var field = $(this);

        if (this.id)
        {
            var label = $.trim($('label[for="' + this.id + '"]:last').hide().text());
        }
        else
        {
            return;
        }

        if (field.val() == label)
        {
            field
			.val('')
			.removeClass('label');
        }
        else
        {
            field
			.removeClass('label');
        }
    })
	.blur(function()
	{
	    var field = $(this);

	    if (this.id)
	    {
	        var label = $.trim($('label[for="' + this.id + '"]:last').hide().text());
	    }
	    else
	    {
	        return;
	    }

	    if (field.val() == label || field.val() == '')
	    {
	        field
			.val(label)
			.addClass('label');
	    }
	})
	.blur()
	.parents('form').submit(function(e)
	{
	    var current = $(':focus');
	    var scrollY = $(document).scrollTop();

	    // trigger the focus event to remove label text from field
	    self.focus();
	    // remove all bound events
	    self.unbind();

	    current.get(0).focus();

	    $(document).scrollTop(scrollY);
	});

    return self;
}

/*
$(this).next().fadeSlideToggle({ speed:300, easing:"swing" });
*/
$.fn.fadeSlideToggle = function(settings)
{
	var self = $(this);
	var settings = $.extend({ speed: 500, easing: "swing", callback: function() { } }, settings);

	if (self.css("display") == "none")
	{
		self.animate({
			opacity: 1,
			height: 'toggle'
		}, settings.speed, settings.easing, settings.callback);
	}
	else
	{
		self.animate({
			opacity: 0,
			height: 'toggle'
		}, settings.speed, settings.easing, settings.callback);
	}

	return self;
};



/*
* jQuery Color Animations
* Copyright 2007 John Resig
* Released under the MIT and GPL licenses.
*/

(function(jQuery)
{
	// We override the animation for all of these color styles
	jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i, attr)
	{
		jQuery.fx.step[attr] = function(fx)
		{
			if (fx.state == 0)
			{
				fx.start = getColor(fx.elem, attr);
				fx.end = getRGB(fx.end);
			}
			try
			{
				fx.elem.style[attr] = "rgb(" + [
					Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
					Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
					Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
				].join(",") + ")";
			}
			catch (e) { }
		}
	});

	// Color Conversion functions from highlightFade
	// By Blair Mitchelmore
	// http://jquery.offput.ca/highlightFade/

	// Parse strings looking for color tuples [255,255,255]
	function getRGB(color)
	{
		var result;

		// Check if we're already dealing with an array of colors
		if (color && color.constructor == Array && color.length == 3)
			return color;

		// Look for rgb(num,num,num)
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
			return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];

		// Look for rgb(num%,num%,num%)
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
			return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];

		// Look for #a0b1c2
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
			return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];

		// Look for #fff
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
			return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];

		// Otherwise, we're most likely dealing with a named color
		return colors[jQuery.trim(color).toLowerCase()];
	}

	function getColor(elem, attr)
	{
		var color;

		do
		{
			color = jQuery.curCSS(elem, attr);

			// Keep going until we find an element that has color, or we hit the body
			if (color != '' && color != 'transparent' || jQuery.nodeName(elem, "body"))
				break;

			attr = "backgroundColor";
		} while (elem = elem.parentNode);

		return getRGB(color);
	};
})(jQuery);

jQuery.fn.randomise = function()
{
	return this.pushStack(jQuery.makeArray([].fisherYates.apply(this, arguments)));
};

String.prototype.removeAccent = function()
{
	var from = "ÀÁÄÂÈÉËÊÌÍÏÎÒÓÖÔÙÚÜÛàáäâèéëêìíïîòóöôùúüûÑñÇçßØø".split('');
	from.push("æ", "Æ", "œ", "Œ");

	var to = "AAAAEEEEIIIIOOOOUUUUaaaaeeeeiiiioooouuuuNnCcBOo".split('');
	to.push("ae", "AE", "oe", "OE");

	var str = this;

	for (var i = 0, l = from.length; i < l; i++)
	{
		str = str.replace(new RegExp(from[i], "g"), to[i]);
	}

	return str;
};

String.prototype.removeDiacritics = function()
{
	var diacritics = [
        [/[\300-\306]/g, 'A'],
        [/[\340-\346]/g, 'a'],
        [/[\310-\313]/g, 'E'],
        [/[\350-\353]/g, 'e'],
        [/[\314-\317]/g, 'I'],
        [/[\354-\357]/g, 'i'],
        [/[\322-\330]/g, 'O'],
        [/[\362-\370]/g, 'o'],
        [/[\331-\334]/g, 'U'],
        [/[\371-\374]/g, 'u'],
        [/[\321]/g, 'N'],
        [/[\361]/g, 'n'],
        [/[\307]/g, 'C'],
        [/[\347]/g, 'c']
    ];

	var str = this;

	for (var i = 0, l = diacritics.length; i < l; i++)
	{
		str = str.replace(diacritics[i][0], diacritics[i][1]);
	}

	return str;
};


String.prototype.urlFriendly = function()
{
	var str = this.removeAccent().toLowerCase();

	str = str.replace(/[^a-z0-9\s-]/g, ""); // remove invalid chars
	str = str.replace(/[\s-]+/g, "-"); // convert spaces and hyphens into one hyphen
	str = str.replace(/^(\s+|-+)|(\s+|-+)$/g, ""); // trim any unecessary spaces or hyphens

	return str;
};

Array.prototype.fisherYates = function()
{
	var i = this.length;
	if (i == 0) return false;

	while (--i)
	{
		var j = Math.floor(Math.random() * (i + 1));
		var tempi = this[i];
		var tempj = this[j];
		this[i] = tempj;
		this[j] = tempi;
	}
};

/**
Global Helper function for setting cookies.
	
@param name Name of the cookie
@param value Value to store in the cookie
@param [days] Number of days to keep cookie
*/
function set_cookie(/**String*/name, /**String*/value, /**Number*/days) {
    if (days) {
        var date = new Date();

        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));

        var expires = "; expires=" + date.toGMTString();
    }
    else {
        var expires = "";
    }

    document.cookie = name + "=" + escape(value) + expires + "; path=/";
};

/**
Global Helper function for retrieving cookies.
*/
function get_cookie(/**String*/name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');

    for (var i = 0, l = ca.length; i < l; i++) {
        var c = ca[i];

        while (c.charAt(0) == ' ') {
            c = c.substring(1, c.length);
        }

        if (c.indexOf(nameEQ) == 0) {
            return unescape(c.substring(nameEQ.length, c.length));
        }
    }

    return null;
};

/**
Global Helper function for deleting cookies.
*/
function del_cookie(/**String*/name) {
    set_cookie(name, "", -1);
};


// google maps
$.fn.googlemap = function (options)
{
	options = $.extend(true, {
		'zoom': '10',
		'minZoom': null,
		'maxZoom': null,
		'disableDefaultUI': null,
		'disableDoubleClickZoom': null,
		'draggable': null,
		'zoomControl': null,
		'panControl': null,
		'scaleControl': null,
		'scrollwheel': null,
		'streetViewControl': null,
		'mapTypeControl': null,
		'backgroundColor': null,
		'type': 'ROADMAP',
		'center': {
			'lat': null,
			'lng': null
		}
	}, options);

	return this.each(function (i)
	{
		var cbName = 'mapsapi_callback_' + (new Date()).getTime() + '_' + i;
		var canvas = this;
		var markers = [];
		var bounds;
		var map;

		$(canvas).bind('toggleMarkers', function(e, type)
		{
			for (var i = 0, l = markers.length; i < l; i++)
			{
				if(markers[i].type == type)
				{
					markers[i].pin.setVisible(!markers[i].pin.getVisible());
				}
			}
		});

		// set up maps api callback
		window[cbName] = function ()
		{
			init(canvas);

			// clean up
			window[cbName] = undefined;
			delete window[cbName];
			cbName = undefined;
			canvas = undefined;
		}
		// load google maps api js
		$.getScript('http://maps.google.com/maps/api/js?callback=' + cbName + '&sensor=false');

		function init(canvas)
		{
			map = new google.maps.Map(canvas, {
				mapTypeId: google.maps.MapTypeId[options.type.toUpperCase()],
				center: new google.maps.LatLng(options.center.lat, options.center.lng),
				zoom: parseInt(options.zoom),
				maxZoom: parseInt(options.maxZoom),
				minZoom: parseInt(options.minZoom),
				disableDefaultUI: parseBool(options.disableDefaultUI),
				disableDoubleClickZoom: parseBool(options.disableDoubleClickZoom),
				draggable: parseBool(options.draggable),
				zoomControl: parseBool(options.zoomControl),
				panControl: parseBool(options.panControl),
				scaleControl: parseBool(options.scaleControl),
				scrollwheel: parseBool(options.scrollwheel),
				streetViewControl: parseBool(options.streetViewControl),
				mapTypeControl: parseBool(options.mapTypeControl),
				backgroundColor: options.backgroundColor
			});

			bounds = new google.maps.LatLngBounds();

			if (options.markers)
			{
				$.each(options.markers, function (i)
				{
					if (this.lat && this.lng)
					{
						addMarker(this);
					}
					else if (this.postcode)
					{
						doLookup(this, addMarker);
					}
				});
			}
		}

		// postcode lookup
		function doLookup(marker, callback)
		{
			$.ajax({
				url: 'http://ajax.googleapis.com/ajax/services/search/local',
				data: { v: '1.0', q: marker.postcode, gl: 'uk' },
				dataType: 'jsonp',
				context: marker,
				success: function(data)
				{
					if (data.responseStatus == 200 && data.responseData.results[0])
					{
						this.lat = data.responseData.results[0].lat;
						this.lng = data.responseData.results[0].lng;

						addMarker(this);
					}
				}
			});
		}

		// add marker
		function addMarker(marker)
		{
			// create a LatLng object
			var latLng = new google.maps.LatLng(marker.lat, marker.lng);

			// add the marker to the map
			var pin = new google.maps.Marker({
				//icon: new google.maps.MarkerImage(marker.icon),
				title: marker.title || '',
				position: latLng,
				map: map
			});

			if(marker.icon)
			{
				pin.setIcon(new google.maps.MarkerImage(marker.icon));
				pin.setShadow(new google.maps.MarkerImage(marker.icon.replace(/(\.png)$/, "_shadow$1")));

				markers.push({ pin: pin, type: marker.icon });
			}

			// if the marker has a url property then attach a click handler
			if (marker.url)
			{
				pin.setCursor('pointer');

				google.maps.event.addListener(pin, 'click', function ()
				{
					document.location = marker.url;
				});
			}

			// extend the bounds object
			bounds.extend(latLng);

			// re-center and zoom the map to show all pins
			map.setCenter(bounds.getCenter());
			map.fitBounds(bounds);
		}
	});

	// utility function to parse a string into a boolean
	function parseBool(str)
	{
		return (str == null || str == 'null') ? null : (str.toLowerCase() != 'false' && str != '' && parseInt(str) != 0);
	}
}
