1 // ==========================================================================
  2 // Project:   The M-Project - Mobile HTML5 Application Framework
  3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
  4 //            (c) 2011 panacoda GmbH. All rights reserved.
  5 // Creator:   Dominik
  6 // Date:      24.01.2011
  7 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
  8 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
  9 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
 10 // ==========================================================================
 11 
 12 m_require('core/foundation/object.js');
 13 
 14 /**
 15  * @class
 16  *
 17  * M.Location defines a prototype for a location object. It is mainly used by
 18  * the M.LocationManager and contains properties like latitude and longitude,
 19  * that specify the retrieved location.
 20  *
 21  * @extends M.Object
 22  */
 23 M.Location = M.Object.extend(
 24 /** @scope M.Location.prototype */ {
 25 
 26     /**
 27      * The type of this object.
 28      *
 29      * @type String
 30      */
 31     type: 'M.Location',
 32 
 33     /**
 34      * The latitude of this location.
 35      *
 36      * @type Number
 37      */
 38     latitude: null,
 39 
 40     /**
 41      * The longitude of this location.
 42      *
 43      * @type Number
 44      */
 45     longitude: null,
 46 
 47     /**
 48      * The date this location was retrieved.
 49      *
 50      * @type M.Date
 51      */
 52     date: null,
 53 
 54     /**
 55      * This property specifies the location's accuracy in meters.
 56      *
 57      * @type Number
 58      */
 59     accuracy: null,
 60 
 61     /**
 62      * This property contains a reference to the object, that called the
 63      * update() of this location. This reference is needed for calling back
 64      * to the defined success and error callbacks.
 65      *
 66      * @private
 67      * @type Object
 68      */
 69     caller: null,
 70 
 71     /**
 72      * This method contains a reference to the specified success callback
 73      * method.
 74      *
 75      * @type Function
 76      */
 77     onUpdateSuccess: null,
 78 
 79     /**
 80      * This method contains a reference to the specified error callback
 81      * method.
 82      *
 83      * @type Function
 84      */
 85     onUpdateError: null,
 86 
 87     /**
 88      * This method initializes an M.Location object with the passed latitude
 89      * and longitude parameters. This method can be used to manually create
 90      * an M.Location object if the position is already known.
 91      *
 92      * To create an M.Location object with the user's current position, you
 93      * will have to use the M.LocationManager, respectively its getLocation()
 94      * method.
 95      *
 96      * Nevertheless you can use this method to initialiy create an M.Location
 97      * object with a specified location and then later use its update() method
 98      * to retrieve the real and current location of the user / device.
 99      *
100      * @param {Number} latitude The latitude of the location.
101      * @param {Number} longitude The longitude of the location.
102      */
103     init: function(latitude, longitude) {
104         return this.extend({
105             latitude: latitude,
106             longitude: longitude
107         });
108     },
109 
110     /**
111      * This method is used to automatically update the location. Since this
112      * is an asyncrhonous process, you have to specify two callback methods
113      * in case of success or error. additionally you can pass along options
114      * to configure the retrieving process.
115      *
116      * For further information about the parameters, check out getLocation()
117      * in M.LocationManager since this method is called out of update().
118      *
119      * If the update was successful, the properties of the location object
120      * are updated and your specified callback is called (without parameter).
121      *
122      * If the update goes wrong, your specified error callback is called with
123      * the error message as its only parameter. The error message will be one
124      * of the following constant string values:
125      *   - PERMISSION_DENIED
126      *   - POSITION_UNAVAILABLE
127      *   - TIMEOUT
128      *   - UNKNOWN_ERROR
129      *   - NOT_SUPPORTED
130      *
131      * @param {Object} caller The object, calling this function.
132      * @param {Object} onSuccess The success callback.
133      * @param {Object} onError The error callback.
134      * @param {Object} options The options for retrieving a location.
135      */
136     update: function(caller, onSuccess, onError, options) {
137         this.caller = caller;
138         this.onUpdateSuccess = onSuccess;
139         this.onUpdateError = onError;
140         
141         M.LocationManager.getLocation(this, this.onUpdateSuccessInternal, this.onUpdateErrorInternal, options);
142     },
143 
144     /**
145      * This method is called automatically as the success callback of the
146      * update(). After updating this location object, the external success
147      * callback is called.
148      *
149      * @param {Object} position The position object of the Geolocation API.
150      */
151     onUpdateSuccessInternal: function(position) {
152         if(position && position.coords) {
153             this.latitude = position.coords.latitude;
154             this.longitude = position.coords.longitude;
155             this.date = M.Date.now();
156 
157             if(this.caller) {
158                 if(this.onUpdateSuccess) {
159                     this.bindToCaller(this.caller, this.onUpdateSuccess)();
160                 } else {
161                     M.Logger.log('No success callback specified for update() of M.Location.', M.INFO);
162                 }
163             } else {
164                 M.Logger.log('No caller specified for update() of M.Location.', M.WARN);
165             }
166         } else {
167             M.Logger.log('An internal error occured while retrieving the position.', M.ERR);
168         }
169     },
170 
171     /**
172      * This method is called automatically as the error callback of the
173      * update(). After updating this location object, the external error
174      * callback is called.
175      *
176      * @param {Object} position The error that occurred.
177      */
178     onUpdateErrorInternal: function(error) {
179         if(this.caller) {
180             if(this.onUpdateError) {
181                 this.bindToCaller(this.caller, this.onUpdateError, error)();
182             } else {
183                 M.Logger.log('No error callback specified for update() of M.Location.', M.INFO);
184             }
185         } else {
186             M.Logger.log('No caller specified for update() of M.Location.', M.WARN);
187         }
188     }
189 
190 });