/* Auto-Bus Widget City File For Ottawa Ontario Canada
 * Version 1.0.0
 * March 30th 2007
 * 
 * Copyright 2007 Frederic Weigand Warr
 *
 * This file is an addition to the Auto-Bus widget for the Yahoo! Widget Engine.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
//-----------------------------------------------------------------------
/*
 * Adding and Editing Bus Stops for Ottawa
 * 
 * Specifying Direction:
 * The direction is specified internally in the web page by either a 1 or a 0.
 * To determine if your direction corresponds to a 1 or a 0, you need to look at
 * the title of the frame that contains the times. The last digit in the title
 * (the one right after wke, sat or sun) determines whether you should check the
 * direction box. If the digit is a 1, check the direction box, if it is a 0,
 * do not check the direction box.
 * To view the title of the frame:
 * Firefox: right click any of the times, and select This Frame/Show Only This Frame.
 *          the frame's address will be in the address bar, the direction digit is the
 *          last one in the address.
 * IE7: right click any of the times and select View Source. The direction digit is
 *      the last digit in the title of the notepad window that appears (ignore any 
 *      number within []).
 * 
 */

//-----------------------------------------------------------------------

/* Note about city specific js files
 * 
 * This file contains code specific to a transit system.
 * To make a city file for another transit system, use this as a template
 * and follow the instructions given in the comments above each function.
 * There are 7 functions that are necessary to implement to create a city
 * file. These are: getData, getTimes, getLineStr, getStpStr, getDirStr,
 * addStop and editStop. The first 5 (the getters) are methods of the
 * BusStop object and can therefore access the particular bus stop's info
 * through the keyword this. The last 2, are global functions to allow
 * the user to add STOPS and edit the STOPS list. Since these are global
 * functions, access to the bus STOPS is done through the "STOPS" array.
 * 
 * If you do create a functional city file for another transit system,
 * please send it to fwwarr@hotmail.com so that it can be posted on the
 * Auto-Bus widget's web page and be accessible for others to use.
 */

//------------------------------------------------------------------------
/* BusStop object methods
 */


/* method getData(doGetInfo)
 * 
 * Retrieves a bus stop's data from the web.
 * 
 * This is a method of the BusStop object
 * so the corresponding BusStop can be accessed
 * using "this" in the method body.
 * 
 * param doGetInfo
 * 
 *          If true, this method will call all of
 *          getTimes, getLineStr, getStpStr and getDirStr
 *          once the data has been received and appropriately
 *          refresh the display for all this information.
 *          
 *          If false, this method will only call getTimes
 *          once the data has been received and only the
 *          display of the times will be refreshed.
 * 
 * Note: Typically to adapt this method to a particular transit system
 * only the url location would have to be modified. Although this
 * may not be the case for every transit system.
 */
BusStop.prototype.getData = function (doGetInfo) {
	
	var url = new URL();
	var now,
		urlString;
	// Do not modify above this line
	//------------------------------
	// Start of city specific code
	now = new Date();
	urlString = "http://www.octranspo.com/mapscheds/currenttables/times/times";
	switch(this.args[0].length) {
	case 1:
		urlString += "00" + this.args[0]; break;
	case 2:
		urlString += "0" + this.args[0]; break;
	default:
		urlString += this.args[0];
	}
	if (now.getDay() === 0) {
		urlString += "sun";
	} else if (now.getDay() == 6) {
		urlString += "sat";
	} else {
		urlString += "wke";
	}
	urlString += this.args[2];
	urlString += ".htm";
	url.location = urlString;
	
	// End of city specific code
	//-----------------------------
	//Do not modify below this line
	url.object = this;
	appendLineToFile(LOGPATH, "Fetching data for " + this.args[0]);
	if (doGetInfo) {
		url.fetchAsync(useData);
	} else {
		url.fetchAsync(useTimeData);
	}
};


/* method getTimes()
 * 
 * Extracts the next few passage times from the data fetched by the getData method.
 * That data is accessible to this method through "this.data".
 * 
 * This method is expected to return an array of Date objects.
 * 
 * This method is called after each bus passage so that the first element
 * of the array is always the very next passage time.
 * 
 * If there is no way of getting the next passage times (eg. there are no more passages today),
 * this method should return an empty array and appropriately modify this.nextUpdateTime
 * with a Date object representing the next time the widget should try to fetch the times.
 * 
 * The entirety of this method's code is city specific
 */
BusStop.prototype.getTimes = function () {
	var str,
		i,
		j,
		k,
		passageTimes,
		time,
		now;
	
	now = new Date();
	str = this.data;
	passageTimes = [];
	for (i = 0,k = 0; i < 5 && k < 200; k++) {
		str = str.substring(str.indexOf("<TR>"));
		for(j = 0; j < parseInt(this.args[1],10)-1; j++) {
			str = str.substr(str.indexOf("time") + 5);
		}
		time = new Date();
		time.setHours(str.substr(str.indexOf("time") + 18, 2));
		time.setMinutes(str.substr(str.indexOf("time") + 21, 2));
		if( time > now ){
			passageTimes[i] = time;
			i++;
		}
	}
	
	return passageTimes;
};

/* method getLineStr()
 * 
 * This method returns the string to display as the bus' line.
 * Typically this information is already stored in the bus stop's
 * args array at index 0, but if different information is required
 * from the web, the data accessed by getData is still accessible
 * through this.data.
 */
BusStop.prototype.getLineStr = function () {
	return this.args[0];
};

/* method getStpStr()
 * 
 * This method returns the string to display as the bus stop info.
 * 
 * Depending on the ciy, this string may be specified by the user 
 * and stored in the bus stop's args array at index 1, but typically
 * the info stored in args[1] is not an easily recognizable string
 * (i.e. it's just a stop number) and the string to display must be
 * extracted from the web data.
 * 
 * Alternatively, the user can be asked to specify this
 * string (as well as a bus stop number if necessary) upon
 * creation/modification of the bus stop (by methods addStop
 * and editStop) and stored in this.args[7]. In that case
 * this method would only have to return this.args[7].
 */
BusStop.prototype.getStpStr = function () {

	return this.args[7];
};

/* method getDirStr()
 * 
 * This method returns the string to display as the direction
 * for which the times should be displayed.
 * 
 * Depending on the city, this string could be specified directly 
 * by the user and stored in args[2]. However, for some bus systems,
 * direction information is not needed to completely specify a bus stop
 * and the direction can be found on the web without the user specifying
 * it at all. (For example, in Montreal, a bus stop is fully qualified 
 * by a route number and a stop number and the direction corresponding
 * to that bus stop can be taken from the web.)
 * 
 * This method should not actually fetch data from the web but rather
 * use data fetched by getData and stored in this.data.
 */
BusStop.prototype.getDirStr = function () {
	
	return this.args[8];
};

//------------------------------------------------------------------------
/* Global functions
 */


/* function addStop()
 * 
 * Adds a bus stop to the array of STOPS to monitor.
 * Should create a form for the user to input the
 * necessary properties about the bus stop. A new
 * BusStop object created with the given properties
 * should then be added to the end of the STOPS array.
 * All other updating and displaying is taken care of
 * by non city specific code.
 * Typically the form should contain fields to specify
 * the route number, the stop name or number and sometimes
 * also the direction. These 3 properties should be stored
 * respectively in indexes 0, 1 and 2 of the  array.
 * This means that the BusStop object can be created simply
 * using the constructor BusStop(args) where args is an
 * array containing the three mentionned properties in
 * indexes 0 through 2.
 */
function addStop() {
	
	var formFields = [];
	var i = 0;
	formFields[i] = new FormField();
	formFields[i].title = "Line Number";
	formFields[i].type = "text";
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Direction";
	formFields[i].type = "checkbox";
	formFields[i].description = "Read the instructions near the top of the city file to know how to specify your direction.";
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Stop Column number";
	formFields[i].type = "text";
	formFields[i].description = "This is the number of the colunm that represents your bus stop on the timetable web page. Start counting from 1. Example: Route 1 direction South Keys, for the stop at Dalhousie Rideau, enter 3";
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Stop Display Text";
	formFields[i].type = "text";
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Direction Display Text";
	formFields[i].type = "text";
		
	var formResults = form( formFields, "Add a bus stop", "OK" );
	var args = [];
	
	if( formResults !== null ){
		
		args[0] = formResults[0];
		args[1] = formResults[2];
		args[2] = formResults[1];
		args[7] = formResults[3];
		args[8] = formResults[4];
		STOPS[STOPS.length] = new BusStop(args);
		
		// End of city specific code
		//------------------------------
		// Do not modify below this line
		STOPS[STOPS.length - 1].initDisplay();
		STOPS[STOPS.length - 1].getData(true);
		makeDisplay();
		saveStops();
	}
}

/* function editStop()
 * 
 * Provides the form for editing the basic properties of a bus stop.
 * Properties that define a particular bus stop should be specified
 * by the user in this form and saved in the BusStop object's args
 * array in indexes 0 through 2.
 * 
 * param busStop
 * 
 *           Indicates the indes of the STOPS array corresponding
 *           to the bus stop to be modified. The BusStop object to
 *           modify is therefore available through STOPS[busStop].
 * 
 * Typically, index 0 corresponds to the route number,
 * index 1 corresponds to the stop name or number, and
 * index 2 corresponds to the direction.
 * If additional information is needed to fully describe a bus stop,
 * indexes greater than 8 could be used.
 */
function editStop(busStop){
	
	var formFields = [];
	var i = 0;
	formFields[i] = new FormField();
	formFields[i].title = "Line Number";
	formFields[i].type = "text";
	formFields[i].value = STOPS[busStop].args[0];
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Direction";
	formFields[i].type = "checkbox";
	formFields[i].description = "Read the instructions near the top of the city file to know how to specify your direction.";
	formFields[i].value = STOPS[busStop].args[2];
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Stop Column number";
	formFields[i].type = "text";
	formFields[i].description = "This is the number of the colunm that represents your bus stop on the timetable web page. Start counting from 1. Example: Route 1 direction South Keys, for the stop at Dalhousie Rideau, enter 3";
	formFields[i].value = STOPS[busStop].args[1];
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Stop Display Text";
	formFields[i].type = "text";
	formFields[i].value = STOPS[busStop].args[7];
	i++;
	formFields[i] = new FormField();
	formFields[i].title = "Direction Display Text";
	formFields[i].type = "text";
	formFields[i].value = STOPS[busStop].args[8];
	
	var formResults = form( formFields, "Edit bus stop", "OK" );
	var args = [];
	
	if( formResults !== null ){
		
		STOPS[busStop].args[0] = formResults[0];
		STOPS[busStop].args[1] = formResults[2];
		STOPS[busStop].args[2] = formResults[1];
		STOPS[busStop].args[7] = formResults[3];
		STOPS[busStop].args[8] = formResults[4];		
		// End of city specific code
		//------------------------------
		// Do not modify below this line
		STOPS[busStop].getData();
		makeDisplay();
		saveStops();
	}
}



//--------------------------------------------------------------------------
/* Utility functions
 * 
 * Any other functions that may be used by the 7 previous functions but that
 * are not necessary to implement for every transit system should go here.
 */

