text: /**
   * Initial bootstrap file for hordemap.
   *
   * This file is responsible for loading the javascript for the map driver we are
   * using. Horde ships with a Horde driver that relies on OpenLayers.js. The
   * Horde driver is able to support any mapping provider that can serve map
   * tiles. We have built in support for Google, Yahoo, and Bing as well as built
   * in support for OpenStreetMaps. To write a new driver to support a new
   * provider, include a new {drivername}.js file in the same directory as this
   * file. Your js file is responsible for including any additional javascript
   * files you may need (such as externally served api files for example). Take
   * a look at the public.js or google.js files for the interface that needs to be
   * implemented.
   */
  HordeMap = {
  
      Map: {},
      _includes: [],
      _opts: {},
      conf: {},
  
      /**
       * Initialize hordemap javascript
       *
       * @param object opts  Hash containing:
       *      'driver':    HordeMap driver to use (Horde)
       *      'geocoder':  Geocoder driver to use
       *      'providers': Default provider layers to add (Google, Yahoo etc...)
       *      'jsuri':     The uri to the hordemap directory
              'ssl':       Use SSL for provider endpoints if possible.
       *
       *      'conf': Any driver specific config settings such as:
       *          'language':
       *          'apikeys': An object containing any api keys needed by the mapping
       *                     provider(s). {'google': 'xxxxx', ...}
       *          'useMarkerLayer': whether or not to use the 'built-in' marker
       *                            layer.
       *          'markerImage':  Path to a marker icon.
       *          'markerBackground':  Path to a marker icon background.
       *          ''
       */
      initialize: function(opts)
      {
          var path;
          this._opts = opts;
          if (!opts.jsuri) {
              path = this._getScriptLocation();
          } else {
              path = opts.jsuri;
          }
          this.conf = this._opts.conf;
          if (this._opts.driver == 'Horde') {
              this._addScript(path + 'OpenLayers.js');
              if (this._opts.conf.language != 'en-US') {
                  this._addScript(path + 'lang/' + this._opts.conf.language + '.js');
              }
          }
  
          this._addScript(path + this._opts.driver.toLowerCase() + '.js');
  
          if (this._opts.geocoder) {
              this._addScript(this._getProviderUrl(this._opts.geocoder));
              this._addScript(path + this._opts.geocoder.toLowerCase() + '.js');
          }
  
          if (this._opts.providers) {
              this._opts.providers.each(function(p) {
                  var u = this._getProviderUrl(p);
                  if (u) {
                      this._addScript(u);
                  }
                  this._addScript(path + p.toLowerCase() + '.js');
              }.bind(this));
          }
  
          this._includeScripts();
      },
  
      _includeScripts: function()
      {
          var files = this._includes;
  
          // Need to use document.write instead of inserting into DOM directly
          // to play nice with horde's javascript caching/loading
          var writeFiles = [];
          for (var i = 0, len = files.length; i < len; i++) {
              writeFiles.push('<script src="' + files[i] + '"></script>');
          }
          document.write(writeFiles.join(""));
      },
  
      _addScript: function(s)
      {
          if (s.length == 0) {
              return;
          }
          var l = this._includes.length;
          for (var i = 0; i < l; i++) {
              if (this._includes[i] == s) {
                  return;
              }
          }
          this._includes.push(s);
      },
  
      /**
       * Return the path to this script.
       *
       * @return string Path to this script
       */
      _getScriptLocation: function () {
          var scriptLocation = "";
          var isMap = new RegExp("(^|(.*?\map\/))(map.js)(\\?|$)");
  
          var scripts = document.getElementsByTagName('script');
          for (var i=0, len=scripts.length; i<len; i++) {
              var src = scripts[i].getAttribute('src');
              if (src) {
                  var match = src.match(isMap);
                  if(match) {
                      scriptLocation = match[1];
                      break;
                  }
              }
          }
          return scriptLocation;
      },
  
      _getProviderUrl: function(p)
      {
          var prot = this._opts.ssl ? 'https' : 'http';
          switch (p) {
          case 'Google':
             return  prot + '://maps.google.com/maps/api/js?v=3.5&amp;sensor=false';
          case 'Yahoo':
              return prot + '://api.maps.yahoo.com/ajaxymap?v=3.8&appid=' + this.conf['apikeys']['yahoo'];
  
          default:
              return '';
          }
      },
  
      /**
       * Base Geocoder implementations.
       * The Horde Class will implement a geocoding service utilizing the various
       * Horde_Core_Ajax_Imple_Geocoder_* classes. Mapping providers that include
       * geocoding services will have HordeMap.Geocoder implementations in their
       * respective *.js files.  The Null driver provides fallback implementaions
       * for those without geocoder support.
       *
       */
      Geocoder: {}
  };
  
  