# Source: core.js

    /**

     * @module WPGMZA

     * @summary This is the core Javascript module. Some code exists in ../core.js, the functionality there will slowly be handed over to this module.

     */

    (function($) {

    	var core = {

    		maps: [],

    		events: null,

    		settings: null,

    		loadingHTML: '<div class="wpgmza-preloader"><div class="wpgmza-loader">...</div></div>',

    		/**

    		 * @function guid

    		 * @summary Utility function returns a GUID

    		 * @static

    		 * @return {string} The GUID

    		 */

    		guid: function() { // Public Domain/MIT

    		  var d = new Date().getTime();

    			if (typeof performance !== 'undefined' && typeof performance.now === 'function'){

    				d += performance.now(); //use high-precision timer if available

    			}

    			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {

    				var r = (d + Math.random() * 16) % 16 | 0;

    				d = Math.floor(d / 16);

    				return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);

    			});

    		},

    		/**

    		 * @function hexOpacityToRGBA

    		 * @summary Takes a hex string and opacity value and converts it to Openlayers RGBA format

    		 * @param {string} colour The hex color string

    		 * @param {number} opacity The opacity from 0.0 - 1.0

    		 * @static

    		 * @return {array} RGBA where color components are 0 - 255 and opacity is 0.0 - 1.0

    		 */

    		hexOpacityToRGBA: function(colour, opacity)

    		{

    			hex = parseInt(colour.replace(/^#/, ""), 16);

    			return [

    				(hex & 0xFF0000) >> 16,

    				(hex & 0xFF00) >> 8,

    				hex & 0xFF,

    				parseFloat(opacity)

    			];

    		},

    		latLngRegexp: /^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/,

    		/**

    		 * @function isLatLngString

    		 * @summary Utility function returns true is string is a latitude and longitude

    		 * @param str {string} The string to attempt to parse as coordinates

    		 * @static

    		 * @return {array} the matched latitude and longitude or null if no match

    		 */

    		isLatLngString: function(str)

    		{

    			if(typeof str != "string")

    				return null;

    			// Remove outer brackets

    			if(str.match(/^\(.+\)$/))

    				str = str.replace(/^\(|\)$/, "");

    			var m = str.match(WPGMZA.latLngRegexp);

    			if(!m)

    				return null;

    			return {

    				lat: parseFloat(m[1]),

    				lng: parseFloat(m[3])

    			};

    		},

    		/**

    		 * @function stringToLatLng

    		 * @summary Utility function returns a latLng literal given a valid latLng string

    		 * @param str {string} The string to attempt to parse as coordinates

    		 * @static

    		 * @return {object} LatLng literal

    		 */

    		stringToLatLng: function(str)

    		{

    			var result = WPGMZA.isLatLngString(str);

    			if(!result)

    				throw new Error("Not a valid latLng");

    			return result;

    		},

    		/**

    		 * @function getImageDimensions

    		 * @summary Utility function to get the dimensions of an image, caches results for best performance

    		 * @param src {string} Image source URL

    		 * @param callback {function} Callback to recieve image dimensions

    		 * @static

    		 * @return {void}

    		 */

    		imageDimensionsCache: {},

    		getImageDimensions: function(src, callback)

    		{

    			if(WPGMZA.imageDimensionsCache[src])

    			{

    				callback(WPGMZA.imageDimensionsCache[src]);

    				return;

    			}

    			var img = document.createElement("img");

    			img.onload = function(event) {

    				var result = {

    					width: image.width,

    					height: image.height

    				};

    				WPGMZA.imageDimensionsCache[src] = result;

    				callback(result);

    			};

    			img.src = src;

    		},

    		/**

    		 * @function isDeveloperMode

    		 * @summary Returns true if developer mode is set

    		 * @static

    		 * @return {boolean} True if developer mode is on

    		 */

    		isDeveloperMode: function()

    		{

    			return this.developer_mode || (window.Cookies && window.Cookies.get("wpgmza-developer-mode"));

    		},

    		/**

    		 * @function isProVersion

    		 * @summary Returns true if the Pro add-on is active

    		 * @static

    		 * @return {boolean} True if the Pro add-on is active

    		 */

    		isProVersion: function()

    		{

    			return (this._isProVersion == "1");

    		},

    		/**

    		 * @function openMediaDialog

    		 * @summary Opens the WP media dialog and returns the result to a callback

    		 * @param {function} callback Callback to recieve the attachment ID as the first parameter and URL as the second

    		 * @static

    		 * @return {void}

    		 */

    		openMediaDialog: function(callback) {

    			// Media upload

    			var file_frame;

    			// If the media frame already exists, reopen it.

    			if ( file_frame ) {

    				// Set the post ID to what we want

    				file_frame.uploader.uploader.param( 'post_id', set_to_post_id );

    				// Open frame

    				file_frame.open();

    				return;

    			}

    			// Create the media frame.

    			file_frame = wp.media.frames.file_frame = wp.media({

    				title: 'Select a image to upload',

    				button: {

    					text: 'Use this image',

    				},

    				multiple: false	// Set to true to allow multiple files to be selected

    			});

    			// When an image is selected, run a callback.

    			file_frame.on( 'select', function() {

    				// We set multiple to false so only get one image from the uploader

    				attachment = file_frame.state().get('selection').first().toJSON();

    				callback(attachment.id, attachment.url);

    			});

    			// Finally, open the modal

    			file_frame.open();

    		},

    		/**

    		 * @function getCurrentPosition

    		 * @summary This function will get the users position, it first attempts to get

    		 * high accuracy position (mobile with GPS sensors etc.), if that fails

    		 * (desktops will time out) then it tries again without high accuracy

    		 * enabled

    		 * @static

    		 * @return {object} The users position as a LatLng literal

    		 */

    		getCurrentPosition: function(callback)

    		{

    			if(!navigator.geolocation)

    			{

    				console.warn("No geolocation available on this device");

    				return;

    			}

    			var options = {

    				enableHighAccuracy: true

    			};

    			navigator.geolocation.getCurrentPosition(function(position) {

    				callback(position);

    			},

    			function(error) {

    				options.enableHighAccuracy = false;

    				navigator.geolocation.getCurrentPosition(function(position) {

    					callback(position);

    				},

    				function(error) {

    					console.warn(error.code, error.message);

    				},

    				options);

    			},

    			options);

    		},

    		/**

    		 * @function runCatchableTask

    		 * @summary Runs a catchable task and displays a friendly error if the function throws an error

    		 * @param {function} callback The function to run

    		 * @param {HTMLElement} friendlyErrorContainer The container element to hold the error

    		 * @static

    		 * @return {void}

    		 */

    		runCatchableTask: function(callback, friendlyErrorContainer) {

    			if(WPGMZA.isDeveloperMode())

    				callback();

    			else

    				try{

    					callback();

    				}catch(e) {

    					var friendlyError = new WPGMZA.FriendlyError(e);

    					$(friendlyErrorContainer).html("");

    					$(friendlyErrorContainer).append(friendlyError.element);

    					$(friendlyErrorContainer).show();

    				}

    		},

    		/**

    		 * @function assertInstanceOf

    		 * @summary

    		 * This function is for checking inheritence has been setup correctly.

    		 * For objects that have engine and Pro specific classes, it will automatically

    		 * add the engine and pro prefix to the supplied string and if such an object

    		 * exists it will test against that name rather than the un-prefix argument

    		 * supplied.

    		 *

    		 * For example, if we are running the Pro addon with Google maps as the engine,

    		 * if you supply Marker as the instance name the function will check to see

    		 * if instance is an instance of GoogleProMarker

    		 * @param {object} instance The object to check

    		 * @param {string} instanceName The class name as a string which this object should be an instance of

    		 * @static

    		 * @return {void}

    		 */

    		assertInstanceOf: function(instance, instanceName) {

    			var engine, fullInstanceName, assert;

    			var pro = WPGMZA.isProVersion() ? "Pro" : "";

    			switch(WPGMZA.settings.engine)

    			{

    				case "google-maps":

    					engine = "Google";

    					break;

    				default:

    					engine = "OL";

    					break;

    			}

    			if(WPGMZA[engine + pro + instanceName])

    				fullInstanceName = engine + pro + instanceName;

    			else if(WPGMZA[pro + instanceName])

    				fullInstanceName = pro + instanceName;

    			else if(WPGMZA[engine + instanceName])

    				fullInstanceName = engine + instanceName;

    			else

    				fullInstanceName = instanceName;

    			assert = instance instanceof WPGMZA[fullInstanceName];

    			if(!assert)

    				throw new Error("Object must be an instance of " + fullInstanceName + " (did you call a constructor directly, rather than createInstance?)");

    		},

    		/**

    		 * @function getMapByID

    		 * @param {mixed} id The ID of the map to retrieve

    		 * @static

    		 * @return {object} The map object, or null if no such map exists

    		 */

    		getMapByID: function(id) {

    			for(var i = 0; i < WPGMZA.maps.length; i++) {

    				if(WPGMZA.maps[i].id == id)

    					return WPGMZA.maps[i];

    			}

    			return null;

    		},

    		/**

    		 * @function isGoogleAutocompleteSupported

    		 * @summary Shorthand function to determine if the Places Autocomplete is available

    		 * @static

    		 * @return {boolean}

    		 */

    		isGoogleAutocompleteSupported: function() {

    			return typeof google === 'object' && typeof google.maps === 'object' && typeof google.maps.places === 'object' && typeof google.maps.places.Autocomplete === 'function';

    		}

    	};

    	if(window.WPGMZA)

    		window.WPGMZA = $.extend(window.WPGMZA, core);

    	else

    		window.WPGMZA = core;

    	for(var key in WPGMZA_localized_data)

    	{

    		var value = WPGMZA_localized_data[key];

    		WPGMZA[key] = value;

    	}

    	/*for(var key in WPGMZA_localized_data)

    		WPGMZA[key] = WPGMZA_localized_data[key];

    	$(document).ready(function(event) {

    		// Datatables to throw errors

    		if($.fn.dataTable)

    			$.fn.dataTable.ext.errMode = 'throw';

    		// Combined script warning

    		if($("script[src*='wp-google-maps.combined.js'], script[src*='wp-google-maps-pro.combined.js']").length)

    			console.warn("Minified script is out of date, using combined script instead.");

    		// Check for multiple jQuery versions

    		var elements = $("script").filter(function() {

    			return this.src.match(/(^|\/)jquery\.(min\.)?js(\?|$)/i);

    		});

    		if(elements.length > 1)

    			console.warn("Multiple jQuery versions detected: ", elements);

    		// Disable map edit page preloader in developer more

    		if(WPGMZA.isDeveloperMode())

    			$("#wpgmza-map-edit-page form.wpgmza").show();

    		// Shortcode boxes

    		$(".wpgmza_copy_shortcode").on("click", function() {

    			var temp = $("<input>");

    			var temp2 = $('<div id="wpgmza_tmp" style="display: none;" width:100%; text-align:center;"/>');

    			$(document.body).append(temp);

    			temp.val($(this).val()).select();

    			document.execCommand("copy");

    			temp.remove();

    			$(this).after(temp2);

    			$(temp2).html(

    				$("[data-shortcode-copy-string]").attr("data-shortcode-copy-string")

    			);

    			$(temp2).fadeIn();

    			setTimeout(function() {

    				$(temp2).fadeOut();

    			}, 1000);

    			setTimeout(function() {

    				$(temp2).remove();

    			}, 1500);

    		});

    		// Fancy switches

    		// $("form.wpgmza .cmn-toggle").each(function(index, el) {

    		//

    		// 	$(el).wrap("<div class='switch'/>");

    		// 	$(el).after("<label for=""/>")

    		//

    		// });

    		$("form.wpgmza").on("click", ".switch label", function(event) {

    			var input = $(this).prev(".cmn-toggle");

    			if(input.prop("disabled"))

    				return;

    			var val = !input.prop("checked");

    			input.prop("checked", val);

    			if(val)

    				input.attr("checked", "checked");

    			else

    				input.removeAttr("checked");

    			input.trigger("change");

    		});

    		// Geolocation warnings

    		if(window.location.protocol != 'https:')

    		{

    			var warning = '<span class="notice notice-warning">' + WPGMZA.localized_strings.unsecure_geolocation + "</span>";

    			$(".wpgmza-geolocation-setting").after(

    				$(warning)

    			);

    		}

    		// Switch off thanks for feedback message

    		document.cookie = "wpgmza_feedback_thanks=false; expires=Thu, 01 Jan 1970 00:00:01 GMT;";

    	});*/

    })(jQuery);