// GSVPano.js
                      // Copyright (c) 2014 Heganoo
                      // https://github.com/heganoo/GSVPano
                      
                      var eventEmitter = require('event-emitter');
                      
                      /**
                       * @module GSVPANO
                       * @author Hegano
                       * @author juampi92
                       */
                      var GSVPANO = GSVPANO || {};
                      
                      
                      /**
                       * Fetch URL. Use this parameter in case the URL stops working. At
                       * the end of this string, the parameters &panoid, &x, &y, &zoom 
                       * and the current timestamp are appended.
                       * @property GSVPANO._url
                       * @type {String}
                       * @default 'http://maps.google.com/cbk?output=tile'
                       */
                      // 'https://geo0.ggpht.com/cbk?cb_client=maps_sv.tactile&authuser=0&hl=en&output=tile&nbt&fover=2'
                      // 'https://cbks2.google.com/cbk?cb_client=maps_sv.tactile&authuser=0&hl=en&output=tile'
                      
                      GSVPANO._url = 'http://maps.google.com/cbk?output=tile';
                      
                      /**
                       * Data Fetch URL. Use this parameter in case the URL stops working.
                       * At the end of this string, the parameter &ll is appended.
                       * @property GSVPANO._data_url
                       * @type {String}
                       * @default 'https://cbks0.google.com/cbk?cb_client=maps_sv.tactile&authuser=0&hl=en&output=polygon&it=1%3A1&rank=closest&radius=350'
                       */
                      GSVPANO._data_url = 'https://cbks0.google.com/cbk?cb_client=maps_sv.tactile&authuser=0&hl=en&output=polygon&it=1%3A1&rank=closest&radius=350';
                      
                      GSVPANO.Pano = require('./Pano');
                      
                      /**
                       * @class PanoLoader
                       * @extends {EventEmitter}
                       * @constructor
                       * @param {Object} parameters
                       * @param {Number} parameters.zoom Zoom (default 1)
                       * @param {Number} parameters.autocompose Compose automatically (default true)
                       * @param {Number} parameters.radius Google getPanoramaByLocation radius parameter (default 50)
                       * @example
                       *       var loader = new GSVPANO.PanoLoader({ zoom: 3, autocompose: false });
                       */
                      GSVPANO.PanoLoader = function(parameters) {
                        'use strict';
                      
                        eventEmitter(this);
                      
                        var _params = parameters || {};
                      
                        this._panoClient = new google.maps.StreetViewService();
                      
                        /**
                         * @attribute zoom
                         * @type {Number}
                         * @default 1
                         * @private
                         */
                        this.setZoom(_params.zoom || 1);
                        /**
                         * Decides that when a Pano is added, it starts composing right away
                         * @attribute autocompose
                         * @type {Boolean}
                         * @default true
                         */
                        this.autocompose = (_params.autocompose === undefined) ? true : _params.autocompose;
                        /**
                         * Google getPanoramaByLocation radius parameter
                         * @attribute radius
                         * @type {Number}
                         * @default 50
                         */
                        this.radius = _params.radius || 50;
                      };
                      
                      /**
                       * @event panorama.data
                       * @param {Pano} pano
                       * @example
                       *     loader.on('panorama.data', function(pano){
                       *       console.log('Pano ' + pano.id + ' added');
                       *     });
                       */
                      
                      /**
                       * @event panorama.nodata
                       * @param {Google.Maps.LatLng} location
                       * @param {Google.Maps.StreetViewStatus} status
                       */
                      
                      /**
                       * @event panorama.progress
                       * @param {Number} p
                       * @param {Pano} pano
                       * @example
                       *         loader.on('progress', function(p, pano) {
                       *           console.log('Pano progress: ' + p + '%');
                       *         });
                       */
                      GSVPANO.PanoLoader.prototype._setProgress = function(pano, p) {
                        this.emit('panorama.progress', p, pano);
                      };
                      /**
                       * @event panorama.load
                       * @param {Pano} pano
                       * @example
                       *     loader.on('panorama.load', function(pano){
                       *       $container.append(pano.canvas);
                       *     });
                       */
                      
                      /**
                       * @event error
                       * @param {String} message
                       * @example
                       *     loader.on('error', function(message){
                       *       console.log(message)
                       *     });
                       */
                      GSVPANO.PanoLoader.prototype._throwError = function(message) {
                        this.emit('error', message);
                      };
                      
                      /**
                       * Middle function for working with IDs.
                       * @method loadData
                       * @param {Google.Maps.Location} location
                       * @deprecated Disabled right now
                       */
                      /*this.loadData = function(location) {
                        var self = this;
                        var url;
                      
                        //url = 'https://maps.google.com/cbk?output=json&hl=x-local&ll=' + location.lat() + ',' + location.lng() + '&cb_client=maps_sv&v=3';
                        url = GSVPANO._data_url + '&ll=' + location.lat() + ',' + location.lng();
                      
                        var http_request = new XMLHttpRequest();
                        http_request.open("GET", url, true);
                        http_request.onreadystatechange = function() {
                          if (http_request.readyState == 4 && http_request.status == 200) {
                            var data = JSON.parse(http_request.responseText);
                            // self.loadPano(location, data.result[0].id);
                          }
                        };
                        http_request.send(null);
                      };*/
                      
                      /**
                       * Fires panorama.data, panorama.nodata
                       * @method load
                       * @param {Google.Maps.Location} location
                       * @param {Function} callback
                       * @example
                       *         // Let the panorama.load event handle it's load
                       *         loader.load(new google.maps.LatLng(lat, lng));
                       * @example
                       *         // Also handle the load individually
                       *         loader.load(new google.maps.LatLng(lat, lng), function(pano){
                       *           // This individual load has been completed
                       *           container.append(pano.canvas);
                       *         });
                       */
                      GSVPANO.PanoLoader.prototype.load = function(location, callback) {
                        var self = this;
                      
                        this._panoClient.getPanoramaByLocation(location, this.radius, function(result, status) {
                      
                          if (status === google.maps.StreetViewStatus.OK) {
                      
                            var pano = new GSVPANO.Pano({
                                id: result.location.pano,
                                rotation: result.tiles.centerHeading,
                                pitch: result.tiles.originPitch,
                                copyright: result.copyright,
                                imageDate: result.imageDate,
                                location: result.location,
                                zoom: self.zoom
                              })
                              .on('complete', self.emit.bind(self, 'panorama.load'))
                              .on('progress', self._setProgress.bind(self, pano));
                      
                            if (self.autocompose) {
                              pano.compose();
                            }
                            self.emit('panorama.data', pano);
                      
                            if (callback) {
                              callback(pano);
                            }
                          } else {
                            self.emit('panorama.nodata', location, status);
                            self._throwError('Could not retrieve panorama for the following reason: ' + status);
                          }
                        });
                      };
                      
                      /**
                       * @method setZoom
                       * @param {Number} z
                       */
                      GSVPANO.PanoLoader.prototype.setZoom = function(z) {
                        this.zoom = z;
                      };
                      
                      global.GSVPANO = module.exports = GSVPANO;