;
/*
 * This document is licensed as free software under the terms of the
 * MIT License: <a href="http://www.opensource.org/licenses/mit-license.php" title="http://www.opensource.org/licenses/mit-license.php">http://www.opensource.org/licenses/mit-license.php</a>
 *
 * Adapted by Rahul Singla.
 *
 * Brantley Harris wrote this plugin. It is based somewhat on the JSON.org 
 * website's <a href="http://www.json.org/json2.js" title="http://www.json.org/json2.js">http://www.json.org/json2.js</a>, which proclaims:
 * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
 * I uphold.
 *
 * It is also influenced heavily by MochiKit's serializeJSON, which is 
 * copyrighted 2005 by Bob Ippolito.
 */

/**
 * jQuery.JSON.encode( json-serializble ) Converts the given argument into a
 * JSON respresentation.
 * 
 * If an object has a "toJSON" function, that will be used to get the
 * representation. Non-integer/string keys are skipped in the object, as are
 * keys that point to a function.
 * 
 * json-serializble: The *thing* to be converted.
 */
jQuery.JSON = {
	encode: function(o) {
		if (typeof (JSON) == 'object' && JSON.stringify)
			return JSON.stringify(o);

		var type = typeof (o);

		if (o === null)
			return "null";

		if (type == "undefined")
			return undefined;

		if (type == "number" || type == "boolean")
			return o + "";

		if (type == "string")
			return this.quoteString(o);

		if (type == 'object') {
			if (typeof o.toJSON == "function")
				return this.encode(o.toJSON());

			if (o.constructor === Date) {
				var month = o.getUTCMonth() + 1;
				if (month < 10)
					month = '0' + month;

				var day = o.getUTCDate();
				if (day < 10)
					day = '0' + day;

				var year = o.getUTCFullYear();

				var hours = o.getUTCHours();
				if (hours < 10)
					hours = '0' + hours;

				var minutes = o.getUTCMinutes();
				if (minutes < 10)
					minutes = '0' + minutes;

				var seconds = o.getUTCSeconds();
				if (seconds < 10)
					seconds = '0' + seconds;

				var milli = o.getUTCMilliseconds();
				if (milli < 100)
					milli = '0' + milli;
				if (milli < 10)
					milli = '0' + milli;

				return '"' + year + '-' + month + '-' + day + 'T' + hours + ':'
						+ minutes + ':' + seconds + '.' + milli + 'Z"';
			}

			if (o.constructor === Array) {
				var ret = [];
				for ( var i = 0; i < o.length; i++)
					ret.push(this.encode(o[i]) || "null");

				return "[" + ret.join(",") + "]";
			}

			var pairs = [];
			for ( var k in o) {
				var name;
				var type = typeof k;

				if (type == "number")
					name = '"' + k + '"';
				else if (type == "string")
					name = this.quoteString(k);
				else
					continue; // skip non-string or number keys

				if (typeof o[k] == "function")
					continue; // skip pairs where the value is a function.

				var val = this.encode(o[k]);

				pairs.push(name + ":" + val);
			}

			return "{" + pairs.join(", ") + "}";
		}
	},

	/**
	 * jQuery.JSON.decode(src) Evaluates a given piece of json source.
	 */
	decode: function(src) {
		if (typeof (JSON) == 'object' && JSON.parse)
			return JSON.parse(src);
		return eval("(" + src + ")");
	},

	/**
	 * jQuery.JSON.decodeSecure(src) Evals JSON in a way that is *more* secure.
	 */
	decodeSecure: function(src) {
		if (typeof (JSON) == 'object' && JSON.parse)
			return JSON.parse(src);

		var filtered = src;
		filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
		filtered = filtered
				.replace(
						/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
						']');
		filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');

		if (/^[\],:{}\s]*$/.test(filtered))
			return eval("(" + src + ")");
		else
			throw new SyntaxError("Error parsing JSON, source is not valid.");
	},

	/**
	 * jQuery.JSON.quoteString(string) Returns a string-repr of a string, escaping
	 * quotes intelligently. Mostly a support function for JSON.encode.
	 * 
	 * Examples: >>> jQuery.JSON.quoteString("apple") "apple"
	 * 
	 * >>> jQuery.JSON.quoteString('"Where are we going?", she asked.') "\"Where
	 * are we going?\", she asked."
	 */
	quoteString: function(string) {
		if (string.match(this._escapeable)) {
			return '"' + string.replace(this._escapeable, function(a) {
				var c = this._meta[a];
				if (typeof c === 'string')
					return c;
				c = a.charCodeAt();
				return '\\u00' + Math.floor(c / 16).toString(16)
						+ (c % 16).toString(16);
			}) + '"';
		}
		return '"' + string + '"';
	},

	_escapeable: /["\\\x00-\x1f\x7f-\x9f]/g,

	_meta: {
		'\b': '\\b',
		'\t': '\\t',
		'\n': '\\n',
		'\f': '\\f',
		'\r': '\\r',
		'"': '\\"',
		'\\': '\\\\'
	}
};
// When the document is ready
  jQuery(document).ready(function (){
  // Curiousermap class
    Front = function () {
      this.initialized = false;
      this.markers = new Array();
      this.is_ready = false;
      
      this.init = function () {
    //console.log('map init');
        if (curiousermap.front.initialized == false) {
          this.sidebar = jQuery('#home #sidebar');
        
        // Style sidebar
          pua.home_sidebar_fix();
        
        // Bind click to close nav
          jQuery('#curiousermap').one('mousedown', function () {
            setTimeout(function () {
            // Click on the status
              if (!jQuery('#home #sidebar:animated').exists() || curiousermap.front.sidebar.offset().left < jQuery(window).width()/3.9) {
              // Open the status infowindow
                google.maps.event.trigger(curiousermap.front.markers['status'][0], 'click');
               }
            }, 250);
          
          // Remove the nav banner
            pua.nav_remove(true);
            
          // show the marker filter
            jQuery('#home #marker_filter').animate({
                left: "75%"
              }, animation_duration/2);
            
          // Hack to fix marker overlays
            curiousermap.front.marker_fix();
          })
        
        // info window
          curiousermap.front.infoWindow = new google.maps.InfoWindow();
       
        // Get center of map
          curiousermap.front.center = new google.maps.LatLng(this.places[this.last].lat,this.places[this.last].lng);
          
        // Set map options
          curiousermap.front.map_options = {
            backgroundColor: '#99b3cc',
            zoom: 7,
            center: this.center,
            panControl: false,
            mapTypeControl: false,
            scrollwheel: false,
            zoomControl: true,
            zoomControlOptions: {
              style: google.maps.ZoomControlStyle.DEFAULT,
              position: google.maps.ControlPosition.LEFT_CENTER
            },
            streetViewControl: false,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
          
        // Create the map
          curiousermap.front.map = new google.maps.Map(jQuery('#curiousermap')[0], this.map_options);
          
          google.maps.event.addListenerOnce(curiousermap.front.map, 'tilesloaded', function () {
          // Set ready flags
            curiousermap.front.is_ready = true;
            
          // Attempt to show window
            pua.map_loaded();
          
          // Hack to fix marker overlays
            curiousermap.front.marker_fix();
            //console.log('map ready');
          });
          
        // initialize markers
          curiousermap.front.initialize_markers();
          
        // Draw route
          curiousermap.front.draw_route();
        
        // Bind filters
          curiousermap.front.bind_filters();
          
          curiousermap.front.initialized = true;
        }
      }
      this.marker_fix = function () {
        jQuery('.gmnoprint img[src="/sites/all/modules/curiousermap/graphics/marker_sprite.png"]').parent().addClass('marker');
      }
      this.initialize_markers = function () {
      // Shadow for marker icon
        this.shadow = new google.maps.MarkerImage(
          "/sites/all/modules/curiousermap/graphics/marker_shadow.png",
          new google.maps.Size(56,50),
          new google.maps.Point(0,0),
          new google.maps.Point(14,50)
        );
      
      // shape of marker icon
        this.shape = {
          coord: [19,0,21,1,22,2,23,3,24,4,25,5,26,6,26,7,27,8,27,9,27,10,27,11,27,12,27,13,27,14,27,15,27,16,27,17,27,18,27,19,26,20,26,21,26,22,25,23,24,24,24,25,23,26,22,27,21,28,21,29,20,30,19,31,18,32,18,33,17,34,17,35,16,36,16,37,16,38,15,39,15,40,15,41,15,42,14,43,14,44,14,45,14,46,14,47,14,48,14,49,13,49,13,48,13,47,13,46,13,45,13,44,13,43,12,42,12,41,12,40,12,39,11,38,11,37,11,36,10,35,10,34,9,33,9,32,8,31,7,30,7,29,6,28,5,27,4,26,4,25,3,24,2,23,2,22,1,21,1,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,0,9,0,8,1,7,1,6,2,5,3,4,4,3,5,2,6,1,8,0,19,0],
          type: 'poly'
        };
      
      // For each place, create a marker and transfer all the place data to it
        for (x in this.places) {
        // prepare marker image      
          var icon = new google.maps.MarkerImage("/sites/all/modules/curiousermap/graphics/marker_sprite.png", new google.maps.Size(28, 50), new google.maps.Point(0, this.places[x].icon_offset*50), new google.maps.Point(14, 50), new google.maps.Size(84, 1400));
        
        // Create marker
          if (this.places[x].entity == 'node') {
          // Node
            var y = new google.maps.Marker({
              position: new google.maps.LatLng(this.places[x].lat, this.places[x].lng), 
              map: this.map,
              title: this.places[x].title,
              icon: icon,
              shadow: this.shadow,
              shape: this.shape,
              content: this.places[x].content,
              type: this.places[x].type,
              filter: this.places[x].filter,
              id: x,
              center: x == this.last ? true : false,
              icon_offset: this.places[x].icon_offset
            });
            
          // Status opens in info window
            if (this.places[x].type == 'status') {
              y.window = true;
              y.setZIndex(google.maps.Marker.MAX_ZINDEX-1);
              curiousermap.front.map.setCenter(y.getPosition());
            }
          }
          else {
          // User
            var y = new google.maps.Marker({
              position: new google.maps.LatLng(this.places[x].lat, this.places[x].lng), 
              title: this.places[x].title,
              map: this.map, 
              icon: icon,
              shadow: this.shadow,
              shape: this.shape,
              path: this.places[x].path,
              content: this.places[x].content,
              type: this.places[x].type,
              filter: this.places[x].filter,
              id: x,
              center: x == this.last ? true : false,
              icon_offset: this.places[x].icon_offset
            }); 
          }   
        
        // Add to marker array
          if (!this.markers[y.filter]) { this.markers[y.filter] = new Array(); }
          this.markers[y.filter].push(y);
          
        // Bind marker click
          this.bind_marker_click(y);
        }
      
      // Delete our places object, all data is within the marker array
        delete this.places;
        
        var i = 1;
        jQuery.each(this.markers['blog'], function () {
          this.setZIndex(i);
          i++;
        });
        jQuery.each(this.markers['about'], function () {
          this.setZIndex(i);
          i++;
        });
        jQuery.each(this.markers['media'], function () {
          this.setZIndex(i);
          i++;
        });
        jQuery.each(this.markers['event'], function () {
          this.setZIndex(i);
          i++;
        });
      }
      
      this.bind_marker_click = function (marker) {
      // Bind click
        google.maps.event.addListener(marker, 'click', function () {        
        if (curiousermap.front.marker == marker) { return; }
        // pan to
          curiousermap.front.map.panTo(this.getPosition());
        
        // Shrink last marker
          curiousermap.front.toggle_marker(curiousermap.front.marker);
        
        // Enlarge this marker
          curiousermap.front.toggle_marker(this);
          
        // Hacking again, add class
          setTimeout(curiousermap.front.marker_fix, 1000);
        
        // Close infowindow
          curiousermap.front.infoWindow.close();
          
        // Close sidebar
          if (curiousermap.front.sidebar.hasClass('active')) {
            curiousermap.front.sidebar.animate({
              left : '100%'
            }, animation_duration/2, function () {
              jQuery(this).removeClass('active');
            });
          }
          
        // Queue if the nav is closing
          jQuery('#primary_nav>li.home').queue(function () {
          //alert('here');
          // Show window
            if (marker.window == true) {
              curiousermap.front.infoWindow.setContent(marker.content);
              curiousermap.front.infoWindow.open(curiousermap.front.map, marker); 
            }
          // Show sidebar
            else {
              curiousermap.front.show_sidebar(marker.content);
            }
          
          // Dequeue
            jQuery(this).dequeue();
          });
        });
      }
      
      this.toggle_marker = function (marker) {// Shadow for marker icon
        if (!marker) { return; }
        if (marker == curiousermap.front.marker) {
        // Shadow
          var shadow = new google.maps.MarkerImage(
            "/sites/all/modules/curiousermap/graphics/marker_shadow.png",
            new google.maps.Size(56,50),
            new google.maps.Point(0,0),
            new google.maps.Point(14,50)
          );
        
        // shape of marker icon
          var shape = {
            coord: [19,0,21,1,22,2,23,3,24,4,25,5,26,6,26,7,27,8,27,9,27,10,27,11,27,12,27,13,27,14,27,15,27,16,27,17,27,18,27,19,26,20,26,21,26,22,25,23,24,24,24,25,23,26,22,27,21,28,21,29,20,30,19,31,18,32,18,33,17,34,17,35,16,36,16,37,16,38,15,39,15,40,15,41,15,42,14,43,14,44,14,45,14,46,14,47,14,48,14,49,13,49,13,48,13,47,13,46,13,45,13,44,13,43,12,42,12,41,12,40,12,39,11,38,11,37,11,36,10,35,10,34,9,33,9,32,8,31,7,30,7,29,6,28,5,27,4,26,4,25,3,24,2,23,2,22,1,21,1,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,0,9,0,8,1,7,1,6,2,5,3,4,4,3,5,2,6,1,8,0,19,0],
            type: 'poly'
          };
          
          var icon = new google.maps.MarkerImage(
            "/sites/all/modules/curiousermap/graphics/marker_sprite.png",
            new google.maps.Size(28, 50),
            new google.maps.Point(0, marker.icon_offset*50),
            new google.maps.Point(14, 50),
            new google.maps.Size(84, 1400)
          );
          
          var zindex = marker.old_zindex;
        }
        else {
          curiousermap.front.marker = marker;
        // Shadow
          var shadow = new google.maps.MarkerImage(
            "/sites/all/modules/curiousermap/graphics/marker_shadow_large.png",
            new google.maps.Size(110,100),
            new google.maps.Point(0,0),
            new google.maps.Point(28,100)
          );
        
        // shape of marker icon
          var shape = {
            coord: [35,0,38,1,40,2,42,3,44,4,45,5,46,6,47,7,48,8,49,9,50,10,51,11,51,12,52,13,52,14,53,15,53,16,54,17,54,18,54,19,55,20,55,21,55,22,55,23,55,24,55,25,55,26,55,27,55,28,55,29,55,30,55,31,55,32,55,33,55,34,55,35,55,36,54,37,54,38,54,39,53,40,53,41,53,42,52,43,52,44,51,45,50,46,50,47,49,48,48,49,48,50,47,51,46,52,45,53,45,54,44,55,43,56,42,57,42,58,41,59,40,60,39,61,39,62,38,63,37,64,37,65,36,66,36,67,35,68,35,69,34,70,34,71,33,72,33,73,32,74,32,75,32,76,31,77,31,78,31,79,30,80,30,81,30,82,30,83,30,84,29,85,29,86,29,87,29,88,29,89,29,90,29,91,29,92,28,93,28,94,28,95,28,96,28,97,28,98,28,99,27,99,27,98,27,97,27,96,27,95,27,94,27,93,26,92,26,91,26,90,26,89,26,88,26,87,26,86,26,85,25,84,25,83,25,82,25,81,25,80,24,79,24,78,24,77,23,76,23,75,23,74,22,73,22,72,21,71,21,70,21,69,20,68,20,67,19,66,18,65,18,64,17,63,17,62,16,61,15,60,15,59,14,58,13,57,12,56,12,55,11,54,10,53,9,52,9,51,8,50,7,49,6,48,6,47,5,46,4,45,4,44,3,43,3,42,2,41,2,40,1,39,1,38,1,37,0,36,0,35,0,34,0,33,0,32,0,31,0,30,0,29,0,28,0,27,0,26,0,25,0,24,0,23,0,22,0,21,0,20,1,19,1,18,1,17,2,16,2,15,3,14,3,13,4,12,5,11,5,10,6,9,7,8,8,7,9,6,10,5,12,4,13,3,15,2,17,1,20,0,35,0],
            type: 'poly'
          };
          
          var icon = new google.maps.MarkerImage(
            "/sites/all/modules/curiousermap/graphics/marker_sprite.png",
            new google.maps.Size(56, 100),
            new google.maps.Point(28, marker.icon_offset*100),
            new google.maps.Point(28, 100),
            new google.maps.Size(84, 1400)
          );
          
          marker.old_zindex = marker.zIndex;
          var zindex = google.maps.Marker.MAX_ZINDEX;
        }
        
        marker.setZIndex(zindex);
        marker.setShadow(shadow);
        marker.setShape(shape);
        marker.setIcon(icon);
      }
      
      this.bind_marker_hover = function () {
        
      }
      
      this.marker_click = function () {
        
      } 
      this.draw_route = function () {
        var waypoints = new Array();
        
        for (i = 0; i < this.route_array.length; i++) {
          var temp = this.route_array[i];
        // Origin
          if (i == 0) {
            var origin = temp.lat+', '+temp.lng;
            var icon_offset = 3;
            var icon = new google.maps.MarkerImage("/sites/all/modules/curiousermap/graphics/marker_sprite.png", new google.maps.Size(28, 50), new google.maps.Point(0, icon_offset*50), new google.maps.Point(14, 50), new google.maps.Size(84, 1400));
          // Add start marker
            var y = new google.maps.Marker({
              position: new google.maps.LatLng(temp.lat, temp.lng), 
              map: this.map, 
              content: '<div class="node"><h2>Start of Tour</h2><div class="date">March 20, 2010</div><div class="location">Assateague, MD</div><div class="content"><div class="field-body"><p>This is where the tour began</p></div></div></div>',
              animation: google.maps.Animation.DROP,
              filter: 'origin',
              icon: icon,
              shadow: this.shadow,
              shape: this.shape,
              zIndex: google.maps.Marker.MAX_ZINDEX-1,
              window: true,
              icon_offset: icon_offset
            });
            
            // Add to marker array
            if (!this.markers[y.filter]) { this.markers[y.filter] = new Array(); }
            this.markers[y.filter].push(y);
            
            // Bind click
            this.bind_marker_click(y);
          }
        // Destination
          else if (i == this.route_array.length-1) {
            var dest = temp.lat+', '+temp.lng;
            var icon_offset = 4;
            var icon = new google.maps.MarkerImage("/sites/all/modules/curiousermap/graphics/marker_sprite.png", new google.maps.Size(28, 50), new google.maps.Point(0, icon_offset*50), new google.maps.Point(14, 50), new google.maps.Size(84, 1400));
            
            // Add finish marker
            var y = new google.maps.Marker({
              position: new google.maps.LatLng(temp.lat, temp.lng), 
              map: this.map, 
              filter: 'destination',
              content: '<div class="node"><h2>End of Tour</h2><div class="date">Fall, 2012</div><div class="location">San Francisco, CA</div><div class="content"><div class="field-body"><p>This is where the tour is scheduled to end</p></div></div></div>',
              animation: google.maps.Animation.DROP,
              icon: icon,
              shadow: this.shadow,
              shape: this.shape,
              zIndex: google.maps.Marker.MAX_ZINDEX-1,
              window: true,
              icon_offset: icon_offset
            });
            
            // Bind click
            this.bind_marker_click(y);
          }
        // Waypoint
          else {
            waypoints.push({ location: temp.lat+', '+temp.lng, stopover: false });
          }
        };
        
        this.directions = new google.maps.DirectionsService();  
        this.directions.route({destination: dest, origin: origin, waypoints: waypoints, optimizeWaypoints: true, avoidTolls: true, avoidHighways: true, travelMode: google.maps.TravelMode.WALKING}, function (result, status) {  
          curiousermap.dir_response = new google.maps.DirectionsRenderer({
            directions: result,
            hideRouteList: true,
            suppressInfoWindows: true,
            suppressMarkers: true,
            preserveViewport: true,
            map: curiousermap.front.map,
            polylineOptions: {
              strokeColor: "#43c741",
              strokeOpacity: 0.7,
              strokeWeight: 5
            }
          });          
        });
      }
      this.show_sidebar = function (content) {
        curiousermap.front.sidebar.queue(function() {
          jQuery(this).html(content+'<div class="bg"></div>').animate({
            left: '75%'
          }, animation_duration/2, function () {
            jQuery(this).addClass('active');
          });
          
        // Cover photo center
          var img = jQuery('.node-video .cover_photo img, .node-album .cover_photo img', this);
        // Not loaded yet, bind for load
          if (img.height() > 200) {
            var diff = jQuery('.cover_photo', this).height()/2 - img.height()/2;
            img.css('margin-top', diff+'px');
          }
        // Already loaded, center
          else {
            img.load(function () {
              var diff = jQuery(this).closest('.cover_photo').height()/2 - jQuery(this).height()/2;
              jQuery(this).css('margin-top', diff+'px');
            })
          }
          
          jQuery(this).dequeue();
        });
      }
      
      this.bind_filters = function () {
      // Clicks
        jQuery('#marker_filter li').toggle(function () {
          curiousermap.front.filter_off(this);
        }, function () {
          curiousermap.front.filter_on(this);
          curiousermap.front.marker_fix();
        });
        
      // Hovers
        jQuery('#marker_filter li').hover(function () {
          jQuery('#marker_filter span.marker_name').addClass('bold').html(jQuery(this).attr('class'));
        }, function () {
          jQuery('#marker_filter span.marker_name').removeClass('bold').html('Marker');
        });
      }
      
      this.filter_on = function (filter) {
      // Replace filter img
        var src = jQuery('img', filter).attr('src');
        jQuery('img', filter).attr('src', src.replace('_off.png', '.png'));
      
      // Show markers function
        curiousermap.front.show_markers(jQuery(filter).attr('class'));
      }
      
      this.filter_off = function (filter) {
      // Replace filter img
        var src = jQuery('img', filter).attr('src');
        jQuery('img', filter).attr('src', src.replace('.png', '_off.png'));
        
      // hide markers function
        curiousermap.front.hide_markers(jQuery(filter).attr('class'));
      }
      
      this.show_markers = function (type) {
        for (x in curiousermap.front.markers[type]) {
          curiousermap.front.markers[type][x].setMap(curiousermap.front.map);
        }
      }
      
      this.hide_markers = function (type) {
        for (x in curiousermap.front.markers[type]) {
          curiousermap.front.markers[type][x].setMap(null);
        }
      }
    }
    
    Edit = function () {
      this.init = function () {
      // Geocoder
        curiousermap.geocoder = new google.maps.Geocoder();
      
      // Create container for map
        jQuery('#edit-field-curiousermap-und-0').append('<a class="button" id="search_gmap">Search</a><div id="admin_map" style="width: 300px; height: 300px;"></div>');
        
      // Draw map
        this.draw_map();
        
      // Bind change position
        jQuery('#admin_map #gmimap0').live('mouseup', function () {
          jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lat\\]"]').val(curiousermap.edit.marker.position.lat());
          jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lng\\]"]').val(curiousermap.edit.marker.position.lng());
          curiousermap.geocoder.geocode({location:curiousermap.edit.marker.position}, function (results, status) {
            curiousermap.edit.fill_fields(results, status);
          });
        });
      
      // Search maps when the user clicks search
        jQuery('#search_gmap').click(function () {
          curiousermap.edit.search();
        });
      }
      this.draw_map = function () {
      // Get center of map
        this.center = jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lat\\]"]').val() !== '' ? new google.maps.LatLng(jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lat\\]"]').val(), jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lng\\]"]').val()) : new google.maps.LatLng(38.9384626,-77.0320553);
        
      // Set map options
        this.map_options = {
          zoom: 4,
          center: this.center,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        
      // Create the map
        this.map = new google.maps.Map(jQuery('#admin_map')[0], this.map_options);
        
      // Create the marker
        this.marker = new google.maps.Marker({
          position: this.center,
          map: this.map,
          draggable: true
        });
      }
      this.search = function () {
        var search = '';
        search += jQuery('#edit-field-curiousermap-und-0-street').val() !== '' ? jQuery('#edit-field-curiousermap-und-0-street').val()+', ' : '';
        search += jQuery('#edit-field-curiousermap-und-0-city').val() !== '' ? jQuery('#edit-field-curiousermap-und-0-city').val()+', ' : '';
        search += jQuery('#edit-field-curiousermap-und-0-state').val() !== '' ? jQuery('#edit-field-curiousermap-und-0-state').val()+', ' : '';
        search += jQuery('#edit-field-curiousermap-und-0-zip').val() !== '' ? jQuery('#edit-field-curiousermap-und-0-zip').val() : '';
        search = search.trim(', ');
        curiousermap.geocoder.geocode({ 'address' : search}, function (results, status) {
          var lat = results[0]['geometry'].location.lat();
          var lng = results[0]['geometry'].location.lng();
        
        // Change the marker position
          curiousermap.edit.center = new google.maps.LatLng(lat, lng);
          curiousermap.edit.marker.setPosition(curiousermap.edit.center);
          curiousermap.edit.map.panTo(curiousermap.edit.center);
          
        // Change our lng, lat and fill inputs
          jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lat\\]"]').val(lat);
          jQuery('#edit-field-curiousermap-und-0 input[name="field_curiousermap\\[und\\]\\[0\\]\\[lng\\]"]').val(lng);
          
          curiousermap.edit.fill_fields(results, status);
        });
      }
      
      this.fill_fields = function (results, status) {
        results = results[0]['formatted_address'].split(',');
        if (results.length === 3) {
          var street = '';
          var city = results[0];
          var state = results[1].split(' ');
          var zip = state[2];
          var state = state[1];
        }
        else if (results.length === 4) {
          var street = results[0];
          var city = results[1];
          var state = results[2].split(' ');
          var zip = state[2];
          var state = state[1];
        }
        
        jQuery('#edit-field-curiousermap-und-0-street').val(street);
        jQuery('#edit-field-curiousermap-und-0-city').val(jQuery.trim(city));
        jQuery('#edit-field-curiousermap-und-0-state option[value="'+state+'"]').attr('selected', 'selected');
        jQuery('#edit-field-curiousermap-und-0-zip').val(zip);
      } 
    }
    
    Route = function () {
      this.markers = new Array();
      
      this.init = function () {
        var self = this;
      // Geocoder
        curiousermap.geocoder = new google.maps.Geocoder();
        this.directions = new google.maps.DirectionsService();
        
      // Map container
        jQuery('#curiousermap-route-fieldset-wrapper').append('<div id="route_map" style="width: 100%; height: 300px;"></div>');
      
      // Remove add selector and remove selector buttons
        jQuery('#edit-curiousermap-route .clearfix, #edit-curiousermap-route input[type=submit]').remove();
        
      // Add buttons
        jQuery('#edit-curiousermap-route .form-item').after('<a class="button add_dest">Add Destination</a><a class="remove_dest button">Remove Destination</a>');
        
      // draw map
        this.draw_map();  
      
      // Add markers
        this.init_markers();        
        
      // Get directions
        this.get_directions();
        
      // Bind
        jQuery('#edit-curiousermap-route a.add_dest').live('click', function () {
          
          var search = jQuery(this).prev().find('input').val();
          var key = jQuery(this).prevAll('div').length-1;
          var next = jQuery(this).prevAll('div').length;
          var elem = this;
        
        // Search
          curiousermap.geocoder.geocode({ 'address' : search}, function (results, status) {
            var lat = results[0]['geometry'].location.lat();
            var lng = results[0]['geometry'].location.lng();
          
        // Change the marker position
          curiousermap.route.markers[key] = new google.maps.Marker({position: new google.maps.LatLng(lat, lng) });
          curiousermap.route.markers[key].setMap(curiousermap.route.map);
          
        // Change our lng, lat and fill inputs
          jQuery(elem).nextUntil('div').not('a.button').each(function (index) {
              if (index == 0) { jQuery(this).val(lat); }
              else if (index == 1) { jQuery(this).val(lng); }
            });
            
        // Directions
          curiousermap.route.get_directions(true);
        
        // Add more inputs
          var markup = '<div class="form-item form-type-textfield form-item-curiousermap-route-destination-'+next+'-address"><input type="text" class="form-text" maxlength="128" size="60" value="" name="curiousermap_route[destination]['+next+'][address]" id="edit-curiousermap-route-destination-'+next+'-address"></div><a class="button add_dest">Add Destination</a><a class="remove_dest button">Remove Destination</a><input type="hidden" value="" name="curiousermap_route[destination]['+next+'][lat]"><input type="hidden" value="" name="curiousermap_route[destination]['+next+'][lng]">';
          jQuery('#edit-curiousermap-route .fieldset-wrapper').append(markup);
          });
        });
        
        jQuery('#edit-curiousermap-route a.remove_dest').live('click', function () {
          var key = jQuery(this).prevAll('div').length-1;
          jQuery(this).nextUntil('div').add(jQuery(this).prevUntil('input')).add(jQuery(this)).remove();
          curiousermap.route.markers[key].setMap(null);
          
        // Directions
          curiousermap.route.get_directions(true);
        });
      }
      this.draw_map = function () {
      // Get center of map
        this.center = new google.maps.LatLng(38.9384626,-77.0320553);
        
      // Set map options
        this.map_options = {
          zoom: 4,
          center: this.center,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        
      // Create the map
        this.map = new google.maps.Map(jQuery('#route_map')[0], this.map_options);
      }
      this.init_markers = function () {
        var lats = new Array();
        var lngs = new Array();
        
        jQuery('#edit-curiousermap-route input[type=hidden]:odd').each(function (index, value) {
          lngs[index] = jQuery(this).val();
        });
        
        jQuery('#edit-curiousermap-route input[type=hidden]:even').each(function (index, value) {
          lats[index] = jQuery(this).val();
        });
        
        for (i=0; i < lats.length-1; i++) {
          curiousermap.route.markers[i] = new google.maps.Marker({position: new google.maps.LatLng(lats[i], lngs[i]) });
          curiousermap.route.markers[i].setMap(curiousermap.route.map);
        }
      }
      
      this.get_directions = function (bypass) {
        if (!bypass) { bypass = false; }
        if (this.markers.length < 3) { return; }
        //if ((bypass === true || jQuery('#curiousermap-admin input[name=directions]').val() == '')) {
          var waypoints = new Array();
          
          for (i = 0; i < this.markers.length; i++) {
            var temp = this.markers[i].getPosition();
          // Origin
            if (i == 0) {
              var origin = temp.lat()+', '+temp.lng();
            }
          // Destination
            else if (i == this.markers.length-1) {
              var dest = temp.lat()+', '+temp.lng();
            }
          // Waypoint
            else {
              waypoints.push({ location: temp.lat()+', '+temp.lng() });
            }
          };
          
          //this.directions.route({destination: this.waypoints.pop(), origin: this.waypoints.shift(), waypoints: this.waypoints, optimizeWaypoints: true, travelMode: google.maps.TravelMode.DRIVING}, function (result, status) {
          this.directions.route({destination: dest, origin: origin, waypoints: waypoints, optimizeWaypoints: true, avoidTolls: true, avoidHighways: true, travelMode: google.maps.TravelMode.WALKING}, function (result, status) {  
            curiousermap.dir_response = new google.maps.DirectionsRenderer({
              directions: result,
              hideRouteList: true,
              suppressInfoWindows: true,
              suppressMarkers: true,
              preserveViewport: true,
              map: curiousermap.route.map,
              polylineOptions: {
                strokeColor: "#ff9900",
                strokeOpacity: 1.0,
                strokeWeight: 2
              }
            });
            //jQuery('#curiousermap-admin input[name=directions]').val(jQuery.JSON.encode(curiousermap.dir_response.getDirections()));
          });
        //}
      /*
        else {
          result = jQuery.JSON.decode(jQuery('#curiousermap-admin input[name=directions]').val());
          curiousermap.dir_response = new google.maps.DirectionsRenderer({
            directions: result,
            hideRouteList: true,
            suppressInfoWindows: true,
            suppressMarkers: true,
            preserveViewport: true,
            map: curiousermap.route.map,
            polylineOptions: {
              strokeColor: "#ff9900",
              strokeOpacity: 1.0,
              strokeWeight: 2
            }
          });
        }
      */
      }
    }
    
    Curiousermap = function () {
      this.initialized = false;
      
      this.front = new Front();
      this.edit = new Edit();
      this.route = new Route();
      
      this.initialize = function () {
        if (this.initialized == true) { return; }
        else { this.initialized = true; }
        
        if (this.is_edit == true) {
          var script = document.createElement("script");
          script.type = "text/javascript";
          script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=curiousermap.edit.init";
          document.body.appendChild(script);
        }
        else if (this.is_route == true) {
          var script = document.createElement("script");
          script.type = "text/javascript";
          script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=curiousermap.route.init";
          document.body.appendChild(script);
        }
        else if (this.is_front == true && this.front.initialized == false) {
          var script = document.createElement("script");
          script.type = "text/javascript";
          script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=curiousermap.front.init";
          document.body.appendChild(script);
        }
      }
    }
    
  // Curiousermap object
    window.curiousermap = new Curiousermap();
    
    jQuery(window).load(function () {
      if (!curiousermap.is_front) {
        curiousermap.initialize();
      }
    });
  });;

