// bgGoogle.js 10 | requires jquery.js 1.6.2+ | made by Kyle Weems of Mindfly Web Studio (http://mindfly.com/)
// Created Aug 18, 2009 | Last Modified :  Dec 01, 2011

if (!bg) var bg = {};

bg.Google = {
    version: "bg.Google Extension - v10 (requires jquery.js 1.6.2+)",
    map: {
		vars: {
			data: null,
			directions: null,
			marker_collection: [],
			mapName: null,
			mapCallback: null,
			mapElem: null,
			z: null
		},
		request: {
			call: function (request_string, callback) {
				// Called by bg.Google.map.load to create a connection with Google Maps API
				request_string += "&callback=bg.Google.map.request.process";
				$.getScript(request_string, function () { });
			},
			process: function (data) {
				// After a connection is established with bg.Google.map.request.call, this is called to create an instance of a Google map on the page.
				var ll = new google.maps.LatLng(0, 0);
				var domElem = $(bg.Google.map.vars.mapElem).get(0);
				var myOptions = { zoom: bg.Google.map.vars.z, center: ll, mapTypeId: google.maps.MapTypeId.ROADMAP };
				bg.Google.map.vars.data = new google.maps.Map(domElem, myOptions);
				if (bg.Google.map.vars.mapCallback != null) {
					google.maps.event.addListener(bg.Google.map.vars.data, 'tilesloaded', function () {
						bg.Google.map.vars.mapCallback();
						google.maps.event.clearListeners(bg.Google.map.vars.data, "tilesloaded");
					})
				}
			}
        },
        load: function (elem, properties, callback) {
			// Required before any other bg.Google.map function can be used.
			// "elem" is the CSS selector for the element on the page where the Google Map will be loaded.
			// "properties" is an optional object filled with properties for the page load, such as:
			// - "center" can be given a location (vcard, geo, address or latlng) that the map is centered on when loaded.
			// - "zoom" can be given a number for the zoom factor the map will be initiated at.
			// - "marker" if set to true will create a marker will result in a standard marker being placed at the map's initial coordinates.
            if (!!callback) bg.Google.map.vars.mapCallback = callback;
			if ((typeof properties) == "function") {
				bg.Google.map.vars.mapCallback = properties;
			} else {
				var change_view = false;
				var new_view = {};
				if (!!properties.center) {
					new_view.center = properties.center;
					change_view = true;
				}
				if (!!properties.zoom) {
					new_view.zoom = properties.zoom;
					change_view = true;
				}
				if (change_view) {
					bg.Google.map.vars.mapCallback = function() {
						bg.Google.map.view(new_view);
						callback();
					};
				}
				if (properties.marker) {
					if (!!properties.center) {
						var cb = bg.Google.map.vars.mapCallback;
						bg.Google.map.vars.mapCallback = function() {
							bg.Google.map.marker.add(properties.center);
							cb();
						};
					}
				}
			}
            bg.Google.map.vars.mapElem = elem;
            if (bg.Google.map.vars.z == null) bg.Google.map.vars.z = 13;
            var script = "http://maps.google.com/maps/api/js?sensor=false&async=2";
            bg.Google.map.request.call(script);
        },
		marker: {
			add: function(loc, properties, callback) {
				// allowed properties: 
				// 'icon_set' for alternate marker image set
				// either 'index' for numerical index of a marker's image OR 'character' for a specific character image
				// 'onclick' for binding a function to the click event OR 'info' for an info window associated with the marker
				// 'center' if set to true centers the map on the marker when it is created
				bg.Google.map.location(loc, 'latlng', function(ll) {
					var marker_img = "http://www.google.com/mapfiles/marker";
					var animation = google.maps.Animation.DROP;
					var title = null;
					if ((typeof properties) == "function") {
						callback = properties;
					} else if (!!properties) {
						if (!!properties.icon_set) marker_img = properties.icon_set;
						if ((typeof properties.index) == "number") {
							marker_img += String.fromCharCode("A".charCodeAt(0) + properties.index);
						} else if (!!properties.character) {
							marker_img += properties.character;
						}
						if (properties.center) bg.Google.map.view({center: ll});
						if (!!properties.animation) {
							switch (properties.animation) {
								case "none":
									animation = null;
									break;
								case "bounce":
									animation = google.maps.Animation.BOUNCE;
									break;
							}
						}
						if (!!properties.title) title = properties.title;
					}
					marker_img += ".png";
					var marker = new google.maps.Marker({ map: bg.Google.map.vars.data, position: ll, icon: marker_img, title: title, animation: animation});
					if ((typeof properties) == "object") {
						if ((typeof properties.onclick) == "function") {
							google.maps.event.addListener(marker, 'click', function() { properties.onclick(); });
						}
						if (!!properties.info) {
							var infowindow = new google.maps.InfoWindow({content: properties.info});
							google.maps.event.addListener(marker, 'click', function() { infowindow.open(bg.Google.map.vars.data, marker); });
						}
					}
					marker.setMap(bg.Google.map.vars.data);
					bg.Google.map.vars.marker_collection.push(marker);
					if (!!callback) callback();
				});
			}, 
			remove: function(index) {
				// Delete the Google marker from the map that is in the marker_collection at the position of "index".
				bg.Google.map.vars.marker_collection[index].setMap(null);
				bg.Google.map.vars.marker_collection[index] = undefined;
			},
			remove_all: function() {
				// Delete all Google markers from the map.
				if (bg.Google.map.vars.marker_collection.length) {
					for (i =0; i < bg.Google.map.vars.marker_collection.length; i++) {
						if (bg.Google.map.vars.marker_collection[i] instanceof google.maps.Marker) {
							bg.Google.map.vars.marker_collection[i].setMap(null);
						}
					}
					bg.Google.map.vars.marker_collection = [];
				}
			}
		},
		location: function (loc, format, callback) {
			// Converts a location from one format to another and sends the formatted results to the callback function to process.
			// "loc" can be an address, geo, vcard or latlng
			// "format" can be "address" for a string, "geo" for the HTML of a geo microformatted element, or "latlng" for a google.maps.LatLng.
			// Converting to/from latlng and the other types requires geocoding, which has a limit of roughly 10 geocodes per instant/loop with the Google Maps API.
			var geocoder = new google.maps.Geocoder();
			if ((typeof format) == "function") {
				callback = format;
				format = "latlng";
			}
			var from_type = "address";
			switch ((typeof loc)) {
				case "string":
					// It's an address as a string.
					var from_source = loc;
					break;
				case "object":
					if (loc instanceof google.maps.LatLng) { 
						// it's a latlng
						from_type = "latlng";
						var from_source = loc;
					} else if (loc instanceof jQuery) {
						// it's a jQuery object.
						if (loc.hasClass('vcard')) {
							// it's a hcard
							from_type = "address";
							var from_source = loc.find('.street-address').text();
							from_source += ' ' + loc.find('.locality').text();
							from_source += ', ' + loc.find('.region').text();
							from_source += ' ' + loc.find('.postal-code').text();							
						} else if (loc.hasClass('geo')) {
							// it's a geo
							from_type = "latlng";
							var from_source = new google.maps.LatLng(loc.find('.latitude').text(), loc.find('.longitude').text());
						}
					} else if (loc instanceof Array) {
						// it's an array, assume a pair of coordinates
						from_type = "latlng";
						var from_source = new google.maps.LatLng(loc[0], loc[1]);
					}
					break;
			}
			switch (format) {
				case "latlng":
					if (from_type == "latlng") { 
						callback(from_source);
					} else {
						address = from_source.replace(/[\r\n]/g, " ");
						geocoder.geocode({ 'address': address }, function (results, status) {
							if (status == google.maps.GeocoderStatus.OK) {
								var ll = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
								callback(ll);
							}
						});
					}
					break;
				case "address":
					if (from_type == "address") {
						callback(from_source)
					} else {
						geocoder.geocode({ 'latLng': from_source }, function (results, status) {
							if (status == google.maps.GeocoderStatus.OK) {
								if (results[0]) {
									// returns google.maps.GeocoderResult object. You can get a plain text address with results[0].formatted_address.
									callback(results[0].formatted_address);
                                }
                            }
                        });
                    }
                    break;
                case "address_components":
                    if (from_type == "address") {
                        address = from_source.replace(/[\r\n]/g, " ");
                        geocoder.geocode({ 'address': address }, function (results, status) {
                            if (status == google.maps.GeocoderStatus.OK) {
                                var ll = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
                                geocoder.geocode({ 'latLng': ll }, function (results, status) {
                                    if (status == google.maps.GeocoderStatus.OK) {
                                        if (results[0]) {
                                            callback(results[0]);
                                        }
                                    }
                                });
                            }
                        });
                    } else {
                        geocoder.geocode({ 'latlng': from_source }, function (results, status) {
                            if (status == google.maps.GeocoderStatus.OK) {
                                if (results[0]) {
                                    callback(results[0]);
								}
							}
						});					
					}
					break;
				case "geo":
					if (from_type == "latlng") {
						callback("<span class='geo'><span class='latitude'>" + from_source.lat() + "</span>, <span class='longitude'>" + from_source.lng() + "</span></span>");
					} else {
						address = from_source.replace(/[\r\n]/g, " ");
						geocoder.geocode({ 'address': address }, function (results, status) {
							if (status == google.maps.GeocoderStatus.OK) {
								var ll = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
								callback("<span class='geo'><span class='latitude'>" + ll.lat() + "</span>, <span class='longitude'>" + ll.lng() + "</span></span>");
							}
						});					
					}
					break;
				default:
					break;
			}
		},
		view: function(properties) {
			// Alter the view of your Google map's viewport based on the properties inside the object passed to the function.
			// "center" accepts a location (latlng, geo, vcard or address) and centers the viewport to that location.
			// "zoom" accepts a number and zooms the map to that factor.
			if (!!properties.center) bg.Google.map.location(properties.center, 'latlng', function(latlng) { bg.Google.map.vars.data.setCenter(latlng); });
			if (!!properties.zoom) {
				bg.Google.map.vars.z = properties.zoom;
				bg.Google.map.vars.data.setZoom(properties.zoom);
			}
		}
    },
    plusone: {
        load: function (callback) {
            if (!callback) callback = null;
            $.getScript('https://apis.google.com/js/plusone.js', function () { callback; });
        },
        button: function (parent, href, size, counter, click_callback, load_callback) {
            if (!click_callback) click_callback = null;
            bg.Google.plusone.button_noload(parent, href, size, counter, click_callback);
            bg.Google.plusone.load(load_callback);
        },
        button_noload: function (parent, href, size, counter, callback) {
            if (!href) href = document.location.href;
            var parameters = ' href="' + href + '"';
            if (!!size) parameters += ' size="' + size + '"';
            if (!!counter) parameters += ' count="' + counter + '"';
            if (!!callback) parameters += ' callback="' + callback + '"';
            $(parent).append('<g:plusone' + parameters + '></g:plusone>');
        }
    },
    youtube: {
        request: function (request_string, callback) {
            $.ajax({ url: request_string, dataType: 'jsonp', success: function (data) { debug_v = data; if (!!callback) callback(data); } });
        },
        insert_feed: function (element, username, start_index, max_results, list_type, callback) {
            var script_string = 'https://gdata.youtube.com/feeds/api/users/' + username + '/uploads?alt=json';
            if (!start_index) start_index = 1;
            if (!list_type) list_type = "ol";
            script_string += '&start-index=' + start_index;
            if (!!max_results) script_string += '&max-results=' + max_results;
            bg.Google.youtube.request(script_string, function (data) {
                $(element).append('<' + list_type + ' class="youtube-videos"></' + list_type + '>');
                for (i = 0; i < data.feed.entry.length; i++) {
                    var id = data.feed.entry[i].id.$t.split('videos/')[1];
                    $(element + ' .youtube-videos').append('<li><object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/' + id + '?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/' + id + '?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="390"></embed></object></li>');
                    if (!!callback) callback();
                }
            });
        },
        insert_feed_thumbnails: function (element, username, start_index, max_results, list_type, callback) {
            var script_string = 'https://gdata.youtube.com/feeds/api/users/' + username + '/uploads?alt=json';
            if (!start_index) start_index = 1;
            if (!list_type) list_type = "ol";
            script_string += '&start-index=' + start_index;
            if (!!max_results) script_string += '&max-results=' + max_results;
            bg.Google.youtube.request(script_string, function (data) {
                $(element).append('<' + list_type + ' class="youtube-videos"></' + list_type + '>');
                for (i = 0; i < data.feed.entry.length; i++) {
                    var thumb = data.feed.entry[i].media$group.media$thumbnail[0].url;
                    var link = data.feed.entry[i].link[0].href.split("&")[0];
                    var title = data.feed.entry[i].title.$t;
                    $(element + ' .youtube-videos').append('<li><a href="' + link + '" title="' + title + '" target="_blank"><img src="' + thumb + '" alt="thumbnail of ' + title + '" /></a></li>');
                    if (!!callback) callback();
                }
            });
        }
    }
}


