1 if (Garmin == undefined) var Garmin = {};
  2 /**
  3  * Copyright � 2007 Garmin Ltd. or its subsidiaries.
  4  *
  5  * Licensed under the Apache License, Version 2.0 (the 'License')
  6  * you may not use this file except in compliance with the License.
  7  * You may obtain a copy of the License at
  8  *
  9  *    http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an 'AS IS' BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16  * 
 17  * @fileoverview This file contains a number of filters used to filter an array of Garmin.Activity.
 18  * 
 19  * @author Bobby Yang bobby.yang.at.garmin.com
 20  * @version 1.0
 21  */
 22 
 23 /**Provides basic workflow for filtering an array of Garmin.Activity.
 24  * @class Garmin.BasicActivityFilter
 25  * @constructor 
 26  * @param (function) userFilterLogic - a function provided by the user containing the actual logic
 27  * 										used to filter the array of Garmin.Activity. An array containing
 28  * 										the activities will be passed to this function.
 29  */
 30 Garmin.BasicActivityFilter = function(userFilterLogic){};
 31 Garmin.BasicActivityFilter = Class.create();
 32 Garmin.BasicActivityFilter.prototype = {
 33 	
 34 	initialize: function(userFilterLogic) {		
 35 		// filter interal values
 36 		this.activities = null;
 37 		this.filterQueue = null;
 38 		
 39 		// user specified values
 40 		this.userFilterLogic = userFilterLogic;
 41 	},
 42 	
 43 	run: function(activities, filterQueue) {
 44 		// set the activities
 45 		this.activities = activities;
 46 	
 47 		// prepare the filter queue if not already available		
 48 		if (filterQueue != null) {
 49 			if (filterQueue instanceof String) {
 50 				if (window[filterQueue] == null	|| !(window[filterQueue] instanceof Array)) {
 51 					window[filterQueue] = new Array();
 52 				}
 53 				this.filterQueue = window[filterQueue];
 54 			} else if (filterQueue instanceof Array) {
 55 				this.filterQueue = filterQueue;
 56 			}
 57 		}
 58 	
 59 		// add myself to the queue if one exists		
 60 		if (this.filterQueue != null) {
 61 			this.filterQueue.push(this);
 62 		}
 63 
 64 		// wait for my turn
 65 		this._wait();
 66 	},
 67 	
 68 	_wait: function() {
 69 		// check for my turn
 70 		if (garminFilterQueue != null 
 71 			&& garminFilterQueue.length > 0 
 72 			&& garminFilterQueue[0] != this) {
 73 			//console.debug("waiting for my turn to filter...");			
 74 			// delay before checking for my turn again
 75 			setTimeout(function(){this._wait();}.bind(this), 500);
 76 		} else {
 77 			// the wait is over, start processing
 78 			this._process();
 79 		}
 80 	},
 81 	
 82 	_process: function() {
 83 		// run user code to filter the activities
 84 		this.userFilterLogic(this.activities);
 85 		
 86 		// cleanup this filter
 87 		this._finish();
 88 	},	
 89 	
 90 	_finish: function() {
 91 		if (this.filterQueue != null) {
 92 			// remove myself from the queue, normally
 93 			// would be position 0.  Looping through
 94 			// all elements just incase position is not
 95 			// 0.
 96 			for (var i = 0; i < this.filterQueue.length; i++) {
 97 				if (this.filterQueue[i] == this) {			
 98 					this.filterQueue.splice(i, 1);
 99 					break;
100 				}
101 			}
102 		}
103 	}
104 };
105 
106 /**Provides workflow for activity filtering logic that requires an ajax call.
107  * @class Garmin.AjaxActivityFilter
108  * @constructor
109  * @param (function) preAjaxFilterLogic - a function provided by the user containing the actual logic
110  * 										used to filter the array of Garmin.Activity before the ajax call. 
111  * 										An array containing the activities will be passed to this function along
112  * 										with the ajax call options.  
113  * @param (function) postAjaxFilterLogic - a function provided by the user containing the actual logic
114  * 										used to filter the array of Garmin.Activity after the ajax call. 
115  * 										An array containing the activities will be passed to this function along
116  * 										with the ajax response text and xml.
117  * @param (String) ajaxURL - the path for the ajax call.
118  * @param (Hash) ajaxOptions - options used for the ajax call. Please see http://www.prototypejs.org/api/ajax/options.
119  */
120 Garmin.AjaxActivityFilter = function(preAjaxFilterLogic, postAjaxFilterLogic, ajaxURL, ajaxOptions){};
121 Garmin.AjaxActivityFilter = Class.create();
122 Garmin.AjaxActivityFilter.prototype = Object.extend(new Garmin.BasicActivityFilter(), {
123 	
124 	initialize: function(preAjaxFilterLogic, postAjaxFilterLogic, ajaxURL, ajaxOptions) {
125 		// filter interal values
126 		this.activities = null;
127 		this.ajaxRequest = null;
128 		this.filterQueue = null;
129 		
130 		// user specified values
131 		this.preAjaxFilterLogic = preAjaxFilterLogic;
132 		this.postAjaxFilterLogic = postAjaxFilterLogic;
133 		this.ajaxURL = ajaxURL;
134 		this.ajaxOptions = ajaxOptions;
135 	},
136 	
137 	_process: function() {
138 		// run user code to filter the activities before ajax call
139 		if (this.preAjaxFilterLogic != null) {
140 			this.preAjaxFilterLogic(this.activities, this.ajaxOptions);
141 		}
142 		
143 		// backup user ajax callbacks
144 		this.userAjaxComplete = this.ajaxOptions.onComplete;
145 		this.userAjaxException = this.ajaxOptions.onException;
146 		this.userAjaxFailure = this.ajaxOptions.onFailure;
147 		this.userAjaxSuccess = this.ajaxOptions.onSuccess;
148 		
149 		// set my own ajax callbacks
150 		//this.ajaxOptions.onCreate = this.onAjaxCreate.bind(this);
151 		this.ajaxOptions.onComplete = this.onAjaxComplete.bind(this);
152 		this.ajaxOptions.onException = this.onAjaxException.bind(this);
153 		this.ajaxOptions.onFailure = this.onAjaxFailure.bind(this);
154 		//this.ajaxOptions.onInteractive = this.onAjaxInteractive.bind(this);
155 		//this.ajaxOptions.onLoaded = this.onAjaxLoaded.bind(this);
156 		//this.ajaxOptions.onLoading = this.onAjaxLoading.bind(this);		
157 		this.ajaxOptions.onSuccess = this.onAjaxSuccess.bind(this);
158 		//this.ajaxOptions.onUninitialized = this.onAjaxUninitialized.bind(this);		
159 		
160 		// initiate ajax call
161 		this.ajaxRequest = new Ajax.Request(this.ajaxURL, this.ajaxOptions);
162 	},	
163 	
164 	onAjaxComplete: function(transport) {
165 		// call user callback if one exists
166 		if (this.userAjaxComplete != null) {
167 			this.userAjaxComplete(transport);
168 		}
169 		
170 		// cleanup this filter
171 		this._finish();
172 	},
173 	
174 	onAjaxException: function(request, exception) {
175 		// call user callback if one exists
176 		if (this.userAjaxException != null) {
177 			this.userAjaxException(transport);
178 		}
179 		
180 		// cleanup this filter
181 		this._finish();		
182 	},
183 
184 	onAjaxFailure: function(transport) {
185 		// call user callback if one exists
186 		if (this.userAjaxFailure != null) {
187 			this.userAjaxFailure(transport);
188 		}
189 		
190 		// no need to clean up since onComplete will be called
191 		// cleanup this filter
192 		//this._finish();
193 	},
194 	
195 	onAjaxSuccess: function(transport) {
196 		// call user callback if one exists
197 		if (this.userAjaxSuccess != null) {
198 			this.userAjaxSuccess(transport);
199 		}
200 		
201 		// run post ajax user code to filter the activities
202 		if (this.postAjaxFilterLogic != null) {
203 			this.postAjaxFilterLogic(this.activities, transport.responseText, transport.responseXML);
204 		}
205 		
206 		// no need to clean up since onComplete will be called
207 		// cleanup this filter
208 		//this._finish();
209 	}						
210 });
211 
212 /**Filtering logic used by filters in Garmin.FILTER. 
213  */
214 Garmin.FilterCode = {
215 	filterForRoute: function(activities) {
216 		Garmin.FilterCode.filterForSeriesType(activities, [Garmin.Series.TYPES.route]);
217 	},
218 	
219 	filterForRouteAndHistory: function(activities) {
220 		Garmin.FilterCode.filterForSeriesType(activities, [Garmin.Series.TYPES.history, Garmin.Series.TYPES.route]);
221 	},
222 	
223 	filterForHistory: function(activities) {
224 		Garmin.FilterCode.filterForSeriesType(activities, [Garmin.Series.TYPES.history]);
225 	},
226 	
227 	filterForWaypoint: function(activities) {
228 		Garmin.FilterCode.filterForSeriesType(activities, [Garmin.Series.TYPES.waypoint]);
229 	},
230 	
231 	filterForSeriesType: function(activities, seriesTypes) {
232 		//console.debug("Started with " + myActivities.length + " activities.");
233 		// loop through all activities and look for ones
234 		// with series of type seriesType. looping in
235 		// reverse so elements can be removed while looping.
236 		for (var i = activities.length; i > 0; i--) {
237 			var series = activities[i-1].getSeries();
238 			if (series.length > 0) {
239 				var match = false;
240 				// loop through all the series contained by
241 				// this activity for a match
242 				for (var j = 0; j < series.length; j++) {
243 					for (var k = 0; k < seriesTypes.length; k++) {
244 						if (series[j].getSeriesType() == seriesTypes[k]) {
245 							match = true;
246 							break;
247 						}
248 					}
249 				}
250 				// if this activity is not of seriesType then
251 				// remove it from activities
252 				if (!match) {
253 					activities.splice(i-1, 1);
254 				}
255 			}
256 		}
257 		//console.debug("Ended with " + myActivities.length + " activities.");
258 	}	
259 };
260 
261 /**Premade filters ready to be used.
262  */
263 Garmin.FILTERS = {
264 	historyOnly:	 			new Garmin.BasicActivityFilter(Garmin.FilterCode.filterForHistory),
265 	routeOnly:					new Garmin.BasicActivityFilter(Garmin.FilterCode.filterForRoute),
266 	waypointOnly:				new Garmin.BasicActivityFilter(Garmin.FilterCode.filterForWaypoint),
267 	routeAndHistoryOnly:		new Garmin.BasicActivityFilter(Garmin.FilterCode.filterForRouteAndHistory)
268 };