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